-
-
Notifications
You must be signed in to change notification settings - Fork 601
Description
Pre-flight checklist
- I have read the contribution documentation for this project.
- I agree to follow the code of conduct that this project uses.
- I have searched the issue tracker for a feature request that matches the one I want to file, without success.
Problem description
The plugin will throw an error if the package.json's "main" field is not exactly ".webpack/main". (Actually, it only checks if it ends with it)
This is because the Webpack plugin outputs the main Electron bundle to .webpack/main/index.js. This causes some problems if you have a package.json of "type": "module":
- Electron is started with the package to run provided by path.
- Electron imports the given package path using
require(). - Because
require()is given a path instead of a name, Node consults thepackage.json's"main"property for a script to import.- When
require()is given a path, it will only consult the"main"field even if"exports"is defined. See the Node docs
- When
- Node finds the
"main"property is set to".webpack/main". Because this is a directory, Node will load.webpack/main/index.js. - Because the
"type"is"module", all.jsfiles are assumed to be ES modules, and Node throws an error about attempting torequire()it (even though the plugin outputs a CJS bundle).
Proposed solution
In a "type": "module" package, all .js files are treated as ES modules, and any CommonJS modules must have a .cjs extension. (The "exports" field lets you explicitly specify these, but this does not get used due to passing a path to require()).
The simplest solution is to ensure the output bundle has a .cjs extension by editing the Webpack config, and explicitly specify "main": ".webpack/main/index.cjs". This fixes the problem, but the plugin throws an error because the entry point isn't the expected value. The plugin would need to be updated to accept /\.webpack\/main(\/index\..js)?$/ as the entry point.
Perhaps a more proper solution would be to allow the user to configure the bundle output/entry point instead of requiring it to be .webpack/main. #2770 suggested this, but didn't have a specific use case.
Alternatives considered
- It's possible to set up a hook to copy a different
package.jsonor replace the"main"in the output files, but this doesn't seem like a great workaround. - It's possible to split the package up into multiple packages, with one just for building the Electron package, but this adds development/configuration overhead, especially if you want to share a common Webpack config for multiple targets/environments.
Additional information
I'm aware Electron doesn't support ES modules, but it doesn't have to. Webpack already turns everything into cjs, we just need to make sure Node knows that.