threads-plugin icon indicating copy to clipboard operation
threads-plugin copied to clipboard

Electron & Webpack 5 - worker bundles created in Production build

Open dulu93 opened this issue 1 year ago • 0 comments

Hi, I have been having some trouble getting threads & threads-plugin to properly work with electron. I have used it before on a react web app and had no issues, but its not the case for the electorn app.

I have been following the setup documentation, but I seem to have missed something at some point.

Everything is working fine in dev mode but as soon as I build a debian package, install and start it, the workers are not accessible and I get the following error message

Cannot find module '/opt/FormicaConnect/resources/app.asar/dist/main/workers/runAction.ts'
Require stack:
- /opt/FormicaConnect/resources/app.asar/dist/main/main.js

Im pretty sure its because the workers are not bundled into own files, like they did on my web version.

My plan is to spawn workers on electrons background process, which is running nodejs.

await spawn<RunAction>(new Worker('./workers/runAction.ts'));

funny thing is that wepack only creates worker bundles when the workers are spawned with the following code:

await spawn<RunAction>(new Worker(new URL('./workers/runAction.ts', import.meta.url)));

but then again its not working either in dev mode or production mode. in production mode it would complain that runAction.ts has no access to packages like electron-fetch.

I know I have to add the worker bundles to the "asarUnpack" option in my package.json, but the workers are not being bundled in the first place.

Any ideas what I might have missed? Help would be much appreciated.

Heres some example code:

runAction.ts:

import { expose } from 'threads/worker';
import fetch, { HeadersInit } from 'electron-fetch';

export type RunAction = (url: string, method: string, headers: HeadersInit, body: string) => Promise<string>;

expose(async function runAction(url: string, method: string, headers: HeadersInit, body: string): Promise<string> {
  const response = await fetch(url, { method, redirect: 'follow', headers, body });

  return response.text();
});

how I spawn the worker: await spawn<RunAction>(new Worker('./workers/runAction.ts'));

webpack.config.base.ts:

//Base webpack config used across other specific configs

import webpack from 'webpack';
import webpackPaths from './webpack.paths';
import { dependencies as externals } from '../../release/app/package.json';

const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const ThreadsPlugin = require('threads-plugin');

const configuration: webpack.Configuration = {
    externals: [...Object.keys(externals || {})],

    stats: 'errors-only',
    module: {
        rules: [

            {
                // test: /\.[jt]sx?$/,
                test: /\.(ts|js)x?$/,
                exclude: /node_modules/,
                use: {
                    loader: 'ts-loader',
                    options: {
                        // Remove this line to enable type checking in webpack builds
                        transpileOnly: true,
                        compilerOptions: {
                            module: 'esnext',
                        },
                    },
                },
            },
        ],
    },

    output: {
        path: webpackPaths.srcPath,
        // https://github.com/webpack/webpack/issues/1114
        library: {
            type: 'commonjs2',
        },
    },

    /**
     * Determine the array of extensions that should be used to resolve modules.
     */
    resolve: {
        fallback: { path: false, fs: false },
        extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
        modules: [webpackPaths.srcPath, 'node_modules'],
    },

    plugins: [
        new ThreadsPlugin(),
        new webpack.EnvironmentPlugin({
            NODE_ENV: 'production',
        }),
        new CopyPlugin({
            patterns: [
                {
                    from: path.resolve(
                        process.cwd(),
                        './node_modules/sql.js/dist/sql-wasm.js'
                    ),
                    to: webpackPaths.dist,
                },
            ],
        }),
    ],
};

export default configuration;
the build commands I use:
`"build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
Versions used:
- threads: 1.7.0
- threads-plugin: 1.4.0
- node: v16
- webpack: 5.72.0

Please to not close this issue if I dont answer to questions directly. I might be on vacation in between.

Thanks in advance.

dulu93 avatar Sep 23 '22 14:09 dulu93