diff --git a/CHANGELOG.md b/CHANGELOG.md index 3884698..8aa929b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.11.0](https://github.com/NativeScript/worker-loader/compare/0.10.0...0.11.0) (2020-02-20) + +### Bug Fixes + +* worker compilation should not be async ([#54](https://github.com/NativeScript/worker-loader/pull/54)) + + ## [0.9.5](https://github.com/NativeScript/worker-loader/compare/0.9.4...0.9.5) (2019-02-06) diff --git a/src/index.js b/src/index.js index c28f89d..f57b4e6 100644 --- a/src/index.js +++ b/src/index.js @@ -37,103 +37,120 @@ module.exports = function workerLoader() { }; const requests = []; +let pitchPromise = Promise.resolve(); module.exports.pitch = function pitch(request) { - if (!this.webpack) { - throw new Error("Only usable with webpack"); - } - const callback = this.async(); - const options = loaderUtils.getOptions(this) || {}; - const compilerOptions = this._compiler.options || {}; - const pluginOptions = compilerOptions.plugins.find(p => p[NATIVESCRIPT_WORKER_PLUGIN_SYMBOL]).options; - - // handle calls to itself to avoid an infinite loop - if (requests.indexOf(request) === -1) { - requests.push(request); - } else { - return callback(null, ""); - } - validateSchema(optionsSchema, options, "Worker Loader"); - if (!this._compilation.workerChunks) { - this._compilation.workerChunks = []; - } + pitchPromise = pitchPromise.then(() => + new Promise((resolve) => { + if (!this.webpack) { + const error = new Error("Only usable with webpack"); + resolve(); + return callback(error); + } - const filename = loaderUtils.interpolateName(this, options.name || "[hash].worker.js", { - context: options.context || this.rootContext, - regExp: options.regExp, - }); - - const outputOptions = { - filename, - chunkFilename: `[id].${filename}`, - namedChunkFilename: null, - }; - - const plugins = (pluginOptions.plugins || []).map(plugin => { - if (typeof plugin !== "string") { - return plugin; - } - const found = compilerOptions.plugins.find(p => p.constructor.name === plugin); - if (!found) { - console.warn(`Warning (worker-plugin): Plugin "${plugin}" is not found.`); - } - return found; - }); - - const workerCompiler = this._compilation.createChildCompiler("worker", outputOptions, plugins); - new WebWorkerTemplatePlugin(outputOptions).apply(workerCompiler); - if (this.target !== "webworker" && this.target !== "web") { - new NodeTargetPlugin().apply(workerCompiler); - } + const options = loaderUtils.getOptions(this) || {}; + const compilerOptions = this._compiler.options || {}; + const pluginOptions = compilerOptions.plugins.find(p => p[NATIVESCRIPT_WORKER_PLUGIN_SYMBOL]).options; + + // handle calls to itself to avoid an infinite loop + if (requests.indexOf(request) === -1) { + requests.push(request); + } else { + resolve(); + return callback(null, ""); + } + + try { + validateSchema(optionsSchema, options, "Worker Loader"); + } catch (err) { + resolve(); + return callback(err); + } + + if (!this._compilation.workerChunks) { + this._compilation.workerChunks = []; + } + + const filename = loaderUtils.interpolateName(this, options.name || "[hash].worker.js", { + context: options.context || this.rootContext, + regExp: options.regExp, + }); - new SingleEntryPlugin(this.context, `!!${request}`, "main").apply(workerCompiler); - const plugin = { name: "WorkerLoader" }; - - workerCompiler.hooks.thisCompilation.tap(plugin, compilation => { - /** - * A dirty hack to disable HMR plugin in childCompilation: - * https://github.com/webpack/webpack/blob/4056506488c1e071dfc9a0127daa61bf531170bf/lib/HotModuleReplacementPlugin.js#L154 - * - * Once we update to webpack@4.40.3 and above this can be removed: - * https://github.com/webpack/webpack/commit/1c4138d6ac04b7b47daa5ec4475c0ae1b4f596a2 - */ - compilation.hotUpdateChunkTemplate = null; - }); - - workerCompiler.runAsChild((err, entries, childCompilation) => { - if (err) { - return callback(err); - } - - if (entries[0]) { - const fileDeps = Array.from(childCompilation.fileDependencies); - this.clearDependencies(); - fileDeps.forEach(fileName => { - this.addDependency(fileName); + const outputOptions = { + filename, + chunkFilename: `[id].${filename}`, + namedChunkFilename: null, + }; + + const plugins = (pluginOptions.plugins || []).map(plugin => { + if (typeof plugin !== "string") { + return plugin; + } + const found = compilerOptions.plugins.find(p => p.constructor.name === plugin); + if (!found) { + console.warn(`Warning (worker-plugin): Plugin "${plugin}" is not found.`); + } + return found; }); - /** - * Clears the hash of the child compilation as it affects the hash of the parent compilation: - * https://github.com/webpack/webpack/blob/4056506488c1e071dfc9a0127daa61bf531170bf/lib/Compilation.js#L2281 - * - * If we don't clear the hash an emit of runtime.js and an empty [somehash].hot-update.json will happen on save without changes. - * This will restart the NS application. - */ - childCompilation.hash = ""; - const workerFile = entries[0].files[0]; - this._compilation.workerChunks.push(workerFile); - const workerFactory = getWorker(workerFile); - - // invalidate cache - const processedIndex = requests.indexOf(request); - if (processedIndex > -1) { - requests.splice(processedIndex, 1); + + const workerCompiler = this._compilation.createChildCompiler("worker", outputOptions, plugins); + new WebWorkerTemplatePlugin(outputOptions).apply(workerCompiler); + if (this.target !== "webworker" && this.target !== "web") { + new NodeTargetPlugin().apply(workerCompiler); } - return callback(null, `module.exports = function() {\n\treturn ${workerFactory};\n};`); - } + new SingleEntryPlugin(this.context, `!!${request}`, "main").apply(workerCompiler); + const plugin = { name: "WorkerLoader" }; + + workerCompiler.hooks.thisCompilation.tap(plugin, compilation => { + /** + * A dirty hack to disable HMR plugin in childCompilation: + * https://github.com/webpack/webpack/blob/4056506488c1e071dfc9a0127daa61bf531170bf/lib/HotModuleReplacementPlugin.js#L154 + * + * Once we update to webpack@4.40.3 and above this can be removed: + * https://github.com/webpack/webpack/commit/1c4138d6ac04b7b47daa5ec4475c0ae1b4f596a2 + */ + compilation.hotUpdateChunkTemplate = null; + }); - return callback(null, ""); - }); + workerCompiler.runAsChild((err, entries, childCompilation) => { + if (err) { + resolve(); + return callback(err); + } + + if (entries[0]) { + const fileDeps = Array.from(childCompilation.fileDependencies); + this.clearDependencies(); + fileDeps.forEach(fileName => { + this.addDependency(fileName); + }); + /** + * Clears the hash of the child compilation as it affects the hash of the parent compilation: + * https://github.com/webpack/webpack/blob/4056506488c1e071dfc9a0127daa61bf531170bf/lib/Compilation.js#L2281 + * + * If we don't clear the hash an emit of runtime.js and + * an empty [somehash].hot-update.json will happen on save without changes. + * This will restart the NS application. + */ + childCompilation.hash = ""; + const workerFile = entries[0].files[0]; + this._compilation.workerChunks.push(workerFile); + const workerFactory = getWorker(workerFile); + + // invalidate cache + const processedIndex = requests.indexOf(request); + if (processedIndex > -1) { + requests.splice(processedIndex, 1); + } + + resolve(); + return callback(null, `module.exports = function() {\n\treturn ${workerFactory};\n};`); + } + + resolve(); + return callback(null, ""); + }); + })); }; - diff --git a/src/package.json b/src/package.json index 74744dd..6eaba34 100644 --- a/src/package.json +++ b/src/package.json @@ -1,11 +1,11 @@ { "name": "nativescript-worker-loader", - "version": "0.10.0", + "version": "0.11.0", "author": "NativeScript team", "description": "nativescript worker loader module for webpack", "scripts": { "pretest": "babel ./test/test.es6.js --out-file ./test/test.es5.js", - "test": "mocha test/test.es5.js", + "test": "mocha test/test.es5.js --timeout 5000", "posttest": "eslint .", "prepare": "npm run test" }, diff --git a/src/test/test.es6.js b/src/test/test.es6.js index 4ecec21..e70d136 100644 --- a/src/test/test.es6.js +++ b/src/test/test.es6.js @@ -171,10 +171,10 @@ describe("worker-loader", () => { module: { rules: [ { - test: /worker\.js$/, + test: /(w1|w2)\.js$/, loader: "../index.js", options: { - inline: true, + name: "[name].js", fallback: false, }, },