7

I use private JavaScript class methods in my front-end code and Snowpack for my development workflow.

Currently (as of v2.15.0-pre.5), Snowpack doesn't seem to play well with private class methods, i.e., the following fails to when building with snowpack build:

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

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

A repo to reproduce is here. After cloning, run:

npm install
npm run build

I've opened an issue with Snowpack, but apparently the problem lays in the integration with Rollup and the fix isn't a priority.

As far as I understand, to solve it we need:

I wonder if anyone could help with an example of this, before I dive deep into learning Rollup ecosystem?

Or maybe there's another way to make it work?

I'm now back to using _methodName instead of #methodName due to time constraints, but I plan to contribute a fix when time allows.

noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    Using a custom Rollup plugin for Snowpack to inject `acorn-private-methods` into `acornInjectPlugins` does _not_ appear to work correctly, from [my testing](https://gist.github.com/concision/2ce09d47a8b7730aea33623677e3d8d3). It seems this only applies to the project sources, and not dependencies; this appears consistent with what FredKSchott mentions on the linked GitHub issue: _"because mod101 is treated as a dependency, it goes through a different workflow"_. I think a different approach might be necessary. – concision Oct 22 '20 at 20:22
  • 1
    @concision, interesting! Thanks for taking time to verify this. Snowpack already works well with private methods in the project sources, as is, with `acorn-private-methods` injection. – noseratio Oct 22 '20 at 20:37
  • @concision, I've [figured it out](https://stackoverflow.com/a/64501702/1768303). Your comment was helpful too, it gave me an idea to look at other Rollup hooks. Maybe you could tweak you gist and post it as an alternative answer, I'd be happy to reward it with the bounty. Thanks! – noseratio Oct 23 '20 at 14:25
  • 1
    Glad to hear it was of some help. I am surprised that no one seems to have ran into this issue before. This might be useful for future readers, so I am thinking I will package the solution as both a rollup and snowpack plugin available on npm and post those as an answer. Might take a day or two. – concision Oct 24 '20 at 00:33
  • 1
    @concision, that'd be great, thanks! I've made [this snowpack plugin](https://gist.github.com/noseratio/c4f2a6b92ee6024fde3ef95c1ebad147) already as I prefer declarative JSON config to `snowpack.config.js `. It'd be great if you could make it configurable via the `pluginOptions` arg, like specifying what exact Acorn plugins to use. – noseratio Oct 24 '20 at 03:15
  • 2
    I have added an answer with a plugin implementation as you have described. It is available on NPM as [snowpack-plugin-acorn-injection](https://www.npmjs.com/package/snowpack-plugin-acorn-injection). This supports declarative JSON Snowpack configurations. – concision Oct 24 '20 at 21:03

2 Answers2

5

Snowpack Plugin: snowpack-plugin-acorn-injection

Expanding off of @noseratio's work, I have created a NPM dependency called snowpack-plugin-acorn-injection that will inject the relevant Acorn plugins into Rollup's internal configuration.

The plugin is available:


Example

Dependency Installation

Install the plugin and the relevant Acorn plugin(s) that are desired (for example, acorn-stage3) as development dependencies.

Steps:

  • npm:
    npm install --save-dev snowpack-plugin-acorn-injection acorn-stage3
    
  • Yarn:
    yarn add --dev snowpack-plugin-acorn-injection acorn-stage3
    

Configure Snowpack

Configure the project's Snowpack configuration with snowpack-plugin-acorn-injection and the relevant Acorn plugins:

{
  ...
  "plugins": [
    [
      "snowpack-plugin-acorn-injection",
      {
        "plugins": [
          "acorn-stage3"
        ]
      }
    ]
  ],
  ...
}
concision
  • 6,029
  • 11
  • 29
3

I've figured it out, using Rollup.js options hook and acorn-stage3 acorn plugin, repo.

acorn-private-methods can be used as well (if only private methods wanted).

  • Create a custom Rollup.js plugin, I called it @noseratio/rollup-acorn-conf:
"use strict";

module.exports = function plugin(hostOpts = {}) {
  return { 
    name: 'rollup-acorn-conf',

    options: rollupOpts => { 
      console.log("Enabling 'acorn-stage3'...");
      rollupOpts.acorn = rollupOpts.acorn ?? {};
      rollupOpts.acorn.ecmaVersion = 2020;
      rollupOpts.acornInjectPlugins = rollupOpts.acornInjectPlugins ?? [];
      rollupOpts.acornInjectPlugins.push(require('acorn-stage3'));
      return rollupOpts;
    }
  };
};

Its package.json:

{
  "name": "@noseratio/rollup-acorn-conf",
  "version": "0.1.1",
  "description": "Enable ES2020 features (Stage 3) for Rollup.js",
  "homepage": "https://github.com/noseratio/snowpack-discussions-1209",
  "main": "index.js",
  "scripts": {},
  "devDependencies": {
    "acorn-stage3": "^4.0.0"
  }
}
  • In snowpack.config.js:
  installOptions: {
    rollup: { 
      plugins: [require('@noseratio/rollup-acorn-conf')()]
    }
  }
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • A [gist](https://gist.github.com/noseratio/c4f2a6b92ee6024fde3ef95c1ebad147) for declarative `snowpack.config.json`. – noseratio Oct 26 '20 at 23:36