Skip to content

Commit 708477b

Browse files
module: refactor commonjs typescript loader
This commit refactors the CommonJS loader to remove TypeScript-specific extensions from the require.extensions object for compatibility with libraries that depended on it to initialize extenal TypeScript loaders. PR-URL: #58657 Refs: nodejs/typescript#37 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Pietro Marchini <[email protected]> Reviewed-By: Xuguang Mei <[email protected]>
1 parent f48c6f0 commit 708477b

File tree

1 file changed

+19
-94
lines changed

1 file changed

+19
-94
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 19 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -453,17 +453,6 @@ function initializeCJS() {
453453
// TODO(joyeecheung): deprecate this in favor of a proper hook?
454454
Module.runMain =
455455
require('internal/modules/run_main').executeUserEntryPoint;
456-
457-
const tsEnabled = getOptionValue('--experimental-strip-types');
458-
if (tsEnabled) {
459-
Module._extensions['.cts'] = loadCTS;
460-
Module._extensions['.ts'] = loadTS;
461-
}
462-
if (getOptionValue('--experimental-require-module')) {
463-
if (tsEnabled) {
464-
Module._extensions['.mts'] = loadMTS;
465-
}
466-
}
467456
}
468457

469458
// Given a module name, and a list of paths to test, returns the first
@@ -669,31 +658,6 @@ function resolveExports(nmPath, request, conditions) {
669658
}
670659
}
671660

672-
// We don't cache this in case user extends the extensions.
673-
function getDefaultExtensions() {
674-
let extensions = ObjectKeys(Module._extensions);
675-
const tsEnabled = getOptionValue('--experimental-strip-types');
676-
if (tsEnabled) {
677-
// remove .ts and .cts from the default extensions
678-
// to avoid extensionless require of .ts and .cts files.
679-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
680-
(ext !== '.ts' || Module._extensions['.ts'] !== loadTS) &&
681-
(ext !== '.cts' || Module._extensions['.cts'] !== loadCTS),
682-
);
683-
}
684-
685-
if (!getOptionValue('--experimental-require-module')) {
686-
return extensions;
687-
}
688-
689-
if (tsEnabled) {
690-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
691-
ext !== '.mts' || Module._extensions['.mts'] !== loadMTS,
692-
);
693-
}
694-
return extensions;
695-
}
696-
697661
/**
698662
* Get the absolute path to a module.
699663
* @param {string} request Relative or absolute file path
@@ -785,7 +749,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
785749
if (!filename) {
786750
// Try it with each of the extensions
787751
if (exts === undefined) {
788-
exts = getDefaultExtensions();
752+
exts = ObjectKeys(Module._extensions);
789753
}
790754
filename = tryExtensions(basePath, exts, isMain);
791755
}
@@ -794,7 +758,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
794758
if (!filename && rc === 1) { // Directory.
795759
// try it with each of the extensions at "index"
796760
if (exts === undefined) {
797-
exts = getDefaultExtensions();
761+
exts = ObjectKeys(Module._extensions);
798762
}
799763
filename = tryPackage(basePath, exts, isMain, request);
800764
}
@@ -1459,12 +1423,6 @@ Module.prototype.load = function(filename) {
14591423

14601424
const extension = findLongestRegisteredExtension(filename);
14611425

1462-
if (getOptionValue('--experimental-strip-types')) {
1463-
if (StringPrototypeEndsWith(filename, '.mts') && !Module._extensions['.mts']) {
1464-
throw new ERR_REQUIRE_ESM(filename, true);
1465-
}
1466-
}
1467-
14681426
Module._extensions[extension](this, filename);
14691427
this.loaded = true;
14701428

@@ -1776,55 +1734,6 @@ function loadSource(mod, filename, formatFromNode) {
17761734
return { source: mod[kModuleSource], format: mod[kFormat] };
17771735
}
17781736

1779-
/**
1780-
* Built-in handler for `.mts` files.
1781-
* @param {Module} mod CJS module instance
1782-
* @param {string} filename The file path of the module
1783-
*/
1784-
function loadMTS(mod, filename) {
1785-
const loadResult = loadSource(mod, filename, 'module-typescript');
1786-
mod._compile(loadResult.source, filename, loadResult.format);
1787-
}
1788-
1789-
/**
1790-
* Built-in handler for `.cts` files.
1791-
* @param {Module} module CJS module instance
1792-
* @param {string} filename The file path of the module
1793-
*/
1794-
function loadCTS(module, filename) {
1795-
const loadResult = loadSource(module, filename, 'commonjs-typescript');
1796-
module._compile(loadResult.source, filename, loadResult.format);
1797-
}
1798-
1799-
/**
1800-
* Built-in handler for `.ts` files.
1801-
* @param {Module} module CJS module instance
1802-
* @param {string} filename The file path of the module
1803-
*/
1804-
function loadTS(module, filename) {
1805-
const pkg = packageJsonReader.getNearestParentPackageJSON(filename);
1806-
const typeFromPjson = pkg?.data.type;
1807-
1808-
let format;
1809-
if (typeFromPjson === 'module') {
1810-
format = 'module-typescript';
1811-
} else if (typeFromPjson === 'commonjs') {
1812-
format = 'commonjs-typescript';
1813-
} else {
1814-
format = 'typescript';
1815-
}
1816-
const loadResult = loadSource(module, filename, format);
1817-
1818-
// Function require shouldn't be used in ES modules when require(esm) is disabled.
1819-
if (typeFromPjson === 'module' && !getOptionValue('--experimental-require-module')) {
1820-
const err = getRequireESMError(module, pkg, loadResult.source, filename);
1821-
throw err;
1822-
}
1823-
1824-
module[kFormat] = loadResult.format;
1825-
module._compile(loadResult.source, filename, loadResult.format);
1826-
};
1827-
18281737
function reconstructErrorStack(err, parentPath, parentSource) {
18291738
const errLine = StringPrototypeSplit(
18301739
StringPrototypeSlice(err.stack, StringPrototypeIndexOf(
@@ -1878,6 +1787,7 @@ function getRequireESMError(mod, pkg, content, filename) {
18781787
*/
18791788
Module._extensions['.js'] = function(module, filename) {
18801789
let format, pkg;
1790+
const tsEnabled = getOptionValue('--experimental-strip-types');
18811791
if (StringPrototypeEndsWith(filename, '.cjs')) {
18821792
format = 'commonjs';
18831793
} else if (StringPrototypeEndsWith(filename, '.mjs')) {
@@ -1888,10 +1798,25 @@ Module._extensions['.js'] = function(module, filename) {
18881798
if (typeFromPjson === 'module' || typeFromPjson === 'commonjs' || !typeFromPjson) {
18891799
format = typeFromPjson;
18901800
}
1801+
} else if (StringPrototypeEndsWith(filename, '.mts') && tsEnabled) {
1802+
format = 'module-typescript';
1803+
} else if (StringPrototypeEndsWith(filename, '.cts') && tsEnabled) {
1804+
format = 'commonjs-typescript';
1805+
} else if (StringPrototypeEndsWith(filename, '.ts') && tsEnabled) {
1806+
pkg = packageJsonReader.getNearestParentPackageJSON(filename);
1807+
const typeFromPjson = pkg?.data.type;
1808+
if (typeFromPjson === 'module') {
1809+
format = 'module-typescript';
1810+
} else if (typeFromPjson === 'commonjs') {
1811+
format = 'commonjs-typescript';
1812+
} else {
1813+
format = 'typescript';
1814+
}
18911815
}
18921816
const { source, format: loadedFormat } = loadSource(module, filename, format);
18931817
// Function require shouldn't be used in ES modules when require(esm) is disabled.
1894-
if (loadedFormat === 'module' && !getOptionValue('--experimental-require-module')) {
1818+
if ((loadedFormat === 'module' || loadedFormat === 'module-typescript') &&
1819+
!getOptionValue('--experimental-require-module')) {
18951820
const err = getRequireESMError(module, pkg, source, filename);
18961821
throw err;
18971822
}

0 commit comments

Comments
 (0)