Ben Butterworth
Ben Butterworth

Reputation: 28572

Web Workers written in Typescript in Webpack 5: SyntaxError: Cannot use import statement outside a module

Webpack 5 documentation mentions that worker-loader is not needed anymore, and it seems easy for javascript files. However, I am using Typescript, and I'm not able to get my worker.js output file working properly. When I launch load the webworker with const worker = new Worker(workerPath);, I get

Uncaught SyntaxError: Cannot use import statement outside a module

Note: my workerPath is "dist/app.worker.js" and this file exists, but it sadly contains either import or require statements, which don't work in the browser. I think need to bundle these together, but I'm not sure how. Currently, it contains the following code, and I hoped that auth.ts will be bundled in:

import Auth from "./auth";

Upvotes: 5

Views: 2525

Answers (1)

Ben Butterworth
Ben Butterworth

Reputation: 28572

Instead of using worker-loader or the default webpack config using module.export = {...}, I exported multiple configurations. Specifically, I created 2 entry points (main and worker in webpack.config.js, and used module.exports = [main, worker]. In the code, I referenced the second entry point using const workerPath = "./dist/worker_name.worker.js".

My webpack.config.js

const path = require('path')

const main = {
    entry: "./src/index.ts",
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: "dist/"
    },
    context: __dirname,
    devtool: "source-map",
    mode: "development",
    resolve: {
        modules: [
            'src',
            'node_modules'
        ],
        extensions: [
            '.js',
            '.ts',
            '.tsx'
        ],
        plugins: [],
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                options: {
                    transpileOnly: true,
                },
            },
        ],
    },
}

const worker = {
    entry: "./src/worker_name.worker.ts",
    output: {
        filename: 'worker_name.worker.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: "dist/"
    },
    target: "webworker",
    devtool: "source-map",
    mode: "development",
    resolve: {
        modules: [
            'src',
            'node_modules'
        ],
        extensions: [
            '.js',
            '.ts',
            '.tsx'
        ],
        plugins: [],
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                options: {
                    transpileOnly: true,
                },
            },
        ],
    },
}


module.exports = [main, worker]

You can probably refactor the above to make it shorter by sharing code between them.

Upvotes: 4

Related Questions