diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index a42e1a742a5f56..0a15d5b87d4f95 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -164,7 +164,8 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE const { tsParse } = require('internal/modules/helpers'); const parsedSource = tsParse(source); const detectedFormat = detectModuleFormat(parsedSource, url); - const format = detectedFormat ? `${detectedFormat}-typescript` : 'commonjs-typescript'; + // When source is undefined, default to module-typescript. + const format = detectedFormat ? `${detectedFormat}-typescript` : 'module-typescript'; if (format === 'module-typescript' && foundPackageJson) { // This module has a .js extension, a package.json with no `type` field, and ESM syntax. // Warn about the missing `type` field so that the user can avoid the performance penalty of detection. diff --git a/lib/internal/modules/helpers.js b/lib/internal/modules/helpers.js index 2eae0f6cd3f78f..36de471a66a02e 100644 --- a/lib/internal/modules/helpers.js +++ b/lib/internal/modules/helpers.js @@ -307,10 +307,15 @@ function lazyLoadTSParser() { return parseTS; } +/** + * Performs type-stripping to TypeScript source code. + * @param {string} source TypeScript code to parse. + * @returns {string} JavaScript code. + */ function tsParse(source) { - if (!source || typeof source !== 'string') { return; } + if (!source || typeof source !== 'string') { return ''; } const transformSync = lazyLoadTSParser(); - const { code } = transformSync(source); + const { code } = transformSync(source, { __proto__: null, mode: 'strip-only' }); return code; } diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index ee526cc089b20d..1e1a1ea46fc6c1 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -84,7 +84,7 @@ function shouldUseESMLoader(mainPath) { if (getOptionValue('--experimental-strip-types')) { // This ensures that --experimental-default-type=commonjs and .mts files are treated as commonjs if (getOptionValue('--experimental-default-type') === 'commonjs') { return false; } - if (mainPath && StringPrototypeEndsWith(mainPath, '.cts')) { return false; } + if (!mainPath || StringPrototypeEndsWith(mainPath, '.cts')) { return false; } // This will likely change in the future to start with commonjs loader by default if (mainPath && StringPrototypeEndsWith(mainPath, '.mts')) { return true; } } diff --git a/test/es-module/test-typescript-commonjs.mjs b/test/es-module/test-typescript-commonjs.mjs index aa3550bbab95f3..f65d7281010ab7 100644 --- a/test/es-module/test-typescript-commonjs.mjs +++ b/test/es-module/test-typescript-commonjs.mjs @@ -118,7 +118,7 @@ test('execute a .cts file importing a .mts file export', async () => { strictEqual(result.code, 0); }); -test('expect failure of a .cts file with default type module', async () => { +test('execute a .cts file with default type module', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', '--experimental-default-type=module', // Keeps working with commonjs diff --git a/test/es-module/test-typescript-eval.mjs b/test/es-module/test-typescript-eval.mjs index aba4c01108f821..a6bb378be37023 100644 --- a/test/es-module/test-typescript-eval.mjs +++ b/test/es-module/test-typescript-eval.mjs @@ -4,7 +4,6 @@ import { test } from 'node:test'; test('eval TypeScript ESM syntax', async () => { const result = await spawnPromisified(process.execPath, [ - '--input-type=module', '--experimental-strip-types', '--eval', `import util from 'node:util' @@ -18,7 +17,6 @@ test('eval TypeScript ESM syntax', async () => { test('eval TypeScript CommonJS syntax', async () => { const result = await spawnPromisified(process.execPath, [ - '--input-type=commonjs', '--experimental-strip-types', '--eval', `const util = require('node:util'); diff --git a/test/es-module/test-typescript-module.mjs b/test/es-module/test-typescript-module.mjs index 976e6004100bf5..1af8f686962535 100644 --- a/test/es-module/test-typescript-module.mjs +++ b/test/es-module/test-typescript-module.mjs @@ -28,7 +28,6 @@ test('execute an .mts file importing an .mts file', async () => { test('execute an .mts file importing a .ts file', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', // this should fail '--no-warnings', fixtures.path('typescript/mts/test-import-ts-file.mts'), ]); @@ -42,7 +41,6 @@ test('execute an .mts file importing a .cts file', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', '--no-warnings', - '--no-warnings', fixtures.path('typescript/mts/test-import-commonjs.mts'), ]); @@ -95,3 +93,27 @@ test('execute a .ts file from node_modules', async () => { strictEqual(result.stdout, ''); strictEqual(result.code, 1); }); + +test('execute an empty .ts file', async () => { + const result = await spawnPromisified(process.execPath, [ + '--experimental-strip-types', + '--no-warnings', + fixtures.path('typescript/ts/test-empty-file.ts'), + ]); + + strictEqual(result.stderr, ''); + strictEqual(result.stdout, ''); + strictEqual(result.code, 0); +}); + +test('execute .ts file importing a module', async () => { + const result = await spawnPromisified(process.execPath, [ + '--experimental-strip-types', + '--no-warnings', + fixtures.path('typescript/ts/test-import-fs.ts'), + ]); + + strictEqual(result.stderr, ''); + strictEqual(result.stdout, 'Hello, TypeScript!\n'); + strictEqual(result.code, 0); +}); diff --git a/test/es-module/test-typescript.mjs b/test/es-module/test-typescript.mjs index 1c41215f06c0bc..b8d509d3f5997c 100644 --- a/test/es-module/test-typescript.mjs +++ b/test/es-module/test-typescript.mjs @@ -17,7 +17,6 @@ test('execute a TypeScript file', async () => { test('execute a TypeScript file with imports', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', '--no-warnings', fixtures.path('typescript/ts/test-import-foo.ts'), ]); @@ -30,7 +29,6 @@ test('execute a TypeScript file with imports', async () => { test('execute a TypeScript file with node_modules', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', '--no-warnings', fixtures.path('typescript/ts/test-typescript-node-modules.ts'), ]); @@ -43,7 +41,6 @@ test('execute a TypeScript file with node_modules', async () => { test('expect error when executing a TypeScript file with imports with no extensions', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', fixtures.path('typescript/ts/test-import-no-extension.ts'), ]); @@ -101,7 +98,6 @@ test('execute a TypeScript file with type definition', async () => { test('execute a TypeScript file with type definition but no type keyword', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', fixtures.path('typescript/ts/test-import-no-type-keyword.ts'), ]); @@ -124,7 +120,6 @@ test('execute a TypeScript file with CommonJS syntax', async () => { test('execute a TypeScript file with ES module syntax', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=module', '--no-warnings', fixtures.path('typescript/ts/test-module-typescript.ts'), ]); @@ -159,7 +154,6 @@ test('expect stack trace of a TypeScript file to be correct', async () => { test('execute CommonJS TypeScript file from node_modules with require-module', async () => { const result = await spawnPromisified(process.execPath, [ - '--experimental-default-type=module', '--experimental-strip-types', fixtures.path('typescript/ts/test-import-ts-node-modules.ts'), ]); @@ -218,7 +212,6 @@ test('execute a TypeScript file with CommonJS syntax requiring .mts with require test('execute a TypeScript file with CommonJS syntax requiring .mts with require-module', async () => { const result = await spawnPromisified(process.execPath, [ '--experimental-strip-types', - '--experimental-default-type=commonjs', '--no-warnings', fixtures.path('typescript/ts/test-require-cts.ts'), ]); diff --git a/test/fixtures/typescript/ts/test-empty-file.ts b/test/fixtures/typescript/ts/test-empty-file.ts new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/test/fixtures/typescript/ts/test-empty-file.ts @@ -0,0 +1 @@ + diff --git a/test/fixtures/typescript/ts/test-import-fs.ts b/test/fixtures/typescript/ts/test-import-fs.ts new file mode 100644 index 00000000000000..032a93fa52eee5 --- /dev/null +++ b/test/fixtures/typescript/ts/test-import-fs.ts @@ -0,0 +1,2 @@ +import fs from 'fs'; +console.log('Hello, TypeScript!');