New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

worker-plugin

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

worker-plugin - npm Package Compare versions

Comparing version 3.2.0 to 4.0.0

5

dist/loader.js

@@ -30,3 +30,4 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var compilerOptions = this._compiler.options || {};
var pluginOptions = compilerOptions.plugins.find(function (p) { return p[WORKER_PLUGIN_SYMBOL]; }).options;
var plugin = compilerOptions.plugins.find(function (p) { return p[WORKER_PLUGIN_SYMBOL]; }) || {};
var pluginOptions = plugin && plugin.options || {};

@@ -82,3 +83,3 @@ if (pluginOptions.globalObject == null && !hasWarned && compilerOptions.output && compilerOptions.output.globalObject === 'window') {

if (err) { return cb(err); }
return cb(null, ("module.exports = __webpack_public_path__ + " + (JSON.stringify(entry))));
return cb(null, ((options.esModule ? 'export default' : 'module.exports =') + " __webpack_public_path__ + " + (JSON.stringify(entry))));
});

@@ -85,0 +86,0 @@ }

131

dist/worker-plugin.js
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var path = _interopDefault(require('path'));
var WORKER_PLUGIN_SYMBOL = _interopDefault(require('./symbol.js'));
var ParserHelpers = _interopDefault(require('webpack/lib/ParserHelpers'));
var WORKER_PLUGIN_SYMBOL = _interopDefault(require('./symbol.js'));

@@ -22,4 +22,9 @@ /**

*/
var HarmonyImportSpecifierDependency;
try {
HarmonyImportSpecifierDependency = require('webpack/lib/dependencies/HarmonyImportSpecifierDependency');
} catch (e) {}
var NAME = 'WorkerPlugin';
var JS_TYPES = ['auto', 'esm', 'dynamic'];
var workerLoader = path.resolve(__dirname, 'loader.js');

@@ -36,61 +41,97 @@ var WorkerPlugin = function WorkerPlugin(options) {

var workerId = 0;
factory.hooks.parser.for('javascript/auto').tap(NAME, function (parser) { return parse(parser, false); });
factory.hooks.parser.for('javascript/dynamic').tap(NAME, function (parser) { return parse(parser, false); });
factory.hooks.parser.for('javascript/esm').tap(NAME, function (parser) { return parse(parser, true); });
for (var i = 0, list = JS_TYPES; i < list.length; i += 1) {
var type = list[i];
var parse = function (parser, esModule) {
var handleWorker = function (workerTypeString) { return function (expr) {
var dep = parser.evaluateExpression(expr.arguments[0]);
factory.hooks.parser.for(("javascript/" + type)).tap(NAME, function (parser) {
parser.hooks.new.for('Worker').tap(NAME, function (expr) {
var dep = parser.evaluateExpression(expr.arguments[0]);
if (!dep.isString()) {
parser.state.module.warnings.push({
message: ("new " + workerTypeString + "() will only be bundled if passed a String.")
});
return false;
}
if (!dep.isString()) {
parser.state.module.warnings.push({
message: 'new Worker() will only be bundled if passed a String.'
});
return false;
}
var optsExpr = expr.arguments[1];
var hasInitOptions = false;
var typeModuleExpr;
var opts;
var optsExpr = expr.arguments[1];
var typeModuleExpr;
var opts;
if (optsExpr) {
opts = {};
if (optsExpr) {
opts = {};
for (var i = optsExpr.properties.length; i--;) {
var prop = optsExpr.properties[i];
for (var i = optsExpr.properties.length; i--;) {
var prop = optsExpr.properties[i];
if (prop.type === 'Property' && !prop.computed && !prop.shorthand && !prop.method) {
opts[prop.key.name] = parser.evaluateExpression(prop.value).string;
if (prop.type === 'Property' && !prop.computed && !prop.shorthand && !prop.method) {
opts[prop.key.name] = parser.evaluateExpression(prop.value).string;
if (prop.key.name === 'type') {
typeModuleExpr = prop;
}
if (prop.key.name === 'type') {
typeModuleExpr = prop;
} else {
hasInitOptions = true;
}
}
}
}
if (!opts || opts.type !== 'module') {
parser.state.module.warnings.push({
message: ("new Worker() will only be bundled if passed options that include { type: 'module' }." + (opts ? ("\n Received: new Worker(" + (JSON.stringify(dep.string)) + ", " + (JSON.stringify(opts)) + ")") : ''))
});
return false;
}
if (!opts || opts.type !== 'module') {
parser.state.module.warnings.push({
message: ("new " + workerTypeString + "() will only be bundled if passed options that include { type: 'module' }." + (opts ? ("\n Received: new " + workerTypeString + "()(" + (JSON.stringify(dep.string)) + ", " + (JSON.stringify(opts)) + ")") : ''))
});
return false;
}
var loaderOptions = {
name: opts.name || workerId + ''
};
var req = "require(" + (JSON.stringify(workerLoader + '?' + JSON.stringify(loaderOptions) + '!' + dep.string)) + ")";
var id = "__webpack__worker__" + (workerId++);
var isStrictModule = esModule || parser.state.buildMeta && parser.state.buildMeta.strictHarmonyModule; // Querystring-encoded loader prefix (faster/cleaner than JSON parameters):
var loaderRequest = workerLoader + "?name=" + (encodeURIComponent(opts.name || workerId)) + (isStrictModule ? '&esModule' : '') + "!" + (dep.string); // Unique ID for the worker URL variable:
var id = "__webpack__worker__" + (workerId++); // .mjs / strict harmony mode
if (isStrictModule) {
var module = parser.state.current;
if (!HarmonyImportSpecifierDependency) {
throw Error((NAME + ": Failed to import HarmonyImportSpecifierDependency. This plugin requires Webpack version 4."));
} // This is essentially the internals of "prepend an import to the module":
var dependency = new HarmonyImportSpecifierDependency(loaderRequest, module, workerId, // no idea if this actually needs to be unique. 0 seemed to work. safety first?
parser.scope, 'default', id, // this never gets used
expr.arguments[0].range, // replace the usage/callsite with the generated reference: X_IMPORT_0["default"]
true); // avoid serializing the full loader filepath: (this gets prepended to unique suffix)
dependency.userRequest = dep.string;
module.addDependency(dependency);
} else {
// For CommonJS/Auto
var req = "require(" + (JSON.stringify(loaderRequest)) + ")";
ParserHelpers.toConstantDependency(parser, id)(expr.arguments[0]);
ParserHelpers.addParsedVariableToModule(parser, id, req);
} // update/remove the WorkerInitOptions argument
if (this$1.options.workerType) {
ParserHelpers.toConstantDependency(parser, JSON.stringify(this$1.options.workerType))(typeModuleExpr.value);
} else if (this$1.options.preserveTypeModule !== true) {
ParserHelpers.toConstantDependency(parser, '')(typeModuleExpr);
if (this$1.options.workerType) {
ParserHelpers.toConstantDependency(parser, JSON.stringify(this$1.options.workerType))(typeModuleExpr.value);
} else if (this$1.options.preserveTypeModule !== true) {
if (hasInitOptions) {
// there might be other options - to avoid trailing comma issues, replace the type value with undefined but *leave the key*:
ParserHelpers.toConstantDependency(parser, 'type:undefined')(typeModuleExpr);
} else {
// there was only a `{type}` option, so we can remove the whole second argument:
ParserHelpers.toConstantDependency(parser, '')(optsExpr);
}
}
return ParserHelpers.addParsedVariableToModule(parser, id, req);
});
});
}
return true;
}; };
parser.hooks.new.for('Worker').tap(NAME, handleWorker('Worker'));
if (this$1.options.sharedWorker) {
parser.hooks.new.for('SharedWorker').tap(NAME, handleWorker('SharedWorker'));
}
};
});

@@ -97,0 +138,0 @@ };

{
"name": "worker-plugin",
"version": "3.2.0",
"version": "4.0.0",
"description": "Webpack plugin to bundle Workers automagically.",

@@ -8,3 +8,3 @@ "main": "dist/worker-plugin.js",

"scripts": {
"build": "microbundle --inline none --format cjs --no-compress src/*.js",
"build": "microbundle --raw --inline none --format cjs --no-compress src/*.js",
"prepack": "npm run build",

@@ -11,0 +11,0 @@ "dev": "jest --verbose --watchAll",

@@ -18,5 +18,5 @@ <p align="center">

The best part? That worker constructor works just fine without bundling turned on too.
The best part? That worker constructor works just fine without bundling turned on, but when bundled the result is **supported in all browsers** that support Web Workers - all the way back to IE 10!
Workers created from Blob & data URLs or without the `{ type:'module' }` option are left unchanged.
Workers with fully dynamic URLs, Blob URLs, data URLs or with no `{ type:'module' }` option are left unchanged.

@@ -66,2 +66,4 @@ ## Installation

> **Note:** in order to ensure WorkerPlugin bundles your worker, make sure you're passing a **string** URL/filename to the Worker constructor. WorkerPlugin cannot bundle workers with dynamic/variable filenames, Blob or data URLs - it will leave them unmodified and print a warning during your build.
## Options

@@ -71,5 +73,5 @@

### `globalObject`
### `globalObject` _(string | false)_
WorkerPlugin will warn you if your Webpack configuration has `output.globalObject` set to `window`, since doing so breaks Hot Module Replacement in web workers.
WorkerPlugin will print a warning if your Webpack configuration has `output.globalObject` set to `window`, since doing so breaks Hot Module Replacement in web workers.

@@ -94,5 +96,5 @@ If you're not using HMR and want to disable this warning, pass `globalObject:false`:

### `plugins`
### `plugins` _(array)_
By default, `WorkerPlugin` doesn't run any of your configured Webpack plugins when bundling worker code - this avoids running things like `html-webpack-plugin` twice. For cases where it's necessary to apply a plugin to Worker code, use the `plugins` option.
By default, WorkerPlugin doesn't run any of your configured Webpack plugins when bundling worker code - this avoids running things like `html-webpack-plugin` twice. For cases where it's necessary to apply a plugin to Worker code, use the `plugins` option.

@@ -122,4 +124,79 @@ Here you can specify the names of plugins to "copy" from your existing Webpack configuration, or provide specific plugins to apply only to worker code:

### `sharedWorker` _(boolean)_
If set to `true`, this option enables the bundling of [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker):
```js
const shared = new SharedWorker('./my-shared-worker.js', { type: 'module' });
```
### `preserveTypeModule` _(boolean)_
### `workerType` _(string)_
Normally, WorkerPlugin will transform `new Worker('./a.js', { type: 'module' })` to completely remove the `type` option, outputting something like `new Worker('a.worker.js')`. This allows the plugin to compile Module Workers to Classic Workers, which are supported in all browsers.
To instead retain `{type:'module'}` in bundled output, set the `preserveTypeModule` option to `true`:
```js
plugins: [
new WorkerPlugin({
preserveTypeModule: true
})
]
```
Similarly, if you need to have WorkerPlugin output a specific `type` value, use the `workerType` option to spefify it:
```js
plugins: [
new WorkerPlugin({
workerType: 'foo' // note: this isn't a thing!
})
]
```
## Loader
At its core, worker-plugin provides two features: parsing and handling of `new Worker()`, and standalone bundling of modules for use in a different JavaScript context.
If all you want is to compile separate bundles for a module, `worker-plugin/loader` provides the bundling functionality of worker-plugin as a standalone Webpack loader. This is useful for generating bundles for use in iframes, Service Workers or Worklets. Applying `worker-plugin/loader` to an import will bundle that module and return its URL:
```js
import workerUrl from 'worker-plugin/loader!./my-worker';
console.log(workerUrl); // "/0.worker.js"
CSS.paintWorklet.addModule(workerUrl);
```
Two options are available:
| Option | Type | Description
|---|---|:--|
| `name` | _string_ | Controls the name of the generated chunk.<br>The name is used to generate a URL according to `output.chunkFilename`.
| `esModule` | _boolean_ | Export the URL from an ES Module (`export default url`).<br>The default is CommonJS (`module.exports = url`).
Options can be supplied inline:
```js
import url from 'worker-plugin/loader?name=foo&esModule!./foo';
```
... or by setting up a loader alias:
```js
// webpack.config.js to enable this:
// import url from 'worker!./foo';
{
resolveLoader: {
alias: {
worker: 'worker-plugin/loader?esModule'
}
}
}
```
## License
Apache-2.0

@@ -18,7 +18,10 @@ /**

import path from 'path';
import WORKER_PLUGIN_SYMBOL from './symbol';
import ParserHelpers from 'webpack/lib/ParserHelpers';
import WORKER_PLUGIN_SYMBOL from './symbol';
let HarmonyImportSpecifierDependency;
try {
HarmonyImportSpecifierDependency = require('webpack/lib/dependencies/HarmonyImportSpecifierDependency');
} catch (e) {}
const NAME = 'WorkerPlugin';
const JS_TYPES = ['auto', 'esm', 'dynamic'];
const workerLoader = path.resolve(__dirname, 'loader.js');

@@ -35,55 +38,105 @@

let workerId = 0;
for (const type of JS_TYPES) {
factory.hooks.parser.for(`javascript/${type}`).tap(NAME, parser => {
parser.hooks.new.for('Worker').tap(NAME, expr => {
const dep = parser.evaluateExpression(expr.arguments[0]);
factory.hooks.parser.for('javascript/auto').tap(NAME, parser => parse(parser, false));
factory.hooks.parser.for('javascript/dynamic').tap(NAME, parser => parse(parser, false));
factory.hooks.parser.for('javascript/esm').tap(NAME, parser => parse(parser, true));
if (!dep.isString()) {
parser.state.module.warnings.push({
message: 'new Worker() will only be bundled if passed a String.'
});
return false;
}
const parse = (parser, esModule) => {
const handleWorker = workerTypeString => expr => {
const dep = parser.evaluateExpression(expr.arguments[0]);
const optsExpr = expr.arguments[1];
let typeModuleExpr;
let opts;
if (optsExpr) {
opts = {};
for (let i = optsExpr.properties.length; i--;) {
const prop = optsExpr.properties[i];
if (prop.type === 'Property' && !prop.computed && !prop.shorthand && !prop.method) {
opts[prop.key.name] = parser.evaluateExpression(prop.value).string;
if (!dep.isString()) {
parser.state.module.warnings.push({
message: `new ${workerTypeString}() will only be bundled if passed a String.`
});
return false;
}
if (prop.key.name === 'type') {
typeModuleExpr = prop;
}
const optsExpr = expr.arguments[1];
let hasInitOptions = false;
let typeModuleExpr;
let opts;
if (optsExpr) {
opts = {};
for (let i = optsExpr.properties.length; i--;) {
const prop = optsExpr.properties[i];
if (prop.type === 'Property' && !prop.computed && !prop.shorthand && !prop.method) {
opts[prop.key.name] = parser.evaluateExpression(prop.value).string;
if (prop.key.name === 'type') {
typeModuleExpr = prop;
} else {
hasInitOptions = true;
}
}
}
}
if (!opts || opts.type !== 'module') {
parser.state.module.warnings.push({
message: `new Worker() will only be bundled if passed options that include { type: 'module' }.${opts ? `\n Received: new Worker(${JSON.stringify(dep.string)}, ${JSON.stringify(opts)})` : ''}`
});
return false;
if (!opts || opts.type !== 'module') {
parser.state.module.warnings.push({
message: `new ${workerTypeString}() will only be bundled if passed options that include { type: 'module' }.${opts ? `\n Received: new ${workerTypeString}()(${JSON.stringify(dep.string)}, ${JSON.stringify(opts)})` : ''}`
});
return false;
}
const isStrictModule = esModule || (parser.state.buildMeta && parser.state.buildMeta.strictHarmonyModule);
// Querystring-encoded loader prefix (faster/cleaner than JSON parameters):
const loaderRequest = `${workerLoader}?name=${encodeURIComponent(opts.name || workerId)}${isStrictModule ? '&esModule' : ''}!${dep.string}`;
// Unique ID for the worker URL variable:
const id = `__webpack__worker__${workerId++}`;
// .mjs / strict harmony mode
if (isStrictModule) {
const module = parser.state.current;
if (!HarmonyImportSpecifierDependency) {
throw Error(`${NAME}: Failed to import HarmonyImportSpecifierDependency. This plugin requires Webpack version 4.`);
}
const loaderOptions = { name: opts.name || workerId + '' };
const req = `require(${JSON.stringify(workerLoader + '?' + JSON.stringify(loaderOptions) + '!' + dep.string)})`;
const id = `__webpack__worker__${workerId++}`;
// This is essentially the internals of "prepend an import to the module":
const dependency = new HarmonyImportSpecifierDependency(
loaderRequest,
module,
workerId, // no idea if this actually needs to be unique. 0 seemed to work. safety first?
parser.scope,
'default',
id, // this never gets used
expr.arguments[0].range, // replace the usage/callsite with the generated reference: X_IMPORT_0["default"]
true
);
// avoid serializing the full loader filepath: (this gets prepended to unique suffix)
dependency.userRequest = dep.string;
module.addDependency(dependency);
} else {
// For CommonJS/Auto
const req = `require(${JSON.stringify(loaderRequest)})`;
ParserHelpers.toConstantDependency(parser, id)(expr.arguments[0]);
ParserHelpers.addParsedVariableToModule(parser, id, req);
}
if (this.options.workerType) {
ParserHelpers.toConstantDependency(parser, JSON.stringify(this.options.workerType))(typeModuleExpr.value);
} else if (this.options.preserveTypeModule !== true) {
ParserHelpers.toConstantDependency(parser, '')(typeModuleExpr);
// update/remove the WorkerInitOptions argument
if (this.options.workerType) {
ParserHelpers.toConstantDependency(parser, JSON.stringify(this.options.workerType))(typeModuleExpr.value);
} else if (this.options.preserveTypeModule !== true) {
if (hasInitOptions) {
// there might be other options - to avoid trailing comma issues, replace the type value with undefined but *leave the key*:
ParserHelpers.toConstantDependency(parser, 'type:undefined')(typeModuleExpr);
} else {
// there was only a `{type}` option, so we can remove the whole second argument:
ParserHelpers.toConstantDependency(parser, '')(optsExpr);
}
}
return ParserHelpers.addParsedVariableToModule(parser, id, req);
});
});
}
return true;
};
parser.hooks.new.for('Worker').tap(NAME, handleWorker('Worker'));
if (this.options.sharedWorker) {
parser.hooks.new.for('SharedWorker').tap(NAME, handleWorker('SharedWorker'));
}
};
});
}
}

@@ -32,3 +32,4 @@ /**

const pluginOptions = compilerOptions.plugins.find(p => p[WORKER_PLUGIN_SYMBOL]).options;
const plugin = compilerOptions.plugins.find(p => p[WORKER_PLUGIN_SYMBOL]) || {};
const pluginOptions = plugin && plugin.options || {};

@@ -82,3 +83,3 @@ if (pluginOptions.globalObject == null && !hasWarned && compilerOptions.output && compilerOptions.output.globalObject === 'window') {

if (err) return cb(err);
return cb(null, `module.exports = __webpack_public_path__ + ${JSON.stringify(entry)}`);
return cb(null, `${options.esModule ? 'export default' : 'module.exports ='} __webpack_public_path__ + ${JSON.stringify(entry)}`);
});

@@ -85,0 +86,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc