GeezerVison is showing github.com — module: fix strip-types interaction with detect-module · nodejs/node@c20e841
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/get_format.js +2-1Lines changed: 2 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -163,7 +163,8 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE | 163 | 163 | const { tsParse } = require('internal/modules/helpers'); | 164 | 164 | const parsedSource = tsParse(source); | 165 | 165 | const detectedFormat = detectModuleFormat(parsedSource, url); | 166 | | - const format = detectedFormat ? `${detectedFormat}-typescript` : 'commonjs-typescript'; | | 166 | + // When source is undefined, default to module-typescript. | | 167 | + const format = detectedFormat ? `${detectedFormat}-typescript` : 'module-typescript'; | 167 | 168 | if (format === 'module-typescript') { | 168 | 169 | // This module has a .js extension, a package.json with no `type` field, and ESM syntax. | 169 | 170 | // Warn about the missing `type` field so that the user can avoid the performance penalty of detection. | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/helpers.js +7-2Lines changed: 7 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -307,10 +307,15 @@ function lazyLoadTSParser() { | 307 | 307 | return parseTS; | 308 | 308 | } | 309 | 309 |
| | 310 | +/** | | 311 | + * Performs type-stripping to TypeScript source code. | | 312 | + * @param {string} source TypeScript code to parse. | | 313 | + * @returns {string} JavaScript code. | | 314 | + */ | 310 | 315 | function tsParse(source) { | 311 | | - if (!source || typeof source !== 'string') { return; } | | 316 | + if (!source || typeof source !== 'string') { return ''; } | 312 | 317 | const transformSync = lazyLoadTSParser(); | 313 | | - const { code } = transformSync(source); | | 318 | + const { code } = transformSync(source, { __proto__: null, mode: 'strip-only' }); | 314 | 319 | return code; | 315 | 320 | } | 316 | 321 |
| |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/run_main.js +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -84,7 +84,7 @@ function shouldUseESMLoader(mainPath) { | 84 | 84 | if (getOptionValue('--experimental-strip-types')) { | 85 | 85 | // This ensures that --experimental-default-type=commonjs and .mts files are treated as commonjs | 86 | 86 | if (getOptionValue('--experimental-default-type') === 'commonjs') { return false; } | 87 | | - if (mainPath && StringPrototypeEndsWith(mainPath, '.cts')) { return false; } | | 87 | + if (!mainPath || StringPrototypeEndsWith(mainPath, '.cts')) { return false; } | 88 | 88 | // This will likely change in the future to start with commonjs loader by default | 89 | 89 | if (mainPath && StringPrototypeEndsWith(mainPath, '.mts')) { return true; } | 90 | 90 | } | |
Collapse file Copy file name to clipboardExpand all lines: src/node_options.cc +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -800,6 +800,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | 800 | 800 | "Experimental type-stripping for TypeScript files.", | 801 | 801 | &EnvironmentOptions::experimental_strip_types, | 802 | 802 | kAllowedInEnvvar); | | 803 | + Implies("--experimental-strip-types", "--experimental-detect-module"); | 803 | 804 | AddOption("--interactive", | 804 | 805 | "always enter the REPL even if stdin does not appear " | 805 | 806 | "to be a terminal", | |
Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-typescript-commonjs.mjs +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -118,7 +118,7 @@ test('execute a .cts file importing a .mts file export', async () => { | 118 | 118 | strictEqual(result.code, 0); | 119 | 119 | }); | 120 | 120 |
| 121 | | -test('expect failure of a .cts file with default type module', async () => { | | 121 | +test('execute a .cts file with default type module', async () => { | 122 | 122 | const result = await spawnPromisified(process.execPath, [ | 123 | 123 | '--experimental-strip-types', | 124 | 124 | '--experimental-default-type=module', // Keeps working with commonjs | |
Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-typescript-eval.mjs +28-2Lines changed: 28 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -4,7 +4,6 @@ import { test } from 'node:test'; | 4 | 4 |
| 5 | 5 | test('eval TypeScript ESM syntax', async () => { | 6 | 6 | const result = await spawnPromisified(process.execPath, [ | 7 | | - '--input-type=module', | 8 | 7 | '--experimental-strip-types', | 9 | 8 | '--eval', | 10 | 9 | `import util from 'node:util' | @@ -16,9 +15,22 @@ test('eval TypeScript ESM syntax', async () => { | 16 | 15 | strictEqual(result.code, 0); | 17 | 16 | }); | 18 | 17 |
| | 18 | +test('eval TypeScript ESM syntax with input-type module', async () => { | | 19 | + const result = await spawnPromisified(process.execPath, [ | | 20 | + '--experimental-strip-types', | | 21 | + '--input-type=module', | | 22 | + '--eval', | | 23 | + `import util from 'node:util' | | 24 | + const text: string = 'Hello, TypeScript!' | | 25 | + console.log(util.styleText('red', text));`]); | | 26 | + | | 27 | + match(result.stderr, /Type Stripping is an experimental feature and might change at any time/); | | 28 | + match(result.stdout, /Hello, TypeScript!/); | | 29 | + strictEqual(result.code, 0); | | 30 | +}); | | 31 | + | 19 | 32 | test('eval TypeScript CommonJS syntax', async () => { | 20 | 33 | const result = await spawnPromisified(process.execPath, [ | 21 | | - '--input-type=commonjs', | 22 | 34 | '--experimental-strip-types', | 23 | 35 | '--eval', | 24 | 36 | `const util = require('node:util'); | @@ -30,6 +42,20 @@ test('eval TypeScript CommonJS syntax', async () => { | 30 | 42 | strictEqual(result.code, 0); | 31 | 43 | }); | 32 | 44 |
| | 45 | +test('eval TypeScript CommonJS syntax with input-type commonjs', async () => { | | 46 | + const result = await spawnPromisified(process.execPath, [ | | 47 | + '--experimental-strip-types', | | 48 | + '--input-type=commonjs', | | 49 | + '--eval', | | 50 | + `const util = require('node:util'); | | 51 | + const text: string = 'Hello, TypeScript!' | | 52 | + console.log(util.styleText('red', text));`, | | 53 | + '--no-warnings']); | | 54 | + match(result.stdout, /Hello, TypeScript!/); | | 55 | + strictEqual(result.stderr, ''); | | 56 | + strictEqual(result.code, 0); | | 57 | +}); | | 58 | + | 33 | 59 | test('eval TypeScript CommonJS syntax by default', async () => { | 34 | 60 | const result = await spawnPromisified(process.execPath, [ | 35 | 61 | '--experimental-strip-types', | |
Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-typescript-module.mjs +37-2Lines changed: 37 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -28,7 +28,6 @@ test('execute an .mts file importing an .mts file', async () => { | 28 | 28 | test('execute an .mts file importing a .ts file', async () => { | 29 | 29 | const result = await spawnPromisified(process.execPath, [ | 30 | 30 | '--experimental-strip-types', | 31 | | - '--experimental-default-type=module', // this should fail | 32 | 31 | '--no-warnings', | 33 | 32 | fixtures.path('typescript/mts/test-import-ts-file.mts'), | 34 | 33 | ]); | @@ -38,10 +37,22 @@ test('execute an .mts file importing a .ts file', async () => { | 38 | 37 | strictEqual(result.code, 0); | 39 | 38 | }); | 40 | 39 |
| 41 | | -test('execute an .mts file importing a .cts file', async () => { | | 40 | +test('execute an .mts file importing a .ts file with default-type module', async () => { | 42 | 41 | const result = await spawnPromisified(process.execPath, [ | 43 | 42 | '--experimental-strip-types', | | 43 | + '--experimental-default-type=module', | 44 | 44 | '--no-warnings', | | 45 | + fixtures.path('typescript/mts/test-import-ts-file.mts'), | | 46 | + ]); | | 47 | + | | 48 | + strictEqual(result.stderr, ''); | | 49 | + match(result.stdout, /Hello, TypeScript!/); | | 50 | + strictEqual(result.code, 0); | | 51 | +}); | | 52 | + | | 53 | +test('execute an .mts file importing a .cts file', async () => { | | 54 | + const result = await spawnPromisified(process.execPath, [ | | 55 | + '--experimental-strip-types', | 45 | 56 | '--no-warnings', | 46 | 57 | fixtures.path('typescript/mts/test-import-commonjs.mts'), | 47 | 58 | ]); | @@ -95,3 +106,27 @@ test('execute a .ts file from node_modules', async () => { | 95 | 106 | strictEqual(result.stdout, ''); | 96 | 107 | strictEqual(result.code, 1); | 97 | 108 | }); | | 109 | + | | 110 | +test('execute an empty .ts file', async () => { | | 111 | + const result = await spawnPromisified(process.execPath, [ | | 112 | + '--experimental-strip-types', | | 113 | + '--no-warnings', | | 114 | + fixtures.path('typescript/ts/test-empty-file.ts'), | | 115 | + ]); | | 116 | + | | 117 | + strictEqual(result.stderr, ''); | | 118 | + strictEqual(result.stdout, ''); | | 119 | + strictEqual(result.code, 0); | | 120 | +}); | | 121 | + | | 122 | +test('execute .ts file importing a module', async () => { | | 123 | + const result = await spawnPromisified(process.execPath, [ | | 124 | + '--experimental-strip-types', | | 125 | + '--no-warnings', | | 126 | + fixtures.path('typescript/ts/test-import-fs.ts'), | | 127 | + ]); | | 128 | + | | 129 | + strictEqual(result.stderr, ''); | | 130 | + strictEqual(result.stdout, 'Hello, TypeScript!\n'); | | 131 | + strictEqual(result.code, 0); | | 132 | +}); |
Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-typescript.mjs +87-3Lines changed: 87 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -15,6 +15,18 @@ test('execute a TypeScript file', async () => { | 15 | 15 | }); | 16 | 16 |
| 17 | 17 | test('execute a TypeScript file with imports', async () => { | | 18 | + const result = await spawnPromisified(process.execPath, [ | | 19 | + '--experimental-strip-types', | | 20 | + '--no-warnings', | | 21 | + fixtures.path('typescript/ts/test-import-foo.ts'), | | 22 | + ]); | | 23 | + | | 24 | + strictEqual(result.stderr, ''); | | 25 | + match(result.stdout, /Hello, TypeScript!/); | | 26 | + strictEqual(result.code, 0); | | 27 | +}); | | 28 | + | | 29 | +test('execute a TypeScript file with imports with default-type module', async () => { | 18 | 30 | const result = await spawnPromisified(process.execPath, [ | 19 | 31 | '--experimental-strip-types', | 20 | 32 | '--experimental-default-type=module', | @@ -28,6 +40,18 @@ test('execute a TypeScript file with imports', async () => { | 28 | 40 | }); | 29 | 41 |
| 30 | 42 | test('execute a TypeScript file with node_modules', async () => { | | 43 | + const result = await spawnPromisified(process.execPath, [ | | 44 | + '--experimental-strip-types', | | 45 | + '--no-warnings', | | 46 | + fixtures.path('typescript/ts/test-typescript-node-modules.ts'), | | 47 | + ]); | | 48 | + | | 49 | + strictEqual(result.stderr, ''); | | 50 | + match(result.stdout, /Hello, TypeScript!/); | | 51 | + strictEqual(result.code, 0); | | 52 | +}); | | 53 | + | | 54 | +test('execute a TypeScript file with node_modules with default-type module', async () => { | 31 | 55 | const result = await spawnPromisified(process.execPath, [ | 32 | 56 | '--experimental-strip-types', | 33 | 57 | '--experimental-default-type=module', | @@ -43,7 +67,6 @@ test('execute a TypeScript file with node_modules', async () => { | 43 | 67 | test('expect error when executing a TypeScript file with imports with no extensions', async () => { | 44 | 68 | const result = await spawnPromisified(process.execPath, [ | 45 | 69 | '--experimental-strip-types', | 46 | | - '--experimental-default-type=module', | 47 | 70 | fixtures.path('typescript/ts/test-import-no-extension.ts'), | 48 | 71 | ]); | 49 | 72 |
| @@ -52,6 +75,19 @@ test('expect error when executing a TypeScript file with imports with no extensi | 52 | 75 | strictEqual(result.code, 1); | 53 | 76 | }); | 54 | 77 |
| | 78 | +test('expect error when executing a TypeScript file with imports with no extensions with default-type module', | | 79 | + async () => { | | 80 | + const result = await spawnPromisified(process.execPath, [ | | 81 | + '--experimental-strip-types', | | 82 | + '--experimental-default-type=module', | | 83 | + fixtures.path('typescript/ts/test-import-no-extension.ts'), | | 84 | + ]); | | 85 | + | | 86 | + match(result.stderr, /Error \[ERR_MODULE_NOT_FOUND\]:/); | | 87 | + strictEqual(result.stdout, ''); | | 88 | + strictEqual(result.code, 1); | | 89 | + }); | | 90 | + | 55 | 91 | test('expect error when executing a TypeScript file with enum', async () => { | 56 | 92 | const result = await spawnPromisified(process.execPath, [ | 57 | 93 | '--experimental-strip-types', | @@ -99,6 +135,17 @@ test('execute a TypeScript file with type definition', async () => { | 99 | 135 | }); | 100 | 136 |
| 101 | 137 | test('execute a TypeScript file with type definition but no type keyword', async () => { | | 138 | + const result = await spawnPromisified(process.execPath, [ | | 139 | + '--experimental-strip-types', | | 140 | + fixtures.path('typescript/ts/test-import-no-type-keyword.ts'), | | 141 | + ]); | | 142 | + | | 143 | + match(result.stderr, /does not provide an export named 'MyType'/); | | 144 | + strictEqual(result.stdout, ''); | | 145 | + strictEqual(result.code, 1); | | 146 | +}); | | 147 | + | | 148 | +test('execute a TypeScript file with type definition but no type keyword with default-type modue', async () => { | 102 | 149 | const result = await spawnPromisified(process.execPath, [ | 103 | 150 | '--experimental-strip-types', | 104 | 151 | '--experimental-default-type=module', | @@ -122,6 +169,18 @@ test('execute a TypeScript file with CommonJS syntax', async () => { | 122 | 169 | }); | 123 | 170 |
| 124 | 171 | test('execute a TypeScript file with ES module syntax', async () => { | | 172 | + const result = await spawnPromisified(process.execPath, [ | | 173 | + '--experimental-strip-types', | | 174 | + '--no-warnings', | | 175 | + fixtures.path('typescript/ts/test-module-typescript.ts'), | | 176 | + ]); | | 177 | + | | 178 | + strictEqual(result.stderr, ''); | | 179 | + match(result.stdout, /Hello, TypeScript!/); | | 180 | + strictEqual(result.code, 0); | | 181 | +}); | | 182 | + | | 183 | +test('execute a TypeScript file with ES module syntax with default-type module', async () => { | 125 | 184 | const result = await spawnPromisified(process.execPath, [ | 126 | 185 | '--experimental-strip-types', | 127 | 186 | '--experimental-default-type=module', | @@ -159,7 +218,6 @@ test('expect stack trace of a TypeScript file to be correct', async () => { | 159 | 218 |
| 160 | 219 | test('execute CommonJS TypeScript file from node_modules with require-module', async () => { | 161 | 220 | const result = await spawnPromisified(process.execPath, [ | 162 | | - '--experimental-default-type=module', | 163 | 221 | '--experimental-strip-types', | 164 | 222 | fixtures.path('typescript/ts/test-import-ts-node-modules.ts'), | 165 | 223 | ]); | @@ -169,6 +227,19 @@ test('execute CommonJS TypeScript file from node_modules with require-module', a | 169 | 227 | strictEqual(result.code, 1); | 170 | 228 | }); | 171 | 229 |
| | 230 | +test('execute CommonJS TypeScript file from node_modules with require-module and default-type module', | | 231 | + async () => { | | 232 | + const result = await spawnPromisified(process.execPath, [ | | 233 | + '--experimental-strip-types', | | 234 | + '--experimental-default-type=module', | | 235 | + fixtures.path('typescript/ts/test-import-ts-node-modules.ts'), | | 236 | + ]); | | 237 | + | | 238 | + match(result.stderr, /ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING/); | | 239 | + strictEqual(result.stdout, ''); | | 240 | + strictEqual(result.code, 1); | | 241 | + }); | | 242 | + | 172 | 243 | test('execute a TypeScript file with CommonJS syntax but default type module', async () => { | 173 | 244 | const result = await spawnPromisified(process.execPath, [ | 174 | 245 | '--experimental-strip-types', | @@ -218,7 +289,6 @@ test('execute a TypeScript file with CommonJS syntax requiring .mts with require | 218 | 289 | test('execute a TypeScript file with CommonJS syntax requiring .mts with require-module', async () => { | 219 | 290 | const result = await spawnPromisified(process.execPath, [ | 220 | 291 | '--experimental-strip-types', | 221 | | - '--experimental-default-type=commonjs', | 222 | 292 | '--no-warnings', | 223 | 293 | fixtures.path('typescript/ts/test-require-cts.ts'), | 224 | 294 | ]); | @@ -227,3 +297,17 @@ test('execute a TypeScript file with CommonJS syntax requiring .mts with require | 227 | 297 | match(result.stdout, /Hello, TypeScript!/); | 228 | 298 | strictEqual(result.code, 0); | 229 | 299 | }); | | 300 | + | | 301 | +test('execute a TypeScript file with CommonJS syntax requiring .mts with require-module with default-type commonjs', | | 302 | + async () => { | | 303 | + const result = await spawnPromisified(process.execPath, [ | | 304 | + '--experimental-strip-types', | | 305 | + '--experimental-default-type=commonjs', | | 306 | + '--no-warnings', | | 307 | + fixtures.path('typescript/ts/test-require-cts.ts'), | | 308 | + ]); | | 309 | + | | 310 | + strictEqual(result.stderr, ''); | | 311 | + match(result.stdout, /Hello, TypeScript!/); | | 312 | + strictEqual(result.code, 0); | | 313 | + }); |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | + |
Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import fs from 'fs'; | | 2 | +console.log('Hello, TypeScript!'); |
|