Use Webpack to split the module so that it can be loaded into WebWorker

I have a web application that I compile using webpack. One of the modules that my code uses is called table.js . Until recently, it was another module and was compiled into my bundle.js file with everything else.

Now I need to run table.js in Web Worker, so I need to pull it and its dependencies into a separate file, which can be downloaded both offline and my other modules.

At first I thought to include table.js in my webpack.config.js entry .

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

This did not work. Then I decided to split it up, as with my suppliers.

 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 the table and its dependencies into a piece of bundle.js , 1.bundle.js . Unfortunately, calling import Table from 'table' raises this error:

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

I also have a circular relationship between TableStore and Table . TableStore should remain in bundle.js because it should not be loaded into Web Worker. Previously, when I needed to throw things in a separate piece, I did:

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

With cyclic dependency, this does not 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'; 

Can someone properly install me with my webpack.config.js and how to use my import in my module files?

+6
source share
2 answers

(It has been quite a long time since I realized this, and I didn’t touch the project almost six months later, so maybe I missed some details. Please comment if it does not work, and I will try to find out what I am missing.)

webpack.config

It turned out that to do what I want, there are two desktop JavaScript packages: worker-loader and workerjs .

 npm install --save workerjs worker-loader 

I added this to my webpack.config.js:

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

require ()

To indicate that I want my class to run in a WebWorker file, my query looks like this:

 // 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 the variable name that I used for table.js export default class Table {...} . name=tableRoller indicates the generated name=tableRoller file [name].worker.js . For example, I have another WebWorker named distCalc.worker.js , so my import looks like this:

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

Note that in this case, distWorker only works in WebWorker, and Table used both in my main.js entry point and in my tableRoller.worker.js WebWorker file.

workerjs and worker-loader generate a new entry point file and use all the dependencies of these classes. Tobias Koppers (loader worker) and Eugene War (workers) are geniuses.

WebWorker Discovery

My _inWebWorker discovery:

 let _inWebWorker = typeof Window === 'undefined'; 
+6
source

Change the output of file_name in webpack.config.js

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

then Webpack can separate your entries with their name in the dist directory.

0
source

Source: https://habr.com/ru/post/988945/


All Articles