まずnew Worker(“./my/worker”) というやつ
Workerのコンストラクタにファイルパスを渡すやつからしてwebpackだとどう解決されるのか問題。
以上を参考にして、まず
npm install --save-dev worker-loader
つぎに、webpack.config.jsで
var plugins = [
new webpack.LoaderOptionsPlugin({
options: {
worker: {
output: {
filename: "dest/js/worker.[id].js",
}
}
}
})
];
として、自作のWorkerを使いたいほうは、
var Worker = require("worker-loader?inline!../../../Workers/my/worker");
とかしとくと
webpack 2.2の標準出力では
Child worker:
Asset Size Chunks Chunk Names
dest/js/worker.0.js 4.59 kB 0 [emitted] main
[1] ./~/babel-loader/lib!./src/js/Components/Workers/my/worker.js 1.24 kB {0} [built]
+ 1 hidden modules
となって、生成物としては、以下の648がWorkerを引っ張る共通処理、649が、648を使って自作のWorkerを提供する処理になっているので、
648:
(function(module, exports) {
var URL = window.URL || window.webkitURL;
module.exports = function(content, url) {
try {
try {
var blob;
try {
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
blob = new BlobBuilder();
blob.append(content);
blob = blob.getBlob();
} catch(e) {
blob = new Blob([content]);
}
return new Worker(URL.createObjectURL(blob));
} catch(e) {
return new Worker('data:application/javascript,' + encodeURIComponent(content));
}
} catch(e) {
return new Worker(url);
}
}
}),
649:
(function(module, exports, __webpack_require__) {
module.exports = function() {
return __webpack_require__(648)("/** 略 **/", __webpack_require__.p + "dest/js/worker.0.js");
};
このWorkerを使いたいほうでは、649を使ってWorkerインスタンスを作っていることが予想される。以下の通り。
var Worker = __webpack_require__(649);
const worker = new Worker();
となって、うまいことWorkerをwebpackでロードできている感じになった。
importScriptsがどこなの問題
このエントリ書いてるのが2017/02/19 (CET) で、このissueが立ったのが02/08、コントリビュータがbug
のlabelをつけたのが02/17なので、なかなかホット。実際、webpackの成果物で、importScripts
をしている部分を見ると、
前
importScripts("../foo.js", "../bar.js");
後
importScripts("../foo.js", "../bar.js");
となっており、webpack@2.2.1の時点でimportScripts
内のコンテキストは解決されず、生成されたworkerなjsファイル(今回のケースでいうとdest/js/worker.0.js
)に対する相対pathを書く必要がある。
TODO: このissueに動きがあったらここに追記する
Chrome拡張においてうまいことdest/js/worker.0.js
というworkerから相対pathでimportScriptsしてくれなかったので、完全なURLを渡す必要があり、以下のようにした。
自作Worker
import imports from "../imports";
const _init = (data) => {
imports(data.root)("dest/js/nice-lib-x.js", "dest/js/cool-lib-y.js");
};
onmessage = (ev) => {
switch(ev.data.cmd) {
case "init": return _init(ev.data);
case "なんか他のこといろいろ": return _awesome_action(ev.data);
default:
return;
};
};
自作べんりimports関数
export default function imports(root) {
return function() {
if (!root) throw "importScriptsする場合は必ずrootを指定してください";
const _root = root.replace(/\/+$/, "/");
importScripts(...Array.prototype.map.call(arguments, path => _root + path));
};
}
自作Worker呼ぶ方
var Worker = require("worker-loader?inline!../../../Workers/my/worker");
const worker = new Worker();
worker.postMessage({
cmd: "init",
root: chrome.extension.getURL("/")
});
これでうまい感じに
chrome-extension://{extensionId}/dest/js/nice-lib-x.js
に定義した色々が自作Workerの中でアレできるようになった。
雑感
- webpackちょっとわかってきた
- さいきんReact/ReactNativeばっかり書いてて頭おかしくなりそう
- ベルリンのスタートアップはいろいろつらい。早く日本に帰りたい
- ベルリンは好きだ
- ビール安い
- ソーセージをはじめ、肉が安い
- 食材が安いので料理がたのしい
- SAOの劇場版、ドイツでやってるっぽい
sao-movie.net
DRYな備忘録として