import extensionless detects .js and compiles
extensionless is imported as is without resolving .js
was working in v10.0.0
don't see any mention where this is a breaking change?
We're going to need a lot more info in the issue. Errors, what you tried, etc.
@shellscape it's all in the repl, just need to run and it will show the error. Downgrading to v10.0.0 works etc.
import 'systemjs/dist/s.min'; // fails
import 'systemjs/dist/s.min.js'; // works
Always include as much info as possible in the issue. The REPL is there to reproduce the issue, not to document it. The reproduction typically won't survive (and doesn't have to) past resolution of the issue, but the issue will always live in for reference. The same holds true in any repo you contribute issues to.
Cool, no worries, here's the error, thanks!
npx rollup -c
input.js → output/bundle.js...
[!] (plugin Rollup Core) Error: Could not load /home/runner/rollup-plugin-repro/node_modules/systemjs/dist/s.min (imported by /home/runner/rollup-plugin-repro/input.js): ENOENT: no such file or directory, open '/home/runner/rollup-plugin-repro/node_modules/systemjs/dist/s.min'
Error: Could not load /home/runner/rollup-plugin-repro/node_modules/systemjs/dist/s.min (imported by /home/runner/rollup-plugin-repro/input.js): ENOENT: no such file or directory, open '/home/runner/rollup-plugin-repro/node_modules/systemjs/dist/s.min'
exit status 1
However, it's really self explainatory.
I can also confirm, that it was working in v10.0.0 but does not in v11.0.0. Svelte library rollup build fails with error:
[!] Error: Could not load <redacted>/widget/node_modules/@babel/runtime/helpers/esm/assertThisInitialized (imported by src/MenuWidget.svelte): ENOENT: no such file or directory, open '<redacted>/widget/node_modules/@babel/runtime/helpers/esm/assertThisInitialized'
Error: Could not load <redacted>/widget/node_modules/@babel/runtime/helpers/esm/assertThisInitialized (imported by src/MenuWidget.svelte): ENOENT: no such file or directory, open '<redacted>/widget/node_modules/@babel/runtime/helpers/esm/assertThisInitialized'
looking into this atm
Hmm I added a test for this which currently passes. https://github.com/tjenkinson/plugins/commit/965bce9e7b936ba0d1e4b549dff5bfdd78c032ee
Don't have any more time right now but will check this evening
+1 : I just ran into the same issue. Maybe it is helpful to add some more context:
In my current project, I have a complex build chain that has multiple stages of rollup-bundling and only some of them are breaking with node-resolve v11. The first stage bundles all dependencies into a single dependenciesBundle.js which has a stable API and can be updated and shipped independent from the application itself. A later stage bundles the app, treating the dependenciesBundle.js as external. The target platform is web-only. Therefore, the first stage needs to convert CommonJS code into ES-compliant JavaScript by using @rollup/plugin-commonjs. However, the later app bundling stage only faces pure JavaScript and does not need the plugin-commonjs. Interestingly, upgrading node-resolve from v10 to v11 only breakes the first stage of dependency bundling. The app bundling still runs smoothly with v11.
Here is my rollup.config.js for the breaking dependency bundling stage:
/* eslint-disable import/no-extraneous-dependencies */
import commonjs from "@rollup/plugin-commonjs";
import nodeResolve from "@rollup/plugin-node-resolve";
import injectProcessEnv from "rollup-plugin-inject-process-env";
// noinspection JSUnusedGlobalSymbols
export default {
input: "./src/dependencies.js",
output: {
file: "./dependenciesBundle.js",
dir: undefined,
format: "es",
sourcemap: false,
},
plugins: [
nodeResolve(),
commonjs({
mainFields: ["module", "main", "jsnext:main", "browser"],
extensions: [".js", ".mjs", ".json"],
sourceMap: false,
browser: true,
}),
injectProcessEnv({ NODE_ENV: "production" }),
],
};
We need to tackle this on a package per package basis. It's likely that because node-resolve v11 now respects the exports map in the package.json of packages, there are different rules you need to follow now.
For systemjs, this is according to the node js specs. They have specified an export map: https://github.com/systemjs/systemjs/blob/master/package.json#L5 which means that is used for resolving imports.
When you do an import like this: import 'systemjs/dist/s.min'; it means it will match the rule "./dist/": "./dist/" and thus an explicit file extension is required.
Regarding /@babel/runtime/helpers/esm/assertThisInitialized, this is the same issue as https://github.com/rollup/plugins/issues/672 which was already fixed but not yet released.
Right, so it sounds like this is not a bug?
It might be possible to handle this with another plugin with which would try adding the .js if it's missing.
Something like
{
name: 'fallback-js-extension',
async resolveId(source, importer) {
return await this.resolve(source + '.js', importer, { skipSelf: true });
}
}
(untested)
Right so if it is a breaking change should it be mentioned somewhere in the changelog? Just to avoid people opening up further issues on it.
Technically the support for package entrypoints is mentioned. The behavior should now be the same when using native node js, node-resolve v11 and webpack 5. But I can see that the changelog entry doesn't explain all the details by itself.
As the changelog is rather concise, maybe this is more an issue for the readme. By the way, we do not have an opt-out for this feature, do we? Because as this issue shows as package exports can severely restrict/change how certain packages can be imported, this may prevent users from upgrading if there existing code-base heavily depends on old import patterns. Having an opt-out could serve as a means for easing the transition. Also, think about the scenario where a dependency you do not have control over imports from another dependency in a non-compliant way. Would this be difficult to add? I am not thinking of anything fine-grained here, just a brutal on-off switch. Such a feature could also serve as a place in the readme where these restrictions are explained. Thoughts?
I'm 50/50 on that. The plugin is called node-resolve, and this is exactly how the node resolution logic works. You can't turn it off in node, and from what I can tell you can't turn it off webpack either. Adding the option to disable it makes it easier to fragment the ecosystem like it has with esm/commonjs interop.
A full on/off switch also wouldn't be enough I think, because it will be easy to end up with some packages that have exports that look different from the actual file system For example:
{
"exports": {
"./foo": "./dist/foo.js"
}
}
This kind of export would not work anymore when it's turned off completely.
Adding a switch today would be possible, but the underlying resolve package is also working on adding support for the exports field. They would have to make this configurable too for it to keep working.
Most helpful comment
As the changelog is rather concise, maybe this is more an issue for the readme. By the way, we do not have an opt-out for this feature, do we? Because as this issue shows as package exports can severely restrict/change how certain packages can be imported, this may prevent users from upgrading if there existing code-base heavily depends on old import patterns. Having an opt-out could serve as a means for easing the transition. Also, think about the scenario where a dependency you do not have control over imports from another dependency in a non-compliant way. Would this be difficult to add? I am not thinking of anything fine-grained here, just a brutal on-off switch. Such a feature could also serve as a place in the readme where these restrictions are explained. Thoughts?