threads-plugin
threads-plugin copied to clipboard
Cannot import built-in node modules in worker in electron/webpack build
https://github.com/jc-lab/threads-plugin-problem See the repository above.
Error when using module as esnext in tsconfig. If you use commonjs instead of esnext, threads-plugin will not detect Worker.
> npm run build
...
Child WorkerPluginLoader:
2 assets
Entrypoint 0 = 0.bundle.worker.js 0.bundle.worker.js.map
[6] (webpack)/buildin/harmony-module.js 573 bytes {0} [built]
[15] ./node_modules/ts-loader??ref--4!./src/test.thread.ts + 2 modules 16.7 KiB {0} [built]
| ./node_modules/ts-loader??ref--4!./src/test.thread.ts 730 bytes [built]
| + 2 hidden modules
+ 26 hidden modules
ERROR in ./src/test.thread.ts (./node_modules/ts-loader??ref--4!./src/test.thread.ts)
Module not found: Error: Can't resolve 'fs' in 'D:\temp\webpack-worker-test\src'
@ ./src/test.thread.ts (./node_modules/ts-loader??ref--4!./src/test.thread.ts) 3:0-25 8:22-42
ERROR in ./src/test.thread.ts (./node_modules/ts-loader??ref--4!./src/test.thread.ts)
Module not found: Error: Can't resolve 'zlib' in 'D:\temp\webpack-worker-test\src'
@ ./src/test.thread.ts (./node_modules/ts-loader??ref--4!./src/test.thread.ts) 4:0-29 9:23-41
It works with TypeScript, you just need to set module
to esnext
as you already wrote. It's also documented like that: See here.
The error above is unrelated to threads.js and the threads-plugin as far as I can tell.
Try npm install --save-dev @types/node
.
Feel free to re-open if I missed something. The error above looks very much like something else is fishy, though.
@andywer If you comment out ThreadsPlugin as shown below, no error will occur. That's why I think it's an issue of threads-plugin.
// plugins: [new ThreadPlugin()],
output:
> npm run build
> webpack --config webpack.config.js -p
Hash: 1fb9dddabef6f1be9dc0
Version: webpack 4.41.5
Time: 1404ms
Built at: 2020-01-06 23:04:43
Asset Size Chunks Chunk Names
..\dist-ts\index.d.ts 47 bytes [emitted]
..\dist-ts\index.d.ts.map 104 bytes [emitted]
..\dist-ts\test.thread.d.ts 53 bytes [emitted]
..\dist-ts\test.thread.d.ts.map 116 bytes [emitted]
bundle.js 7.37 KiB 0 [emitted] main
bundle.js.map 4.43 KiB 0 [emitted] [dev] main
Entrypoint main = bundle.js bundle.js.map
[0] external "threads" 42 bytes {0} [built]
[1] ./src/index.ts 3.26 KiB {0} [built]
Well, if you out-comment the threads-plugin, then webpack won't even know that it should process the worker script and its dependencies, so it won't crash as the worker's code isn't touched by webpack at all 😉
Have you installed the @types/node
package?
https://github.com/jc-lab/threads-plugin-problem/blob/14b7cdaf46335667902538ecd20009ce2e6812b3/package.json#L9
As shown above, @types/node
is installed.
The same code in test.worker.ts works fine with index.ts.
Wow, that seems like a weird issue and requires more time to investigate then.
@andywer Please review. Thank you.
Can you please check if it's fixed in the latest version? #16 might have fixed it.
I have encountered this issue. solved it by doing:
// webpack.main.js
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
const ThreadsPlugin = require('threads-plugin');
module.exports = function(config) {
// NodeTargetPlugin must be used in order to use nodejs built-in API in workers.
config.plugins.unshift(
new ThreadsPlugin({
plugins: [new NodeTargetPlugin()]
})
);
return config;
};
this works for both main thread and renderer threads
@raz-sinay Cool, thanks!
@jc-lab Can you try and confirm that it works? If so, let's add a target
option to the threads-plugin
that defaults to the webpack config's main target
option and adds the NodeTargetPlugin
if the new setting is node
.
@andywer @jc-lab I've just discovered that you need to enable nodeIntegrationInWorker
when creating a new BrowserWindow
for fs
to work. See https://www.electronjs.org/docs/tutorial/multithreading for more information.
@pverscha Sure, but you shouldn't… 😅 One little XSS vulnerability in your webapp code and the attacker can take over your whole system at once ;)
I wouldn't use fs
in a BrowserWindow context at all, but multithreading should still be possible out of the box - in the web context via web workers and outside of it using worker threads.
(That little security insight is brought to you by someone building cryptocurrency wallets with Electron for a living, among other things ;) )
@andywer Thanks! Didn't think of that.
@raz-sinay Cool, thanks!
@jc-lab Can you try and confirm that it works? If so, let's add a
target
option to thethreads-plugin
that defaults to the webpack config's maintarget
option and adds theNodeTargetPlugin
if the new setting isnode
.
I met the same problem and the NodeTargetPlugin
trick works for me. Maybe you can add this to the documentation?
@arition Hmm, are you using the latest version of the threads-plugin
? As you can see in the loader code, the behavior that I outlined before has already been implemented.
So if you set the webpack target
option to something containing node
, it will automatically add the NodeTargetPlugin
to the worker compiler.
@andywer I think the problem still exists because the target is electron-main
in my case. The target name does not contain node
.