使用Webpack将模块拆分,以便可以将其加载到WebWorker中

我有一个web应用程序,我用webpack编译。 我的代码使用的一个模块名为table.js 。 直到最近,它只是另一个模块,已被编译到我的bundle.js文件中。

现在我需要在一个Web Worker中运行table.js ,所以我需要把它和它的依赖关系放到一个单独的文件中,可以单独加载,也可以通过其他模块加载。

起初我想在我的webpack.config.jsentry包含table.js

 var config = { ... entry: { app: [ './src/main.js', './src/classes/table.js' ], vendors: [], }, ... } 

这没有用。 然后,我想像我的供应商捆绑分开它。

 var config = { /* for vendors (and other modules) we have a CDN for */ addExternal: function (name, globalVar) { this.externals[name] = globalVar; this.entry.vendors.push(name); }, /* for vendors we don't have a CDN for */ addVendor: function (name, path) { this.resolve.alias[name] = path; this.entry.vendors.push(name); }, addPlugin: function (plugin) { this.plugins.push(plugin); }, entry: { app: [ './src/main.js' ], vendors: [], table: [ __dirname + '/src/classes/table.js' ] }, plugins: [], externals: { }, output: { path: __dirname + '/public/dist/', filename: 'bundle.js', publicPath: '/dist/', sourceMapFile: '[file].map' }, resolve: { alias: { 'table': './src/classes/table.js' }, extensions: [ '', '.js', '.jsx' ] }, ... } /* add vendors and externals */ ... config.addPlugin(new CommonsChunkPlugin('vendors', 'vendors.js')); config.addPlugin(new CommonsChunkPlugin('table', 'table.js')); 

这似乎将Table及其依赖关系拉入一大堆bundle.js1.bundle.js 。 不幸的是,然后import Table from 'table'调用import Table from 'table'会导致此错误:

 ERROR in CommonsChunkPlugin: While running in normal mode it's not allowed to use a non-entry chunk (table) 

我也有TableStoreTable之间的循环依赖。 TableStore需要保留在bundle.js因为它不应该加载到Web Worker中。 以前,当我需要把东西扔进一个单独的块时,我已经做了:

 if (someThingNeedsRequiring) { require.ensure([], () => { require('something'); } } 

随着循环依赖,这似乎不工作。

 /* table.js */ let _inWebWorker = self instanceof Window, TableStore = null; if (!_inWebWorker) { require.ensure([], function() { TableStore = require('../stores/table-store'); } ); } /* table-store.js */ import Table from 'table'; 

有人可以设置我正确的方式有我的webpack.config.js和如何在我的模块文件中使用我的import

(自从我弄明白了,已经有一段时间了,在接近六个月的时间里,我还没有触及过这个项目,所以我可能错过了一些细节,如果不行的话,我会试着弄清楚我丢了。)

webpack.config

事实certificate,有两个方便的Dandy JavaScript包,用于执行我想要的操作: worker-loaderworkerjs

 npm install --save workerjs worker-loader 

我在我的webpack.config.js中添加了这个:

 var config = { // ... worker: { output: { filename: '[name].worker.js', chunkFilename: '[name].worker.js' } }, // ... } 

要求()

为了指定我希望我的类在WebWorker文件中运行,我的require如下所示:

 // ecmaScript 6 import TableWorker from 'worker?name=tableRoller!path/to/table'; // ecmaScript 5 var TableWorker = require('worker?name=tableRoller!path/to/table'); 

TableWorker只是我用于table.js的export default class Table {...}一个variables名。 name=tableRoller指定生成的输出[name].worker.js文件名。 例如,我有另一个名为distCalc.worker.js WebWorker,所以我的import如下所示:

 import DistWorker from 'worker?name=distCalc!path/to/distWorker'; 

请注意,在这种情况下, distWorker只能在WebWorker中运行,而Table则在我的main.js入口点和我的tableRoller.worker.js WebWorker文件中使用。

workerjsworker-loader生成一个新的入口点文件,并workerjs这些类的所有依赖关系。 Tobias Koppers(工人装载者)和Eugene Ware(workerjs)是天才。

检测WebWorker

我的_inWebWorker检测是:

 let _inWebWorker = typeof Window === 'undefined'; 

更改webpack.config.js文件中的输出文件名

 output: { path: __dirname + '/public/dist/', filename: '[name].js', publicPath: '/dist/', sourceMapFile: '[file].map' }, 

那么Webpack可以将你的条目与它在dist目录中的名字分开。