javascriptwebpackfrontendviteweb-worker

After trying to migrate a project from Webpack to Vite, JS code fails to execute


There was a Webpack configuration that I used to build a separate bundle for a JS worker (it must be in a separate file) and everything worked well. Here is the webpack config:

const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    entry: {
        worker: {
            import: './assets/scripts/worker.ts',
            filename: './worker_bundle.js',
        }
    },
    output: {
        'path': path.resolve(__dirname, 'static', 'js')
    },
    plugins: [
        new webpack.ProvidePlugin({
            Buffer: ['buffer', 'Buffer'],
            process: 'process/browser',
        })
    ],
    resolve: {
        fallback: {
            "assert": require.resolve('assert'),
            "fs": false,
            "util": require.resolve("util"),
            "path": require.resolve("path-browserify")
        },
        extensions: ['.ts', '.js', '.json']
    },
    module: {
        rules: [
            {
                test: RegExp('\\.ts$'),
                use: 'ts-loader',
                exclude: RegExp('node_modules')
            }
        ]
    },
    externals: {
        jquery: 'jQuery',
    },
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                extractComments: false,
                terserOptions: {
                    format: {
                        comments: false,
                    },
                },
            }),
        ],
    },
}

Then I learned about the modern JS technology called "Vite". It compiles much faster than Webpack, but now the bundle wouldn't execute in the browser no matter what I do.

Here is the new Vite config that builds JS code:

import path from 'path';
import commonjs from '@rollup/plugin-commonjs';
import topLevelAwait from "vite-plugin-top-level-await";
import {nodePolyfills} from "vite-plugin-node-polyfills";


module.exports = {
    plugins: [
        nodePolyfills({
            overrides: {
                fs: 'memfs'
            }
        }),
    ],
    build: {
        minify: false,
        rollupOptions: {
            input: {
                regexes_worker: path.resolve(__dirname, "./assets/scripts/worker.ts"),
            },
            output: [
                {
                    dir: path.resolve(__dirname, 'static/js'),
                    entryFileNames: 'worker_bundle.js',
                    globals: {
                        jquery: '$'
                    },

                    esModule: true
                }
            ],
            plugins: [
                commonjs({
                    filter(id) {
                        if (id.includes('node_modules')) {
                            return true
                        }
                    }
                }),
                topLevelAwait(),
            ]
        },
        emptyOutDir: false
    },
}

The code fails with the following error printed to the devtools console:

Uncaught (in promise) TypeError: Function has non-object prototype 'undefined' in instanceof check

Here is the snippet of the bundle code built with Vite, where the code fails:

function getAugmentedNamespace(n) {
    if (n.__esModule) return n;
    var f = n.default;
    if (typeof f == "function") {
        var a = function a2() {
            if (this instanceof a2 /* !! The execution fails here !! */ ) {
                return Reflect.construct(f, arguments, this.constructor);
            }
            return f.apply(this, arguments);
        };
        a.prototype = f.prototype;
    } else a = {};
    Object.defineProperty(a, "__esModule", {
        value: true
    });
    Object.keys(n).forEach(function (k) {
        var d = Object.getOwnPropertyDescriptor(n, k);
        Object.defineProperty(a, k, d.get ? d : {
            enumerable: true,
            get: function () {
                return n[k];
            }
        });
    });
    return a;
}

I have tried:

  1. compiling bundle with different versions of JS
  2. using various Vite plugins to mimic Webpack functionality
  3. turning on the terser compiler like in Webpack

Nothing helped and now I have no idea what to do.


Solution

  • I had the same situation and I used vite-plugin-commonjs. I found it on the internet years ago and it fixed everything, but I have no idea how it works. I added it to the "root" level "plugins".