Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 67ecb10

Browse filesBrowse files
module: fix discrepancy between .ts and .js
PR-URL: #54461 Backport-PR-URL: #54566 Fixes: #54457 Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
1 parent 8a3482e commit 67ecb10
Copy full SHA for 67ecb10

File tree

Expand file treeCollapse file tree

6 files changed

+83
-56
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+83
-56
lines changed
Open diff view settings
Collapse file

‎lib/internal/modules/esm/get_format.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/get_format.js
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE
161161
default: { // The user did not pass `--experimental-default-type`.
162162
// `source` is undefined when this is called from `defaultResolve`;
163163
// but this gets called again from `defaultLoad`/`defaultLoadSync`.
164-
let parsedSource;
165-
if (source) {
166-
const { stripTypeScriptTypes } = require('internal/modules/helpers');
167-
parsedSource = stripTypeScriptTypes(source, url);
168-
}
164+
// Since experimental-strip-types depends on detect-module, we always return null
165+
// if source is undefined.
166+
if (!source) { return null; }
167+
const { stripTypeScriptTypes, stringify } = require('internal/modules/helpers');
168+
const stringifiedSource = stringify(source);
169+
const parsedSource = stripTypeScriptTypes(stringifiedSource, fileURLToPath(url));
169170
const detectedFormat = detectModuleFormat(parsedSource, url);
170-
// When source is undefined, default to module-typescript.
171-
const format = detectedFormat ? `${detectedFormat}-typescript` : 'module-typescript';
171+
const format = `${detectedFormat}-typescript`;
172172
if (format === 'module-typescript' && foundPackageJson) {
173173
// This module has a .js extension, a package.json with no `type` field, and ESM syntax.
174174
// Warn about the missing `type` field so that the user can avoid the performance penalty of detection.
Collapse file

‎lib/internal/modules/esm/translators.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/translators.js
+2-49Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ const {
1818
globalThis: { WebAssembly },
1919
} = primordials;
2020

21-
/** @type {import('internal/util/types')} */
22-
let _TYPES = null;
23-
/**
24-
* Lazily loads and returns the internal/util/types module.
25-
*/
26-
function lazyTypes() {
27-
if (_TYPES !== null) { return _TYPES; }
28-
return _TYPES = require('internal/util/types');
29-
}
30-
3121
const {
3222
compileFunctionForCJSLoader,
3323
} = internalBinding('contextify');
@@ -37,7 +27,9 @@ const assert = require('internal/assert');
3727
const { readFileSync } = require('fs');
3828
const { dirname, extname, isAbsolute } = require('path');
3929
const {
30+
assertBufferSource,
4031
loadBuiltinModule,
32+
stringify,
4133
stripTypeScriptTypes,
4234
stripBOM,
4335
urlToFilename,
@@ -57,7 +49,6 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
5749
const { emitExperimentalWarning, kEmptyObject, setOwnProperty, isWindows } = require('internal/util');
5850
const {
5951
ERR_UNKNOWN_BUILTIN_MODULE,
60-
ERR_INVALID_RETURN_PROPERTY_VALUE,
6152
} = require('internal/errors').codes;
6253
const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache');
6354
const moduleWrap = internalBinding('module_wrap');
@@ -107,44 +98,6 @@ function initCJSParseSync() {
10798
const translators = new SafeMap();
10899
exports.translators = translators;
109100

110-
let DECODER = null;
111-
/**
112-
* Asserts that the given body is a buffer source (either a string, array buffer, or typed array).
113-
* Throws an error if the body is not a buffer source.
114-
* @param {string | ArrayBufferView | ArrayBuffer} body - The body to check.
115-
* @param {boolean} allowString - Whether or not to allow a string as a valid buffer source.
116-
* @param {string} hookName - The name of the hook being called.
117-
* @throws {ERR_INVALID_RETURN_PROPERTY_VALUE} If the body is not a buffer source.
118-
*/
119-
function assertBufferSource(body, allowString, hookName) {
120-
if (allowString && typeof body === 'string') {
121-
return;
122-
}
123-
const { isArrayBufferView, isAnyArrayBuffer } = lazyTypes();
124-
if (isArrayBufferView(body) || isAnyArrayBuffer(body)) {
125-
return;
126-
}
127-
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
128-
`${allowString ? 'string, ' : ''}array buffer, or typed array`,
129-
hookName,
130-
'source',
131-
body,
132-
);
133-
}
134-
135-
/**
136-
* Converts a buffer or buffer-like object to a string.
137-
* @param {string | ArrayBuffer | ArrayBufferView} body - The buffer or buffer-like object to convert to a string.
138-
* @returns {string} The resulting string.
139-
*/
140-
function stringify(body) {
141-
if (typeof body === 'string') { return body; }
142-
assertBufferSource(body, false, 'load');
143-
const { TextDecoder } = require('internal/encoding');
144-
DECODER = DECODER === null ? new TextDecoder() : DECODER;
145-
return DECODER.decode(body);
146-
}
147-
148101
/**
149102
* Converts a URL to a file path if the URL protocol is 'file:'.
150103
* @param {string} url - The URL to convert.
Collapse file

‎lib/internal/modules/helpers.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/helpers.js
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
} = primordials;
1717
const {
1818
ERR_INVALID_ARG_TYPE,
19+
ERR_INVALID_RETURN_PROPERTY_VALUE,
1920
} = require('internal/errors').codes;
2021
const { BuiltinModule } = require('internal/bootstrap/realm');
2122

@@ -429,10 +430,60 @@ function getCompileCacheDir() {
429430
return _getCompileCacheDir() || undefined;
430431
}
431432

433+
/** @type {import('internal/util/types')} */
434+
let _TYPES = null;
435+
/**
436+
* Lazily loads and returns the internal/util/types module.
437+
*/
438+
function lazyTypes() {
439+
if (_TYPES !== null) { return _TYPES; }
440+
return _TYPES = require('internal/util/types');
441+
}
442+
443+
/**
444+
* Asserts that the given body is a buffer source (either a string, array buffer, or typed array).
445+
* Throws an error if the body is not a buffer source.
446+
* @param {string | ArrayBufferView | ArrayBuffer} body - The body to check.
447+
* @param {boolean} allowString - Whether or not to allow a string as a valid buffer source.
448+
* @param {string} hookName - The name of the hook being called.
449+
* @throws {ERR_INVALID_RETURN_PROPERTY_VALUE} If the body is not a buffer source.
450+
*/
451+
function assertBufferSource(body, allowString, hookName) {
452+
if (allowString && typeof body === 'string') {
453+
return;
454+
}
455+
const { isArrayBufferView, isAnyArrayBuffer } = lazyTypes();
456+
if (isArrayBufferView(body) || isAnyArrayBuffer(body)) {
457+
return;
458+
}
459+
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
460+
`${allowString ? 'string, ' : ''}array buffer, or typed array`,
461+
hookName,
462+
'source',
463+
body,
464+
);
465+
}
466+
467+
let DECODER = null;
468+
469+
/**
470+
* Converts a buffer or buffer-like object to a string.
471+
* @param {string | ArrayBuffer | ArrayBufferView} body - The buffer or buffer-like object to convert to a string.
472+
* @returns {string} The resulting string.
473+
*/
474+
function stringify(body) {
475+
if (typeof body === 'string') { return body; }
476+
assertBufferSource(body, false, 'load');
477+
const { TextDecoder } = require('internal/encoding');
478+
DECODER = DECODER === null ? new TextDecoder() : DECODER;
479+
return DECODER.decode(body);
480+
}
481+
432482
module.exports = {
433483
addBuiltinLibsToObject,
434484
constants,
435485
enableCompileCache,
486+
assertBufferSource,
436487
getBuiltinModule,
437488
getCjsConditions,
438489
getCompileCacheDir,
@@ -442,6 +493,7 @@ module.exports = {
442493
makeRequireFunction,
443494
normalizeReferrerURL,
444495
stripTypeScriptTypes,
496+
stringify,
445497
stripBOM,
446498
toRealPath,
447499
hasStartedUserCJSExecution() {
Collapse file

‎test/es-module/test-typescript.mjs‎

Copy file name to clipboardExpand all lines: test/es-module/test-typescript.mjs
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,14 @@ test('execute a TypeScript file with CommonJS syntax requiring .mts with require
325325
match(result.stdout, /Hello, TypeScript!/);
326326
strictEqual(result.code, 0);
327327
});
328+
329+
test('execute a JavaScript file importing a cjs TypeScript file', async () => {
330+
const result = await spawnPromisified(process.execPath, [
331+
'--experimental-strip-types',
332+
'--no-warnings',
333+
fixtures.path('typescript/ts/issue-54457.mjs'),
334+
]);
335+
strictEqual(result.stderr, '');
336+
match(result.stdout, /Hello, TypeScript!/);
337+
strictEqual(result.code, 0);
338+
});
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// https://github.com/nodejs/node/issues/54457
2+
const { text } = await import('./test-require.ts');
3+
4+
console.log(text);
Collapse file
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const util = require('node:util');
2+
3+
const text = 'Hello, TypeScript!';
4+
5+
module.exports = {
6+
text
7+
};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.