Snowpack: Snowpack doesn't seem to support private ('hashed") class methods

Created on 10 Oct 2020  路  10Comments  路  Source: snowpackjs/snowpack

Original Discussion: https://github.com/pikapkg/snowpack/discussions/1209#discussioncomment-90321
/cc @FredKSchott

Snowpack doesn't seem to support private class methods:

export class TestClass {
  #test() {
    console.log("testing...");
  }

  test() {
    this.#test();
  }
}

Building it with snowpack build fails with:

[snowpack] Failed to load index.js                                                                                 
Unexpected token (2:2) in index.js

snowpack.config.json:

{
  "mount": {
    "public": "/",
    "src": "/_dist_"
  },
  "plugins": []
}

Tried with Node v14.13.1.

Repo to reproduce: https://github.com/noseratio/snowpack-discussions-1209.git

Most helpful comment

Fixed in #1270 (upgrading esbuild added support for this automatically).

I also pushed a quick fix (d34c1940) to add support in the React Fast Refresh plugin, and preact prefresh has a PR out to do the same: https://github.com/JoviDeCroock/prefresh/pull/203

All 10 comments

I think this a private class access issue results from an incapability of the actual rollup dependency that we are using.
Ref: https://github.com/pikapkg/snowpack/blob/30dfc5ce072edbcccc5a2b73631a8fdbd4a29b1b/esinstall/src/index.ts#L437-L463

Fixed in #1270 (upgrading esbuild added support for this automatically).

I also pushed a quick fix (d34c1940) to add support in the React Fast Refresh plugin, and preact prefresh has a PR out to do the same: https://github.com/JoviDeCroock/prefresh/pull/203

Hi @FredKSchott,

Just checking if it was meant to be fixed in v2.15.0-pre.5? It so, the problem is still there, I've updated the repo to repro.

npm run build still fails with the same error: Unexpected token (2:2) in mod101\index.js.

Thanks for looking into this! My package.json:

{
  "scripts": {
    "start": "snowpack dev",
    "build": "snowpack build",
    "test": "echo \"This template does not include a test runner by default.\" && exit 1",
    "format": "prettier --write \"src/**/*.js\"",
    "lint": "prettier --check \"src/**/*.js\""
  },
  "dependencies": {
    "canvas-confetti": "^1.2.0",
    "eslint": "^7.11.0",
    "mod101": "file:mod101",
    "npm": "^7.0.2"
  },
  "devDependencies": {
    "prettier": "^2.0.5",
    "snowpack": "^2.15.0-pre.5"
  }
}

Oh interesting. We've added private method support in your source code for Snowpack, but not in your packages. Because the private field exists in mod101, and because mod101 is treated as a dependency, it goes through a different workflow.

The easiest fix would be to move mod101 into a mounted folder like src, and then import it by relative URL. Can you do that?

Our dependencies go through Rollup to upconvert them to ESM. It's not impossible to extend Rollup to support this (see https://github.com/rollup/rollup/issues/1185), but I don't think I've seen an npm package using these in the wild yet.

The easiest fix would be to move mod101 into a mounted folder like src, and then import it by relative URL. Can you do that?

The problem is, this package lives in the same monorepo and is shared between front-ends (using snowpack) and back-ends (using Node's native ESM support). I just do npm install [relative_path]/mod101 in the root of each project that uses mod101 in this monorepo, be it a front-end or a back-end project.

I think this is a pretty common workflow. I'd rather give up private JS methods to keep the convenience of having mod101 in its single place within this monorepo. So I'm going to change "#methods" to "_methods" for now.

Thanks anyway @FredKSchott!

No problem! Hopefully Rollup adds support for this.

If anyone else finds this issue, please leave a comment asking for support! If we get enough requests , we can look into adding the acorn plugin to Rollup so that packages get this support.

No problem! Hopefully Rollup adds support for this.

@FredKSchott, FWIW I thought I'd report it to Rollup, but I couldn't repro it with Rollup. Running this from the root of my repro-case repo:

npx rollup src\index.js --format es --name "myBundle" --file bundle.js

I see no errors, and bundle.js gets successfully generated with this content:

import confetti from 'canvas-confetti';
import 'mod101';

/**
 * This file is just a silly example to show everything working in the browser.
 * When you're ready to start on your site, clear the file. Happy hacking!
 **/

confetti.create(document.getElementById('canvas'), {
  resize: true,
  useWorker: true,
})({ particleCount: 200, spread: 200 });

Am I missing something?

Leaving a note for the future self and others. As far as I understand the problem with private class methods, to solve it we need:

Due time constraints I'm unable to do it now (it'd take to learn the Rollup ecosystem), but I'll get to it when I can :)

I've solved it, using Rollup.js options hook and acorn-stage3 acorn plugin, repo.
More details in my SO answer.

And now we have an NPM package to configure Acorn options, thanks to @concision.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FredKSchott picture FredKSchott  路  6Comments

FredKSchott picture FredKSchott  路  5Comments

FredKSchott picture FredKSchott  路  6Comments

backspaces picture backspaces  路  5Comments

FredKSchott picture FredKSchott  路  5Comments