diff --git a/CHANGELOG.md b/CHANGELOG.md index 81cce8a..8f6e723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [3.0.3](https://github.com/webpack-contrib/worker-loader/compare/v3.0.2...v3.0.3) (2020-09-22) + + +### Bug Fixes + +* remove unnecessary webpack sourceURL ([#289](https://github.com/webpack-contrib/worker-loader/issues/289)) ([eef2757](https://github.com/webpack-contrib/worker-loader/commit/eef27574160f519c344dfa5fd981b7ac561a8939)) +* compatibility with eval source maps ([#286](https://github.com/webpack-contrib/worker-loader/issues/286)) ([0d4624c](https://github.com/webpack-contrib/worker-loader/commit/0d4624c178c426aa97e5175a5f321e43de482c2b)) + ### [3.0.2](https://github.com/webpack-contrib/worker-loader/compare/v3.0.1...v3.0.2) (2020-08-22) diff --git a/README.md b/README.md index 905e37a..ddb67e6 100644 --- a/README.md +++ b/README.md @@ -66,14 +66,14 @@ And run `webpack` via your preferred method. ## Options -| Name | Type | Default | Description | -| :-----------------------------------: | :--------------------------: | :-----------------------------: | :-------------------------------------------------------------------------------- | -| **[`worker`](#worker)** | `{String\|Object}` | `Worker` | Allows to set web worker constructor name and options | -| **[`publicPath`](#publicpath)** | `{String\|Function}` | based on `output.publicPath` | specifies the public URL address of the output files when referenced in a browser | -| **[`filename`](#filename)** | `{String\|Function}` | based on `output.filename` | The filename of entry chunks for web workers | -| **[`chunkFilename`](#chunkfilename)** | `{String}` | based on `output.chunkFilename` | The filename of non-entry chunks for web workers | -| **[`inline`](#inline)** | `'no-fallback'\|'fallback'` | `undefined` | Allow to inline the worker as a `BLOB` | -| **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax | +| Name | Type | Default | Description | +| :-----------------------------------: | :-------------------------: | :-----------------------------: | :-------------------------------------------------------------------------------- | +| **[`worker`](#worker)** | `{String\|Object}` | `Worker` | Allows to set web worker constructor name and options | +| **[`publicPath`](#publicpath)** | `{String\|Function}` | based on `output.publicPath` | specifies the public URL address of the output files when referenced in a browser | +| **[`filename`](#filename)** | `{String\|Function}` | based on `output.filename` | The filename of entry chunks for web workers | +| **[`chunkFilename`](#chunkfilename)** | `{String}` | based on `output.chunkFilename` | The filename of non-entry chunks for web workers | +| **[`inline`](#inline)** | `'no-fallback'\|'fallback'` | `undefined` | Allow to inline the worker as a `BLOB` | +| **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax | ### `worker` diff --git a/package-lock.json b/package-lock.json index 3543283..002a3b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "worker-loader", - "version": "3.0.2", + "version": "3.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3747a91..50555e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "worker-loader", - "version": "3.0.2", + "version": "3.0.3", "description": "worker loader module for webpack", "license": "MIT", "repository": "webpack-contrib/worker-loader", diff --git a/src/runtime/inline.js b/src/runtime/inline.js index 0372f08..d1259c1 100644 --- a/src/runtime/inline.js +++ b/src/runtime/inline.js @@ -23,7 +23,7 @@ module.exports = (content, workerConstructor, workerOptions, url) => { blob = blob.getBlob(); } - + const URL = window.URL || window.webkitURL; const objectURL = URL.createObjectURL(blob); const worker = new window[workerConstructor](objectURL, workerOptions); diff --git a/src/supportWebpack4.js b/src/supportWebpack4.js index fec90d4..508beeb 100644 --- a/src/supportWebpack4.js +++ b/src/supportWebpack4.js @@ -1,4 +1,8 @@ -import { workerGenerator, sourceMappingURLRegex } from './utils'; +import { + workerGenerator, + sourceMappingURLRegex, + sourceURLWebpackRegex, +} from './utils'; export default function runAsChild( loaderContext, @@ -30,6 +34,9 @@ export default function runAsChild( // Remove `/* sourceMappingURL=url */` comment workerSource = workerSource.replace(sourceMappingURLRegex, ''); + + // Remove `//# sourceURL=webpack-internal` comment + workerSource = workerSource.replace(sourceURLWebpackRegex, ''); } const workerCode = workerGenerator( diff --git a/src/supportWebpack5.js b/src/supportWebpack5.js index 6c6f910..c2a6725 100644 --- a/src/supportWebpack5.js +++ b/src/supportWebpack5.js @@ -1,4 +1,8 @@ -import { workerGenerator, sourceMappingURLRegex } from './utils'; +import { + workerGenerator, + sourceMappingURLRegex, + sourceURLWebpackRegex, +} from './utils'; export default function runAsChild( loaderContext, @@ -45,6 +49,9 @@ export default function runAsChild( if (options.inline === 'no-fallback') { // Remove `/* sourceMappingURL=url */` comment workerSource = workerSource.replace(sourceMappingURLRegex, ''); + + // Remove `//# sourceURL=webpack-internal` comment + workerSource = workerSource.replace(sourceURLWebpackRegex, ''); } const workerCode = workerGenerator( diff --git a/src/utils.js b/src/utils.js index 3797bb7..7a7a034 100644 --- a/src/utils.js +++ b/src/utils.js @@ -87,7 +87,7 @@ ${ } // Matches only the last occurrence of sourceMappingURL -const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*([^\s'"]*)\s*/; +const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*(.*?(?=[\s'"]|\\n|\*\/|$)(?:\\n)?)\s*/; /* eslint-disable prefer-template */ const sourceMappingURLRegex = RegExp( @@ -106,6 +106,10 @@ const sourceMappingURLRegex = RegExp( ')' + '\\s*' ); + +const sourceURLWebpackRegex = RegExp( + '\\/\\/#\\ssourceURL=webpack-internal:\\/\\/\\/(.*?)\\\\n' +); /* eslint-enable prefer-template */ export { @@ -114,4 +118,5 @@ export { getExternalsType, workerGenerator, sourceMappingURLRegex, + sourceURLWebpackRegex, }; diff --git a/test/__snapshots__/chunkFilename-option.test.js.snap b/test/__snapshots__/chunkFilename-option.test.js.snap index 577fecc..3685e6d 100644 --- a/test/__snapshots__/chunkFilename-option.test.js.snap +++ b/test/__snapshots__/chunkFilename-option.test.js.snap @@ -1,5 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`"name" option should chunkFilename suffix be inserted before query parameters: errors 1`] = `Array []`; + +exports[`"name" option should chunkFilename suffix be inserted before query parameters: module 1`] = ` +"export default function() { + return new Worker(__webpack_public_path__ + \\"worker.worker.js\\"); +} +" +`; + +exports[`"name" option should chunkFilename suffix be inserted before query parameters: result 1`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`; + +exports[`"name" option should chunkFilename suffix be inserted before query parameters: result 2`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`; + +exports[`"name" option should chunkFilename suffix be inserted before query parameters: warnings 1`] = `Array []`; + exports[`"name" option should work ("string"): errors 1`] = `Array []`; exports[`"name" option should work ("string"): module 1`] = ` diff --git a/test/__snapshots__/inline-option.test.js.snap b/test/__snapshots__/inline-option.test.js.snap index 9af5142..8414722 100644 --- a/test/__snapshots__/inline-option.test.js.snap +++ b/test/__snapshots__/inline-option.test.js.snap @@ -55,6 +55,12 @@ exports[`"inline" option should work with "no-fallback" value and "esModule" wit exports[`"inline" option should work with "no-fallback" value and "esModule" with "true" value: warnings 1`] = `Array []`; +exports[`"inline" option should work with "no-fallback" value and the "devtool" option ("eval-source-map" value): errors 1`] = `Array []`; + +exports[`"inline" option should work with "no-fallback" value and the "devtool" option ("eval-source-map" value): result 1`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`; + +exports[`"inline" option should work with "no-fallback" value and the "devtool" option ("eval-source-map" value): warnings 1`] = `Array []`; + exports[`"inline" option should work with "no-fallback" value and the "devtool" option ("source-map" value): errors 1`] = `Array []`; exports[`"inline" option should work with "no-fallback" value and the "devtool" option ("source-map" value): errors 2`] = `Array []`; diff --git a/test/__snapshots__/sourceMapperRegexp.test.js.snap b/test/__snapshots__/sourceMapperRegexp.test.js.snap new file mode 100644 index 0000000..2d301e2 --- /dev/null +++ b/test/__snapshots__/sourceMapperRegexp.test.js.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`source-map-loader should work with " + with SourceMap + + // #sourceMappingURL = /sample-source-map.map + // comment + " url: result 1`] = ` +" + with SourceMap + + REPLASED// comment + " +`; + +exports[`source-map-loader should work with " // # sourceMappingURL = absolute-sourceRoot-source-map.map " url: result 1`] = `" REPLASED"`; + +exports[`source-map-loader should work with " // #sourceMappingURL=absolute-sourceRoot-source-map.map" url: result 1`] = `" REPLASED"`; + +exports[`source-map-loader should work with "/* #sourceMappingURL=absolute-sourceRoot-source-map.map */" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "/*#sourceMappingURL=absolute-sourceRoot-source-map.map*/" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "// #sourceMappingURL = //sampledomain.com/external-source-map2.map" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "// #sourceMappingURL = http://sampledomain.com/external-source-map2.map" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "// @sourceMappingURL=data:application/source-map;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzIjpbImlubGluZS1zb3VyY2UtbWFwLnR4dCJdLCJzb3VyY2VzQ29udGVudCI6WyJ3aXRoIFNvdXJjZU1hcCJdLCJtYXBwaW5ncyI6IkFBQUEifQ==" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "//#sourceMappingURL=absolute-sourceRoot-source-map.map" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "//@sourceMappingURL=absolute-sourceRoot-source-map.map" url: result 1`] = `"REPLASED"`; + +exports[`source-map-loader should work with "onmessage = function(event) { + const workerResult = event.data; + + workerResult.onmessage = true; + + postMessage(workerResult); +}; +//# sourceURL=[module] +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9iYXNpYy93b3JrZXIuanM/OGFiZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EiLCJmaWxlIjoiLi9iYXNpYy93b3JrZXIuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJvbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICBjb25zdCB3b3JrZXJSZXN1bHQgPSBldmVudC5kYXRhO1xuXG4gIHdvcmtlclJlc3VsdC5vbm1lc3NhZ2UgPSB0cnVlO1xuXG4gIHBvc3RNZXNzYWdlKHdvcmtlclJlc3VsdCk7XG59O1xuIl0sInNvdXJjZVJvb3QiOiIifQ== +//# sourceURL=webpack-internal:///./basic/worker.js +" url: result 1`] = ` +"onmessage = function(event) { + const workerResult = event.data; + + workerResult.onmessage = true; + + postMessage(workerResult); +}; +//# sourceURL=[module] +REPLASED//# sourceURL=webpack-internal:///./basic/worker.js +" +`; diff --git a/test/chunkFilename-option.test.js b/test/chunkFilename-option.test.js index e535ef1..6dcd708 100644 --- a/test/chunkFilename-option.test.js +++ b/test/chunkFilename-option.test.js @@ -36,6 +36,7 @@ describe('"name" option', () => { output: { path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), filename: '[name].js', + publicPath: '', }, module: { rules: [ @@ -72,6 +73,7 @@ describe('"name" option', () => { path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), filename: '[name].js', chunkFilename: '[name].chunk.js', + publicPath: '', }, module: { rules: [ @@ -97,4 +99,51 @@ describe('"name" option', () => { expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); + + it('should chunkFilename suffix be inserted before query parameters', async () => { + const nanoid = customAlphabet('1234567890abcdef', 10); + const compiler = getCompiler( + './chunks/entry.js', + {}, + { + output: { + path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), + filename: '[name].js', + chunkFilename: '[name].chunk.js?foo=bar&baz=bar', + publicPath: '', + }, + module: { + rules: [ + { + test: /worker\.js$/i, + rules: [ + { + loader: path.resolve(__dirname, '../src'), + }, + ], + }, + ], + }, + } + ); + const stats = await compile(compiler); + const result = await getResultFromBrowser(stats); + + let hasChankName = false; + + Object.keys(stats.compilation.assets).forEach((asset) => { + if (asset.endsWith('chunk.worker.js?foo=bar&baz=bar')) { + hasChankName = true; + } + }); + + expect(hasChankName).toBe(true); + expect(result).toMatchSnapshot('result'); + expect(getModuleSource('./chunks/worker.js', stats)).toMatchSnapshot( + 'module' + ); + expect(result).toMatchSnapshot('result'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); }); diff --git a/test/filename-options.test.js b/test/filename-options.test.js index d0ab25d..a44cf0c 100644 --- a/test/filename-options.test.js +++ b/test/filename-options.test.js @@ -51,6 +51,7 @@ describe('"filename" option', () => { output: { path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), chunkFilename: '[name].chunk.js', + publicPath: '', }, module: { rules: [ @@ -87,6 +88,7 @@ describe('"filename" option', () => { path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), filename: '[name].custom.js', chunkFilename: '[name].chunk.js', + publicPath: '', }, module: { rules: [ @@ -128,6 +130,7 @@ describe('"filename" option', () => { return '[name].js'; }, + publicPath: '', }, module: { rules: [ diff --git a/test/helpers/getCompiler.js b/test/helpers/getCompiler.js index 8810b19..894748a 100644 --- a/test/helpers/getCompiler.js +++ b/test/helpers/getCompiler.js @@ -16,6 +16,7 @@ export default (fixture, loaderOptions = {}, config = {}) => { path: path.resolve(__dirname, '../outputs', `test_${nanoid()}`), filename: '[name].bundle.js', chunkFilename: '[name].chunk.js', + publicPath: '', }, module: { rules: [ diff --git a/test/helpers/getResultFromBrowser.js b/test/helpers/getResultFromBrowser.js index 7fbee2c..64771b1 100644 --- a/test/helpers/getResultFromBrowser.js +++ b/test/helpers/getResultFromBrowser.js @@ -20,7 +20,9 @@ export default async function getResultFromBrowser(stats) { ); for (const asset of assets) { - const [route] = asset; + let [route] = asset; + [route] = route.split('?'); + const existsAt = path.resolve(stats.compilation.outputOptions.path, route); if (route === 'index.html') { diff --git a/test/inline-option.test.js b/test/inline-option.test.js index 763303a..1c5a0f0 100644 --- a/test/inline-option.test.js +++ b/test/inline-option.test.js @@ -62,6 +62,36 @@ describe('"inline" option', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); }); + it('should work with "no-fallback" value and the "devtool" option ("eval-source-map" value)', async () => { + const compiler = getCompiler( + './basic/entry.js', + { inline: 'no-fallback' }, + { devtool: 'eval-source-map' } + ); + const stats = await compile(compiler); + const result = await getResultFromBrowser(stats); + const moduleSource = getModuleSource('./basic/worker.js', stats); + const sourceUrlInternalIndex = moduleSource.indexOf( + 'sourceURL=webpack-internal:///./basic/worker.js' + ); + + expect(moduleSource.indexOf('inline.js') > 0).toBe(true); + expect( + moduleSource.indexOf('__webpack_public_path__ + "test.worker.js"') === -1 + ).toBe(true); + expect( + moduleSource.indexOf( + 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + ) === -1 + ).toBe(true); + expect(sourceUrlInternalIndex === -1).toBe(true); + expect(stats.compilation.assets['test.worker.js']).toBeUndefined(); + expect(stats.compilation.assets['test.worker.js.map']).toBeUndefined(); + expect(result).toMatchSnapshot('result'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); + it('should work with "no-fallback" value and the "devtool" option ("source-map" value)', async () => { const compiler = getCompiler( './basic/entry.js', diff --git a/test/publicPath.test.js b/test/publicPath.test.js index b8e78a3..a487957 100644 --- a/test/publicPath.test.js +++ b/test/publicPath.test.js @@ -67,6 +67,7 @@ describe('"publicPath" option', () => { path: path.resolve(__dirname, './outputs', `test_${nanoid()}`), filename: '[name].bundle.js', chunkFilename: '[name].chunk.js', + publicPath: '', }, } ); diff --git a/test/sourceMapperRegexp.test.js b/test/sourceMapperRegexp.test.js new file mode 100644 index 0000000..ed3188a --- /dev/null +++ b/test/sourceMapperRegexp.test.js @@ -0,0 +1,31 @@ +import { sourceMappingURLRegex } from '../src/utils'; + +describe('source-map-loader', () => { + const cases = [ + '/*#sourceMappingURL=absolute-sourceRoot-source-map.map*/', + '/* #sourceMappingURL=absolute-sourceRoot-source-map.map */', + '//#sourceMappingURL=absolute-sourceRoot-source-map.map', + '//@sourceMappingURL=absolute-sourceRoot-source-map.map', + ' // #sourceMappingURL=absolute-sourceRoot-source-map.map', + ' // # sourceMappingURL = absolute-sourceRoot-source-map.map ', + '// #sourceMappingURL = http://sampledomain.com/external-source-map2.map', + '// #sourceMappingURL = //sampledomain.com/external-source-map2.map', + '// @sourceMappingURL=data:application/source-map;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzIjpbImlubGluZS1zb3VyY2UtbWFwLnR4dCJdLCJzb3VyY2VzQ29udGVudCI6WyJ3aXRoIFNvdXJjZU1hcCJdLCJtYXBwaW5ncyI6IkFBQUEifQ==', + ` + with SourceMap + + // #sourceMappingURL = /sample-source-map.map + // comment + `, + 'onmessage = function(event) {\n const workerResult = event.data;\n\n workerResult.onmessage = true;\n\n postMessage(workerResult);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9iYXNpYy93b3JrZXIuanM/OGFiZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EiLCJmaWxlIjoiLi9iYXNpYy93b3JrZXIuanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJvbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICBjb25zdCB3b3JrZXJSZXN1bHQgPSBldmVudC5kYXRhO1xuXG4gIHdvcmtlclJlc3VsdC5vbm1lc3NhZ2UgPSB0cnVlO1xuXG4gIHBvc3RNZXNzYWdlKHdvcmtlclJlc3VsdCk7XG59O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./basic/worker.js\n', + ]; + + cases.forEach((item) => { + it(`should work with "${item}" url`, async () => { + const result = item.replace(sourceMappingURLRegex, 'REPLASED'); + + expect(result.indexOf('REPLASED') !== -1).toBe(true); + expect(result).toMatchSnapshot('result'); + }); + }); +});
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: