my problem is difficult for me to describe clearly, so hopefully you'll understand me.
I'm trying to bundle a Vue component with rollup and publish it on NPM. The component uses a function in which a create a Worker like this
new Worker('@/workers/tree-traversal-worker.ts', { type: 'module' })
This works perfectly fine in development and is buildable with the vue build command: vue-cli-service build. However, I'd ideally like to use rollup for this since it can generate an esm format.
I've tried several rollup plugins, namely rollup-plugin-web-worker-loader, @qintx/rollup-plugin-web-worker-loader, and rollup-plugin-web-worker-loader'. The furthest I've gotten with was @surma/rollup-plugin-off-main-thread which successfully generated a dedicated worker file and changed the URL in the new Worker(...) appropriately during bundle. However, when I try to install it in another Vue project, I get this error in console
tree-traversal-worker-bc0e96e1.js:1 Uncaught SyntaxError: Unexpected token '<'
If I understand it correctly, it simply means that the file was not found since it tries to resolve a script with relative path /tree-traversal-worker-bc0e96e1.js rather than the actual file stored in node_modules.
So my questions are following. Has anyone managed to somehow bundle a Vue component(s) that use web workers (with or without rollup?). And if not, do you think it's better to pursue a solution that would somehow import the script from Worker from a different file or should I look more into a solution that inlines the worker script into a single bundled file (have tried it as well, without success though)
Any help would be much appreciated. Below is my rollup config that relates only to esm format output
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
import alias from '@rollup/plugin-alias';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import babel from 'rollup-plugin-babel';
import minimist from 'minimist';
import postCSS from 'rollup-plugin-postcss';
import OMT from '@surma/rollup-plugin-off-main-thread';
const postcssConfig = require('../postcss.config');
const esbrowserslist = fs.readFileSync('./.browserslistrc')
.toString()
.split('\n')
.filter((entry) => entry && entry.substring(0, 2) !== 'ie');
const argv = minimist(process.argv.slice(2));
const projectRoot = path.resolve(__dirname, '..');
const baseConfig = {
input: 'src/performant-vue-tree.ts',
plugins: {
preVue: [
alias({
resolve: ['.js', '.jsx', '.ts', '.tsx', '.vue', '.css'],
entries: {
'@': path.resolve(projectRoot, 'src'),
},
}),
],
replace: {
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.ES_BUILD': JSON.stringify('false'),
},
vue: {
css: true,
compileTemplate: true,
style: {
postcssPlugins: [...postcssConfig.plugins],
},
},
/*
* Has to be used for processing postcss in general
* Does not resolve postcss in SFC. For that is vue.style.postcssPlugins
*/
postCSS: {
extract: false,
plugins: [],
},
babel: {
runtimeHelpers: true,
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
},
},
};
const external = [
'vue',
'lodash',
'promise-worker',
'json-fn',
'@clr/icons',
'@clr/icons/shapes/all-shapes',
'vue-virtual-scroller',
'vuex',
'vue-wait',
];
// Customize configs for individual targets
const buildFormats = [];
if (!argv.format || argv.format === 'es') {
const esConfig = {
...baseConfig,
external,
output: {
dir: 'dist',
format: 'esm',
exports: 'named',
},
plugins: [
OMT({
useEval: true,
format: 'esm',
}),
postCSS(baseConfig.postCSS),
replace({
...baseConfig.plugins.replace,
'process.env.ES_BUILD': JSON.stringify('true'),
}),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
babel({
...baseConfig.plugins.babel,
presets: [
[
'@babel/preset-env',
{
targets: esbrowserslist,
},
],
],
}),
commonjs(),
],
};
buildFormats.push(esConfig);
}