proposal-private-methods skips @rollup/plugin-commonjs when injecting `import` statement
micaelmbagira opened this issue · 6 comments
I am bundling a project with the following rollup config
module.exports = [
{
input: './src/index.js',
output: [
{ file: pkg.main, format: 'cjs' },
],
plugins: [
babel(),
commonjs(),
],
},
];
However the commonjs
plugin (which resolves require
statements) is not working -- basically require('./foo')
is not being replaced by the actual source.
I found that it's because I am using '@babel/plugin-proposal-private-methods'
which injects these two lines (I had to tap in rollup/plugin-commonjs
to find that out).
For instance if I remove in my source code, all the usage of private methods/properties (even if I leave the plugin configuration in .babelrc
), it works.
import { classPrivateFieldGet as _classPrivateFieldGet } from "\0rollupPluginBabelHelpers.js";
import { classPrivateFieldSet as _classPrivateFieldSet } from "\0rollupPluginBabelHelpers.js";
Because of that, rollup considers the compiled module as an esModule
and thus does not start resolving the other require
.
Tbh I am not sure whose responsibility it is.
If needed, here is my babel config:
module.exports = {
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
node: '10',
},
},
],
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods',
],
};
It's because rollup detects those files as modules (because of the injected import
statements), and thus doesn't replace
require` that in modules is not the CommonJS function.
You can tell Babel that you are not using modules using the soureType
option:
{
sourceType: "script",
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
node: '10',
},
},
],
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods',
],
}
Note that if this problem is only for code in node_modules
and you are using ES modules in your source code, you can configure it like this:
{
sourceType: "module",
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
node: '10',
},
},
],
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods',
],
overrides: [
{ test: /node_modules/, sourceType: "script" }
]
}
@nicolo-ribaudo indeed this causes a problem only for the code produced by babel
import { classPrivateFieldGet as _classPrivateFieldGet } from "\0rollupPluginBabelHelpers.js";
In any case, sourceType: "script",
does not work and throws this error
'import' and 'export' may appear only with 'sourceType: "module"' (2:0)
Consider renaming the file to '.mjs', or setting sourceType:module or sourceType:unambiguous in your Babel config for this file.
1 | class Foo extends Bar {};
2 | export default Foo;
which I actually don't understand since my code is not using import/export
.
When using
overrides: [
{ test: /node_modules/, sourceType: "script" }
]
the compilation goes through but the initial problem is still there and thus the require
statements are still not transformed.
Ok, try setting sourceType
to unambiguous
. It doesn't work in some edge cases, but if you find them you can special-case the files where it's throwing (or keeping "require") using overrides
.
@nicolo-ribaudo unambiguous
worked here. Let's see if it causes any problems later. It seems a bit odd that we need this step even though the problematic code is generated by babel 😅but it's fine for now.
Well, Rollup expects native ES modules. The rollup-plugin-commonjs
package internally transforms CommonJS to ESM before giving it to rollup. Then it's kinda expected that Babel (with rollup-plugin-babel
) generates ESM imports 😅
@nicolo-ribaudo fair enough, I think I will just use import
/export
syntax, it seems like a better fit than setting the sourceType
for this use case.