Skip to content

Commit 45f7d16

Browse files
marco-ippolitotargos
authored andcommitted
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 ffff8ce commit 45f7d16

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
@@ -454,17 +454,6 @@ function initializeCJS() {
454454
// TODO(joyeecheung): deprecate this in favor of a proper hook?
455455
Module.runMain =
456456
require('internal/modules/run_main').executeUserEntryPoint;
457-
458-
const tsEnabled = getOptionValue('--experimental-strip-types');
459-
if (tsEnabled) {
460-
Module._extensions['.cts'] = loadCTS;
461-
Module._extensions['.ts'] = loadTS;
462-
}
463-
if (getOptionValue('--experimental-require-module')) {
464-
if (tsEnabled) {
465-
Module._extensions['.mts'] = loadMTS;
466-
}
467-
}
468457
}
469458

470459
// Given a module name, and a list of paths to test, returns the first
@@ -670,31 +659,6 @@ function resolveExports(nmPath, request, conditions) {
670659
}
671660
}
672661

673-
// We don't cache this in case user extends the extensions.
674-
function getDefaultExtensions() {
675-
let extensions = ObjectKeys(Module._extensions);
676-
const tsEnabled = getOptionValue('--experimental-strip-types');
677-
if (tsEnabled) {
678-
// remove .ts and .cts from the default extensions
679-
// to avoid extensionless require of .ts and .cts files.
680-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
681-
(ext !== '.ts' || Module._extensions['.ts'] !== loadTS) &&
682-
(ext !== '.cts' || Module._extensions['.cts'] !== loadCTS),
683-
);
684-
}
685-
686-
if (!getOptionValue('--experimental-require-module')) {
687-
return extensions;
688-
}
689-
690-
if (tsEnabled) {
691-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
692-
ext !== '.mts' || Module._extensions['.mts'] !== loadMTS,
693-
);
694-
}
695-
return extensions;
696-
}
697-
698662
/**
699663
* Get the absolute path to a module.
700664
* @param {string} request Relative or absolute file path
@@ -786,7 +750,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
786750
if (!filename) {
787751
// Try it with each of the extensions
788752
if (exts === undefined) {
789-
exts = getDefaultExtensions();
753+
exts = ObjectKeys(Module._extensions);
790754
}
791755
filename = tryExtensions(basePath, exts, isMain);
792756
}
@@ -795,7 +759,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
795759
if (!filename && rc === 1) { // Directory.
796760
// try it with each of the extensions at "index"
797761
if (exts === undefined) {
798-
exts = getDefaultExtensions();
762+
exts = ObjectKeys(Module._extensions);
799763
}
800764
filename = tryPackage(basePath, exts, isMain, request);
801765
}
@@ -1460,12 +1424,6 @@ Module.prototype.load = function(filename) {
14601424

14611425
const extension = findLongestRegisteredExtension(filename);
14621426

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

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

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

0 commit comments

Comments
 (0)