Skip to content

Commit 89dc2bf

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: nodejs#58657 Refs: nodejs/typescript#37 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com> Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
1 parent 5aaa592 commit 89dc2bf

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
@@ -450,17 +450,6 @@ function initializeCJS() {
450450
// TODO(joyeecheung): deprecate this in favor of a proper hook?
451451
Module.runMain =
452452
require('internal/modules/run_main').executeUserEntryPoint;
453-
454-
const tsEnabled = getOptionValue('--experimental-strip-types');
455-
if (tsEnabled) {
456-
Module._extensions['.cts'] = loadCTS;
457-
Module._extensions['.ts'] = loadTS;
458-
}
459-
if (getOptionValue('--experimental-require-module')) {
460-
if (tsEnabled) {
461-
Module._extensions['.mts'] = loadMTS;
462-
}
463-
}
464453
}
465454

466455
// Given a module name, and a list of paths to test, returns the first
@@ -666,31 +655,6 @@ function resolveExports(nmPath, request, conditions) {
666655
}
667656
}
668657

669-
// We don't cache this in case user extends the extensions.
670-
function getDefaultExtensions() {
671-
let extensions = ObjectKeys(Module._extensions);
672-
const tsEnabled = getOptionValue('--experimental-strip-types');
673-
if (tsEnabled) {
674-
// remove .ts and .cts from the default extensions
675-
// to avoid extensionless require of .ts and .cts files.
676-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
677-
(ext !== '.ts' || Module._extensions['.ts'] !== loadTS) &&
678-
(ext !== '.cts' || Module._extensions['.cts'] !== loadCTS),
679-
);
680-
}
681-
682-
if (!getOptionValue('--experimental-require-module')) {
683-
return extensions;
684-
}
685-
686-
if (tsEnabled) {
687-
extensions = ArrayPrototypeFilter(extensions, (ext) =>
688-
ext !== '.mts' || Module._extensions['.mts'] !== loadMTS,
689-
);
690-
}
691-
return extensions;
692-
}
693-
694658
/**
695659
* Get the absolute path to a module.
696660
* @param {string} request Relative or absolute file path
@@ -782,7 +746,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
782746
if (!filename) {
783747
// Try it with each of the extensions
784748
if (exts === undefined) {
785-
exts = getDefaultExtensions();
749+
exts = ObjectKeys(Module._extensions);
786750
}
787751
filename = tryExtensions(basePath, exts, isMain);
788752
}
@@ -791,7 +755,7 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
791755
if (!filename && rc === 1) { // Directory.
792756
// try it with each of the extensions at "index"
793757
if (exts === undefined) {
794-
exts = getDefaultExtensions();
758+
exts = ObjectKeys(Module._extensions);
795759
}
796760
filename = tryPackage(basePath, exts, isMain, request);
797761
}
@@ -1456,12 +1420,6 @@ Module.prototype.load = function(filename) {
14561420

14571421
const extension = findLongestRegisteredExtension(filename);
14581422

1459-
if (getOptionValue('--experimental-strip-types')) {
1460-
if (StringPrototypeEndsWith(filename, '.mts') && !Module._extensions['.mts']) {
1461-
throw new ERR_REQUIRE_ESM(filename, true);
1462-
}
1463-
}
1464-
14651423
Module._extensions[extension](this, filename);
14661424
this.loaded = true;
14671425

@@ -1773,55 +1731,6 @@ function loadSource(mod, filename, formatFromNode) {
17731731
return { source: mod[kModuleSource], format: mod[kFormat] };
17741732
}
17751733

1776-
/**
1777-
* Built-in handler for `.mts` files.
1778-
* @param {Module} mod CJS module instance
1779-
* @param {string} filename The file path of the module
1780-
*/
1781-
function loadMTS(mod, filename) {
1782-
const loadResult = loadSource(mod, filename, 'module-typescript');
1783-
mod._compile(loadResult.source, filename, loadResult.format);
1784-
}
1785-
1786-
/**
1787-
* Built-in handler for `.cts` files.
1788-
* @param {Module} module CJS module instance
1789-
* @param {string} filename The file path of the module
1790-
*/
1791-
function loadCTS(module, filename) {
1792-
const loadResult = loadSource(module, filename, 'commonjs-typescript');
1793-
module._compile(loadResult.source, filename, loadResult.format);
1794-
}
1795-
1796-
/**
1797-
* Built-in handler for `.ts` files.
1798-
* @param {Module} module CJS module instance
1799-
* @param {string} filename The file path of the module
1800-
*/
1801-
function loadTS(module, filename) {
1802-
const pkg = packageJsonReader.getNearestParentPackageJSON(filename);
1803-
const typeFromPjson = pkg?.data.type;
1804-
1805-
let format;
1806-
if (typeFromPjson === 'module') {
1807-
format = 'module-typescript';
1808-
} else if (typeFromPjson === 'commonjs') {
1809-
format = 'commonjs-typescript';
1810-
} else {
1811-
format = 'typescript';
1812-
}
1813-
const loadResult = loadSource(module, filename, format);
1814-
1815-
// Function require shouldn't be used in ES modules when require(esm) is disabled.
1816-
if (typeFromPjson === 'module' && !getOptionValue('--experimental-require-module')) {
1817-
const err = getRequireESMError(module, pkg, loadResult.source, filename);
1818-
throw err;
1819-
}
1820-
1821-
module[kFormat] = loadResult.format;
1822-
module._compile(loadResult.source, filename, loadResult.format);
1823-
};
1824-
18251734
function reconstructErrorStack(err, parentPath, parentSource) {
18261735
const errLine = StringPrototypeSplit(
18271736
StringPrototypeSlice(err.stack, StringPrototypeIndexOf(
@@ -1875,6 +1784,7 @@ function getRequireESMError(mod, pkg, content, filename) {
18751784
*/
18761785
Module._extensions['.js'] = function(module, filename) {
18771786
let format, pkg;
1787+
const tsEnabled = getOptionValue('--experimental-strip-types');
18781788
if (StringPrototypeEndsWith(filename, '.cjs')) {
18791789
format = 'commonjs';
18801790
} else if (StringPrototypeEndsWith(filename, '.mjs')) {
@@ -1885,10 +1795,25 @@ Module._extensions['.js'] = function(module, filename) {
18851795
if (typeFromPjson === 'module' || typeFromPjson === 'commonjs' || !typeFromPjson) {
18861796
format = typeFromPjson;
18871797
}
1798+
} else if (StringPrototypeEndsWith(filename, '.mts') && tsEnabled) {
1799+
format = 'module-typescript';
1800+
} else if (StringPrototypeEndsWith(filename, '.cts') && tsEnabled) {
1801+
format = 'commonjs-typescript';
1802+
} else if (StringPrototypeEndsWith(filename, '.ts') && tsEnabled) {
1803+
pkg = packageJsonReader.getNearestParentPackageJSON(filename);
1804+
const typeFromPjson = pkg?.data.type;
1805+
if (typeFromPjson === 'module') {
1806+
format = 'module-typescript';
1807+
} else if (typeFromPjson === 'commonjs') {
1808+
format = 'commonjs-typescript';
1809+
} else {
1810+
format = 'typescript';
1811+
}
18881812
}
18891813
const { source, format: loadedFormat } = loadSource(module, filename, format);
18901814
// Function require shouldn't be used in ES modules when require(esm) is disabled.
1891-
if (loadedFormat === 'module' && !getOptionValue('--experimental-require-module')) {
1815+
if ((loadedFormat === 'module' || loadedFormat === 'module-typescript') &&
1816+
!getOptionValue('--experimental-require-module')) {
18921817
const err = getRequireESMError(module, pkg, source, filename);
18931818
throw err;
18941819
}

0 commit comments

Comments
 (0)