How to import a library like moment.js into a web worker

。_饼干妹妹 提交于 2019-12-10 14:48:57

问题


Can I import a library installed with npm into a web worker?

I need to use the moment.js library into a web worker.

It is installed via npm into the node_modules/moment directory

I already have tried with this at the top of the worker.js file:

importScripts('/node_modules/moment/moment.js');

But I get

GET http://192.168.2.1:8100/node_modules/moment/moment.js 404 (Not Found)

回答1:


Yes, it's possible, chances are you're already using a popular bundler like webpack or parcel, but even if you're not it's still possible, though probably not directly from node_modules

With Parcel

main.js
// relative path to the worker from current file
const worker = new Worker('../utils/myWorker.js');
myWorker.js
// use import like you would in any other file
import moment from 'moment';

console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);

With Webpack (as entry)

main.js
// relative to the expected public path (have in mind any filename transforms like hashing)
const worker = new Worker('myWorker.bundle.js');
myWorker.js
// use import like you would in any other file
import moment from 'moment';

console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
webpack.config.js
{
  entry: {
    main: './src/app/main.js'
    worker: './src/utils/myWorker.js',
  },
  output: {
    path: `${ROOT_PATH}/public`,
    filename: '[name].bundle.js',
  }
}

With Webpack (worker-loader)

main.js
// relative path to the worker from current file
import Worker from '../utils/myWorker.worker.js';

const worker = new Worker();
myWorker.worker.js
// use import like you would in any other file
import moment from 'moment';

console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
webpack.config.js
{
  module: {
    rules: [
      {
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' }
      }
    ]
  }
}
  • npm install worker-loader --save-dev
  • Webpack worker-loader documentation https://webpack.js.org/loaders/worker-loader/

You can always import the library from a CDN

myWorker.js
importScripts('//cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js');

console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);

Other bundlers

  • Web workers cannot importScripts from parent folders for security reasons
  • The node_modules folder is usually at the root of the project so you can't access it with importScripts
  • The bundler needs to be configured so that the content can be aliased or copied to a location the worker can access

AngularCLI and Ionic

For projects using webpack as a bundler the 2 webpack solutions can be adapted as long as you can access the webpack config and customize it.

The "Webpack (as entry)" example was actually borrowed from Angular CLI generated app with Web Workers

  • It explains how to modify the setup to bootstrap angular using web workers
  • It have been referenced as a webworker solution for Ionic projects too

Note on TypeScript

  • you may need a separate ts config in the worker folder
  • Structuring a TypeScript project with workers
{
  "extends": "../generic-tsconfig.json",
  "compilerOptions": {
    "lib": ["esnext", "webworker"],
  }
}


来源:https://stackoverflow.com/questions/48931878/how-to-import-a-library-like-moment-js-into-a-web-worker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!