rollup / rollup-plugin-commonjs

This module has moved and is now available at @rollup/plugin-commonjs / https://github.com/rollup/plugins/blob/master/packages/commonjs
MIT License
501 stars 126 forks source link

Adding exports to CJS modules with built-in names broken by resolve 1.11.1 #394

Closed bterlson closed 5 years ago

bterlson commented 5 years ago

Resolve changed how it resolves built-in module specifiers like buffer (this also impacted rollup-plugin-node-resolve). The impact is you can no longer add exports for e.g. assert like the following:

  cjs({
    namedExports: {
      assert: ["deepEqual"]
    }
  });

This plugin starts by building a map from resolved module path to declared named exports for that module. The resolve change means the keys for built-in modules went from a resolved path to the like-named npm module to simply returning the built-in name back.

I see three potential fixes here:

  1. similar to https://github.com/rollup/rollup-plugin-node-resolve/pull/223, we do a two-pass resolution, first attempting to resolve with "/" appended, and falling back if we can't find anything.
  2. if adding named exports for node builtins isn't a thing, we append "/" to any specifier that's a built-in module.
  3. update the documentation to be clear that "buffer" and "buffer/" are two different things, and you should be intentional about which you are declaring named exports for. This would also enable a person to provide different named exports for a built-in and an npm package with the same name. I'm not sure if this is valuable.

Do the maintainers have any thoughts on the best fix here?

lukastaegert commented 5 years ago

Only some vague thoughts for now:

Therefore if I understand you correctly, 2. might actually be a viable option

ljharb commented 5 years ago

You can use resolve/lib/core, and if the key is in that object and the value is true, it's a builtin module.

bterlson commented 5 years ago

That rationale seems sound to me, let's go with 2! Should be nearly a one-liner. And yeah, I'll use Resolve's isBuiltin thing here, rather than following what rollup-plugin-node-builtins does (that plugin should probably just use resolves thing too).

lukastaegert commented 5 years ago

One open question could be how to handle version ranges for builtins that are specified for resolve but I guess we should just use all of them as we do not know on which target system we will run.

ljharb commented 5 years ago

@lukastaegert the "core" logic in resolve is written to assume that you're running it on a node version that matches the author's expectations. iow, if they're running on node 6, then only the core modules in node 6 are considered eligible (since the input code isn't written for the target environment, it's written for node)