Моя цель - иметь возможность публиковать пакет NPM Web Worker, который можно импортировать обычным образом (import MyPkg from 'my-pkg'
), не требуя, чтобы пользователь импортировал его с помощью worker-loader
(встроенный или иным образом)
.Я попытался использовать скрипт сборки Babel, а также Webpack с worker-loader
.
. В следующих примерах есть два проекта: пакет Web Worker ("Package"), который npm link
edв тестовое приложение («Приложение»).
Пакет разбит на два файла: entry.webpack.js
и index.worker.js
.Запись, когда она построена и перемещена в /dist
, обозначается как файл main
в файле package.json, и в настоящее время она выглядит следующим образом:
entry.webpack.js
var MyPkg = require('worker-loader!./index.worker.js')
module.exports = MyPkg
index.worker.js
// This is just example code. It doesn't really matter
// what this code does so long as it ends up being run
// as a Web Worker.
var selfRef = self;
function ExampleWorker () {
console.log('Running Worker...');
setTimeout(function () {
// wait 10 seconds then post a message
selfRef.postMessage({foo: "bar"});
}, 10000)
}
module.exports = ExampleWorker
Затем я связываю пакет с Webpack:
package.json
"build": "rm -rf dist/*.* && webpack --progress"
webpack.config.js
module.exports = {
mode: 'production',
devtool: 'source-map',
entry: __dirname + '/src/entry.webpack.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
optimization: {
minimize: false
}
}
Это создает два файла: bundle.js
и файл Web Worker в виде хэша: [hash].worker.js
с кодом, который мы хотим оценить в нем.Они играют ключевую роль в этом, потому что мы использовали worker-loader
inline для импорта, скомпилированный вывод webpack выглядит примерно так:
module.exports = function() {
return new Worker(__webpack_require__.p + "53dc9610ebc22e0dddef.worker.js");
};
Наконец, приложение должно иметь возможность импортировать его и использовать егонапример:
App.js
import MyPkg from 'my-pkg'
// logging MyPkg here produces `{}`
const worker = new MyPkg()
// That throws an Error:
// Uncaught TypeError: _my_pkg__WEBPACK_IMPORTED_MODULE_4___default.a is not a constructor
worker.onmessage = event => {
// this is where we'd receive our message from the web worker
}
Однако вы можете заставить его работать, если в самом приложении вы импортируетерабочая сборка выглядит следующим образом:
import MyPkg from 'my-pkg/dist/53dc9610ebc22e0dddef.worker.js'
Но пакет должен:
A) НЕ требовать от приложений, использующих этот пакет, явной установки worker-loader
и B) неЯ должен явно ссылаться на my-pkg/dist/[hash].worker.js
.
Я также пытался указать встроенный [hash].worker.js' as the
main` в package.json, но это тоже не работает.
Править1: Я забыл упомянуть, что все это основано на том, как react-pdf
делает это.Если вы посмотрите на /src/entry.webpack.js
и следите за тем, как он работает в пакете, вы увидите несколько сходств.