[英]Use Webpack to split out a module so that it can be loaded in a WebWorker
I have a web app that I compile with webpack. 我有一个web应用程序,我用webpack编译。 One of the modules that my code uses is named table.js
. 我的代码使用的其中一个模块名为table.js
。 Until recently, it's just been another module and has been compiled into my bundle.js
file with everything else. 直到最近,它只是另一个模块,并已编译到我的bundle.js
文件中的所有其他内容。
Now I need to run table.js
in a Web Worker, so I need to pull it and its dependencies into a separate file that can be loaded both standalone and by my other modules. 现在我需要在Web Worker中运行table.js
,所以我需要将它和它的依赖项拉到一个单独的文件中,该文件可以单独加载,也可以由我的其他模块加载。
At first I thought to include table.js
in my webpack.config.js
's entry
. 起初我想在我的webpack.config.js
的entry
包含table.js
。
var config = {
...
entry: {
app: [ './src/main.js', './src/classes/table.js' ],
vendors: [],
},
...
}
That didn't work. 那没用。 Then I thought to separate it out like my vendors bundle. 然后我想像我的供应商捆绑一样把它分开。
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'));
This seems to pull Table and its dependencies into a chunk of bundle.js
, 1.bundle.js
. 这似乎将Table及其依赖项拉入了bundle.js
, 1.bundle.js
一大块。 Unfortunately, then calling import Table from 'table'
causes this error: 不幸的是,然后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)
I also have a circular dependency between TableStore
and Table
. 我在TableStore
和Table
之间也有一个循环依赖。 TableStore
needs to stay in bundle.js
because it shouldn't be loaded into the Web Worker. TableStore
需要保留在bundle.js
因为它不应该加载到Web Worker中。 Previously, when I've needed to throw things into a separate chunk, I've done: 以前,当我需要把东西扔进一个单独的块时,我已经完成了:
if (someThingNeedsRequiring) {
require.ensure([], () => {
require('something');
}
}
With the circular dependency, this doesn't seem to work. 由于循环依赖,这似乎不起作用。
/* 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';
Could someone set me straight on the correct way to have my webpack.config.js
and how to use my import
s in my module files? 有人可以让我直接找到我的webpack.config.js
以及如何在我的模块文件中使用我的import
的正确方法吗?
(It's been quite a while since I figured this out, and I haven't touched the project in nearly six months, so I may have missed some of the details. Comment if it's not working, and I'll try to figure out what I'm missing.) (已经有一段时间了,因为我发现了这个问题,而且我近六个月没有接触到这个项目,所以我可能错过了一些细节。评论一下它是否有效,我会试着找出什么我迷路了。)
It turns out there are two handy-dandy JavaScript packages for doing what I want: worker-loader
and workerjs
. 事实证明,有两个方便的dandy JavaScript包可以做我想要的: worker-loader
和workerjs
。
npm install --save workerjs worker-loader
I added this in my webpack.config.js: 我在webpack.config.js中添加了这个:
var config = {
// ...
worker: {
output: {
filename: '[name].worker.js',
chunkFilename: '[name].worker.js'
}
},
// ...
}
In order to specify that I want my class to be run in a WebWorker file, my require looks like: 为了指定我希望我的类在WebWorker文件中运行,我的需要如下所示:
// ecmaScript 6
import TableWorker from 'worker?name=tableRoller!path/to/table';
// ecmaScript 5
var TableWorker = require('worker?name=tableRoller!path/to/table');
TableWorker
is just a variable name I used for table.js's export default class Table {...}
. TableWorker
只是我用于table.js的export default class Table {...}
的变量名。 The name=tableRoller
specifies the generated outputted [name].worker.js
filename. name=tableRoller
指定生成的输出[name].worker.js
文件名。 For example, I have another WebWorker named distCalc.worker.js
, so my import
looks like: 例如,我有另一个名为distCalc.worker.js
WebWorker,所以我的import
如下:
import DistWorker from 'worker?name=distCalc!path/to/distWorker';
Note that in this case, distWorker
only ever runs in a WebWorker, while Table
is used in both my main.js
entry point and my tableRoller.worker.js
WebWorker file. 请注意,在这种情况下, distWorker
只能在WebWorker中运行,而Table
在我的main.js
入口点和tableRoller.worker.js
WebWorker文件中使用。
workerjs
and worker-loader
generate a new entry point file and pull in all of the dependencies of those classes. workerjs
和worker-loader
生成一个新的入口点文件,并提取这些类的所有依赖项。 Tobias Koppers (worker-loader) and Eugene Ware (workerjs) are geniuses. Tobias Koppers(工人装载者)和Eugene Ware(工人家庭)是天才。
My _inWebWorker
detection is: 我的_inWebWorker
检测是:
let _inWebWorker = typeof Window === 'undefined';
Change output filename in your webpack.config.js file 更改webpack.config.js文件中的输出文件名
output: {
path: __dirname + '/public/dist/',
filename: '[name].js',
publicPath: '/dist/',
sourceMapFile: '[file].map'
},
then Webpack can separate your entries with its name in dist directory. 然后Webpack可以将您的条目与dist目录中的名称分开。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.