From 8b20cc212b394f6f2186a0e73dbdd10faee0019c Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Fri, 3 Jan 2025 10:49:21 +0100 Subject: [PATCH] worker: add eval ts input PR-URL: https://github.com/nodejs/node/pull/56394 Reviewed-By: James M Snell Reviewed-By: Paolo Insogna Reviewed-By: Pietro Marchini --- lib/internal/main/worker_thread.js | 27 +++++++- test/parallel/test-worker-eval-typescript.js | 67 ++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-worker-eval-typescript.js diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index f8c410b5b25cb0..caf64728b754cc 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -49,7 +49,10 @@ const { setupMainThreadPort } = require('internal/worker/messaging'); const { onGlobalUncaughtException, evalScript, + evalTypeScript, evalModuleEntryPoint, + parseAndEvalCommonjsTypeScript, + parseAndEvalModuleTypeScript, } = require('internal/process/execution'); let debug = require('internal/util/debuglog').debuglog('worker', (fn) => { @@ -166,7 +169,29 @@ port.on('message', (message) => { value: filename, }); ArrayPrototypeSplice(process.argv, 1, 0, name); - evalScript(name, filename); + const tsEnabled = getOptionValue('--experimental-strip-types'); + const inputType = getOptionValue('--input-type'); + + if (inputType === 'module-typescript' && tsEnabled) { + // This is a special case where we want to parse and eval the + // TypeScript code as a module + parseAndEvalModuleTypeScript(filename, false); + break; + } + + let evalFunction; + if (inputType === 'commonjs') { + evalFunction = evalScript; + } else if (inputType === 'commonjs-typescript' && tsEnabled) { + evalFunction = parseAndEvalCommonjsTypeScript; + } else if (tsEnabled) { + evalFunction = evalTypeScript; + } else { + // Default to commonjs. + evalFunction = evalScript; + } + + evalFunction(name, filename); break; } diff --git a/test/parallel/test-worker-eval-typescript.js b/test/parallel/test-worker-eval-typescript.js new file mode 100644 index 00000000000000..6998bc031a3cba --- /dev/null +++ b/test/parallel/test-worker-eval-typescript.js @@ -0,0 +1,67 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const { Worker } = require('worker_threads'); +const { test } = require('node:test'); +const { once } = require('events'); + +const esmHelloWorld = ` + import worker from 'worker_threads'; + const foo: string = 'Hello, World!'; + worker.parentPort.postMessage(foo); +`; + +const cjsHelloWorld = ` + const { parentPort } = require('worker_threads'); + const foo: string = 'Hello, World!'; + parentPort.postMessage(foo); +`; + +const disableTypeScriptWarningFlag = '--disable-warning=ExperimentalWarning'; + +test('Worker eval module typescript without input-type', async () => { + const w = new Worker(esmHelloWorld, { eval: true, execArgv: [disableTypeScriptWarningFlag] }); + assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']); +}); + +test('Worker eval module typescript with --input-type=module-typescript', async () => { + const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=module-typescript', + disableTypeScriptWarningFlag] }); + assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']); +}); + +test('Worker eval module typescript with --input-type=commonjs-typescript', async () => { + const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=commonjs-typescript', + disableTypeScriptWarningFlag] }); + + const [err] = await once(w, 'error'); + assert.strictEqual(err.name, 'SyntaxError'); + assert.match(err.message, /Cannot use import statement outside a module/); +}); + +test('Worker eval module typescript with --input-type=module', async () => { + const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=module', + disableTypeScriptWarningFlag] }); + const [err] = await once(w, 'error'); + assert.strictEqual(err.name, 'SyntaxError'); + assert.match(err.message, /Missing initializer in const declaration/); +}); + +test('Worker eval commonjs typescript without input-type', async () => { + const w = new Worker(cjsHelloWorld, { eval: true, execArgv: [disableTypeScriptWarningFlag] }); + assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']); +}); + +test('Worker eval commonjs typescript with --input-type=commonjs-typescript', async () => { + const w = new Worker(cjsHelloWorld, { eval: true, execArgv: ['--input-type=commonjs-typescript', + disableTypeScriptWarningFlag] }); + assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']); +}); + +test('Worker eval commonjs typescript with --input-type=module-typescript', async () => { + const w = new Worker(cjsHelloWorld, { eval: true, execArgv: ['--input-type=module-typescript', + disableTypeScriptWarningFlag] }); + const [err] = await once(w, 'error'); + assert.strictEqual(err.name, 'ReferenceError'); + assert.match(err.message, /require is not defined in ES module scope, you can use import instead/); +});