worker_threads: add support for data: URLs by aduh95 · Pull Request #34584 · nodejs/node · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion doc/api/worker_threads.md
3 changes: 3 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1465,6 +1465,9 @@ E('ERR_WORKER_PATH', (filename) =>
(filename.startsWith('file://') ?
' Wrap file:// URLs with `new URL`.' : ''
) +
(filename.startsWith('data:text/javascript') ?
' Wrap data: URLs with `new URL`.' : ''
) +
` Received "${filename}"`,
TypeError);
E('ERR_WORKER_UNSERIALIZABLE_ERROR',
Expand Down
7 changes: 6 additions & 1 deletion lib/internal/main/worker_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ port.on('message', (message) => {
debug(`[${threadId}] starts worker script ${filename} ` +
`(eval = ${eval}) at cwd = ${process.cwd()}`);
port.postMessage({ type: UP_AND_RUNNING });
if (doEval) {
if (doEval === 'classic') {
const { evalScript } = require('internal/process/execution');
const name = '[worker eval]';
// This is necessary for CJS module compilation.
Expand All @@ -161,6 +161,11 @@ port.on('message', (message) => {
});
process.argv.splice(1, 0, name);
evalScript(name, filename);
} else if (doEval === 'module') {
const { evalModule } = require('internal/process/execution');
evalModule(filename).catch((e) => {
workerOnGlobalUncaughtException(e, true);
});
Comment thread
aduh95 marked this conversation as resolved.
} else {
// script filename
// runMain here might be monkey-patched by users in --require.
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/process/execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function evalModule(source, print) {
const { log } = require('internal/console/global');
const { loadESM } = require('internal/process/esm_loader');
const { handleMainPromise } = require('internal/modules/run_main');
handleMainPromise(loadESM(async (loader) => {
return handleMainPromise(loadESM(async (loader) => {
const { result } = await loader.eval(source);
if (print) {
log(result);
Expand Down
11 changes: 9 additions & 2 deletions lib/internal/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const {
ArrayIsArray,
JSONStringify,
MathMax,
ObjectCreate,
ObjectEntries,
Expand Down Expand Up @@ -100,7 +101,7 @@ class Worker extends EventEmitter {
argv = options.argv.map(String);
}

let url;
let url, doEval;
if (options.eval) {
if (typeof filename !== 'string') {
throw new ERR_INVALID_ARG_VALUE(
Expand All @@ -110,7 +111,13 @@ class Worker extends EventEmitter {
);
}
url = null;
doEval = 'classic';
} else if (isURLInstance(filename) && filename.protocol === 'data:') {
url = null;
doEval = 'module';
filename = `import ${JSONStringify(`${filename}`)}`;
} else {
doEval = false;
if (isURLInstance(filename)) {
url = filename;
filename = fileURLToPath(filename);
Expand Down Expand Up @@ -201,7 +208,7 @@ class Worker extends EventEmitter {
argv,
type: messageTypes.LOAD_SCRIPT,
filename,
doEval: !!options.eval,
doEval,
cwdCounter: cwdCounter || workerIo.sharedCwdCounter,
workerData: options.workerData,
publicPort: port2,
Expand Down
25 changes: 25 additions & 0 deletions test/parallel/test-worker-data-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

const common = require('../common');
const { Worker } = require('worker_threads');
const assert = require('assert');

new Worker(new URL('data:text/javascript,'))
.on('error', common.mustNotCall(() => {}));
new Worker(new URL('data:text/javascript,export{}'))
.on('error', common.mustNotCall(() => {}));

new Worker(new URL('data:text/plain,'))
.on('error', common.mustCall(() => {}));
new Worker(new URL('data:text/javascript,module.exports={}'))
.on('error', common.mustCall(() => {}));

new Worker(new URL('data:text/javascript,await Promise.resolve()'))
.on('error', common.mustNotCall(() => {}));
new Worker(new URL('data:text/javascript,await Promise.reject()'))
.on('error', common.mustCall(() => {}));
new Worker(new URL('data:text/javascript,await new Promise(()=>{})'))
.on(
'exit',
common.mustCall((exitCode) => { assert.strictEqual(exitCode, 13); })
);
6 changes: 4 additions & 2 deletions test/parallel/test-worker-unsupported-path.js