使用Webpack将模块拆分,以便可以将其加载到WebWorker中
我有一个web应用程序,我用webpack编译。 我的代码使用的一个模块名为table.js
。 直到最近,它只是另一个模块,已被编译到我的bundle.js
文件中。
现在我需要在一个Web Worker中运行table.js
,所以我需要把它和它的依赖关系放到一个单独的文件中,可以单独加载,也可以通过其他模块加载。
起初我想在我的webpack.config.js
的entry
包含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.js
, 1.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)
我也有TableStore
和Table
之间的循环依赖。 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-loader
和workerjs
。
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文件中使用。
workerjs
和worker-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目录中的名字分开。