Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename module resolution option node to node10 (preserving backward-compatible alias) #51901

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4701,7 +4701,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression, ignoreErrors?: boolean): Symbol | undefined {
const isClassic = getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic;
const errorMessage = isClassic?
Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option
Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option
: Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations;
return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : errorMessage);
}
Expand Down Expand Up @@ -29790,7 +29790,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
const isClassic = getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic;
const errorMessage = isClassic
? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option
? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option
: Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations;
const mod = resolveExternalModule(location!, runtimeImportSpecifier, errorMessage, location!);
const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined;
Expand Down
12 changes: 8 additions & 4 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -961,12 +961,15 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
{
name: "moduleResolution",
type: new Map(getEntries({
node: ModuleResolutionKind.NodeJs,
// N.B. The first entry specifies the value shown in `tsc --init`
node10: ModuleResolutionKind.Node10,
node: ModuleResolutionKind.Node10,
classic: ModuleResolutionKind.Classic,
node16: ModuleResolutionKind.Node16,
nodenext: ModuleResolutionKind.NodeNext,
bundler: ModuleResolutionKind.Bundler,
})),
deprecatedKeys: new Set(["node"]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, this only filters the config parsing diagnostic that says what the valid options are (next changed lines in this file).

affectsModuleResolution: true,
paramType: Diagnostics.STRATEGY,
category: Diagnostics.Modules,
Expand Down Expand Up @@ -1685,8 +1688,9 @@ export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOpt
}

function createDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType, createDiagnostic: (message: DiagnosticMessage, arg0: string, arg1: string) => Diagnostic): Diagnostic {
const namesOfType = arrayFrom(opt.type.keys()).map(key => `'${key}'`).join(", ");
return createDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
const namesOfType = arrayFrom(opt.type.keys());
const stringNames = (opt.deprecatedKeys ? namesOfType.filter(k => !opt.deprecatedKeys!.has(k)) : namesOfType).map(key => `'${key}'`).join(", ");
return createDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, stringNames);
}

/** @internal */
Expand Down Expand Up @@ -3404,7 +3408,7 @@ function getExtendsConfigPath(
return extendedConfigPath;
}
// If the path isn't a rooted or relative path, resolve like a module
const resolved = nodeModuleNameResolver(extendedConfig, combinePaths(basePath, "tsconfig.json"), { moduleResolution: ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
const resolved = nodeModuleNameResolver(extendedConfig, combinePaths(basePath, "tsconfig.json"), { moduleResolution: ModuleResolutionKind.Node10 }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
if (resolved.resolvedModule) {
return resolved.resolvedModule.resolvedFileName;
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3391,7 +3391,7 @@
"category": "Error",
"code": 2791
},
"Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?": {
"Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?": {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also meant to leave some commentary on this change. This message was written when there were only two module resolution options, and only one worked with non-relative specifiers. Now that there’s node16, nodenext, and bundler, it’s a bit harder to infer what someone on classic should be on instead. I picked nodenext, but we could revisit this message in the future if we need to.

"category": "Error",
"code": 2792
},
Expand Down Expand Up @@ -4121,7 +4121,7 @@
"category": "Error",
"code": 5069
},
"Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.": {
"Option '--resolveJsonModule' cannot be specified when 'moduleResolution' is set to 'classic'.": {
"category": "Error",
"code": 5070
},
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,7 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
if (moduleResolution === undefined) {
switch (getEmitModuleKind(compilerOptions)) {
case ModuleKind.CommonJS:
moduleResolution = ModuleResolutionKind.NodeJs;
moduleResolution = ModuleResolutionKind.Node10;
break;
case ModuleKind.Node16:
moduleResolution = ModuleResolutionKind.Node16;
Expand Down Expand Up @@ -1278,7 +1278,7 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
case ModuleResolutionKind.NodeNext:
result = nodeNextModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode);
break;
case ModuleResolutionKind.NodeJs:
case ModuleResolutionKind.Node10:
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
break;
case ModuleResolutionKind.Classic:
Expand Down Expand Up @@ -1593,7 +1593,7 @@ function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host:
NodeResolutionFeatures.None,
moduleName,
initialDir,
{ moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true },
{ moduleResolution: ModuleResolutionKind.Node10, allowJs: true },
host,
/*cache*/ undefined,
Extensions.JavaScript,
Expand Down Expand Up @@ -1656,7 +1656,7 @@ function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleNa
}

let result;
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs) {
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node10) {
const priorityExtensions = extensions & (Extensions.TypeScript | Extensions.Declaration);
const secondaryExtensions = extensions & ~(Extensions.TypeScript | Extensions.Declaration);
result =
Expand Down
9 changes: 3 additions & 6 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3772,7 +3772,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
i++;
}
const resolveFrom = combinePaths(currentDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`);
const localOverrideModuleResult = resolveModuleName("@typescript/lib-" + path, resolveFrom, { moduleResolution: ModuleResolutionKind.NodeJs }, host, moduleResolutionCache);
const localOverrideModuleResult = resolveModuleName("@typescript/lib-" + path, resolveFrom, { moduleResolution: ModuleResolutionKind.Node10 }, host, moduleResolutionCache);
if (localOverrideModuleResult?.resolvedModule) {
return localOverrideModuleResult.resolvedModule.resolvedFileName;
}
Expand Down Expand Up @@ -4118,11 +4118,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
}

if (getResolveJsonModule(options)) {
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs &&
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 &&
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext &&
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Bundler) {
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Classic) {
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_when_moduleResolution_is_set_to_classic, "resolveJsonModule");
}
// Any emit other than common js, amd, es2015 or esnext is error
else if (!hasJsonModuleEmitEnabled(options)) {
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6887,7 +6887,7 @@ export function diagnosticCategoryName(d: { category: DiagnosticCategory }, lowe

export enum ModuleResolutionKind {
Classic = 1,
NodeJs = 2,
Node10 = 2,
// Starting with node12, node's module resolver has significant departures from traditional cjs resolution
// to better support ecmascript modules and their use within node - however more features are still being added.
// TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable
Expand Down Expand Up @@ -7306,6 +7306,7 @@ export interface CommandLineOptionOfBooleanType extends CommandLineOptionBase {
export interface CommandLineOptionOfCustomType extends CommandLineOptionBase {
type: Map<string, number | string>; // an object literal mapping named values to actual values
defaultValueDescription: number | string | undefined | DiagnosticMessage;
deprecatedKeys?: Set<string>;
}

/** @internal */
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7707,7 +7707,7 @@ export function getEmitModuleResolutionKind(compilerOptions: CompilerOptions) {
if (moduleResolution === undefined) {
switch (getEmitModuleKind(compilerOptions)) {
case ModuleKind.CommonJS:
moduleResolution = ModuleResolutionKind.NodeJs;
moduleResolution = ModuleResolutionKind.Node10;
break;
case ModuleKind.Node16:
moduleResolution = ModuleResolutionKind.Node16;
Expand Down
2 changes: 1 addition & 1 deletion src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ export class Session<TMessage = string> implements EventSender {
// resolved from the package root under --moduleResolution node
const entrypoints = getEntrypointsFromPackageJsonInfo(
packageJson,
{ moduleResolution: ModuleResolutionKind.NodeJs },
{ moduleResolution: ModuleResolutionKind.Node10 },
project,
project.getModuleResolutionCache());
// This substring is correct only because we checked for a single `/node_modules/` at the top.
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/importFixes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ function compareModuleSpecifiers(
function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean {
if (fix.isReExport &&
fix.exportInfo?.moduleFileName &&
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs &&
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node10 &&
isIndexFileName(fix.exportInfo.moduleFileName)
) {
const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName));
Expand Down
2 changes: 1 addition & 1 deletion src/services/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2411,7 +2411,7 @@ export function getModuleSpecifierResolverHost(program: Program, host: LanguageS

/** @internal */
export function moduleResolutionUsesNodeModules(moduleResolution: ModuleResolutionKind): boolean {
return moduleResolution === ModuleResolutionKind.NodeJs || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext;
return moduleResolution === ModuleResolutionKind.Node10 || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext;
}

/** @internal */
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/config/commandLineParsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => {
verifyNullNonIncludedOption({
subScenario: "option of type custom map",
type: () => new Map(ts.getEntries({
node: ts.ModuleResolutionKind.NodeJs,
node: ts.ModuleResolutionKind.Node10,
classic: ts.ModuleResolutionKind.Classic,
})),
nonNullValue: "node"
Expand Down
16 changes: 8 additions & 8 deletions src/testRunner/unittests/moduleResolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
content: '{"version": "0.0.0", "main": "./index"}'
}
);
const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs };
const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.Node10 };
const cache = ts.createModuleResolutionCache("/", (f) => f);
baselines.push(`Resolving "a" from /sub/dir/foo.ts`);
let resolution = ts.resolveModuleName("a", "/sub/dir/foo.ts", compilerOptions, host, cache);
Expand Down Expand Up @@ -365,7 +365,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
{ name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' },
);
const cache = ts.createModuleResolutionCache("/", (f) => f);
const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs };
const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.Node10 };
baselineResolution("/app/src/app.ts");
baselineResolution("/app/lib/main.ts");
runBaseline("non relative preserves originalPath on cache hit", baselines);
Expand Down Expand Up @@ -635,7 +635,7 @@ describe("unittests:: moduleResolution:: baseUrl augmented module resolution", (
const file2: File = { name: "/root/folder2/file2.ts" };
const file3: File = { name: "/root/folder2/file3.ts" };
const host = createModuleResolutionHost(baselines, hasDirectoryExists, file1, file2, file3);
for (const moduleResolution of [ts.ModuleResolutionKind.NodeJs, ts.ModuleResolutionKind.Classic]) {
for (const moduleResolution of [ts.ModuleResolutionKind.Node10, ts.ModuleResolutionKind.Classic]) {
const options: ts.CompilerOptions = { moduleResolution, baseUrl: "/root" };
{
baselines.push(`Resolving "folder2/file2" from ${file1.name}${hasDirectoryExists ? "" : " with host that doesnt have directoryExists"}`);
Expand Down Expand Up @@ -674,7 +674,7 @@ describe("unittests:: moduleResolution:: baseUrl augmented module resolution", (
const m3Typings: File = { name: "/root/m3/dist/typings.d.ts" };
const m4: File = { name: "/root/node_modules/m4.ts" }; // fallback to node

const options: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs, baseUrl: "/root" };
const options: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.Node10, baseUrl: "/root" };
const host = createModuleResolutionHost(baselines, hasDirectoryExists, main, m1, m2, m3, m3Typings, m4);

check("m1", main);
Expand Down Expand Up @@ -736,7 +736,7 @@ describe("unittests:: moduleResolution:: baseUrl augmented module resolution", (
const host = createModuleResolutionHost(baselines, hasDirectoryExists, file1, file2, file3, file4, file4Typings, file5, file6);

const options: ts.CompilerOptions = {
moduleResolution: ts.ModuleResolutionKind.NodeJs,
moduleResolution: ts.ModuleResolutionKind.Node10,
baseUrl: "/root",
jsx: ts.JsxEmit.React,
paths: {
Expand Down Expand Up @@ -827,7 +827,7 @@ describe("unittests:: moduleResolution:: baseUrl augmented module resolution", (
const file3: File = { name: "/root/generated/folder2/file3.ts" };
const host = createModuleResolutionHost(baselines, hasDirectoryExists, file1, file1_1, file2, file3);
const options: ts.CompilerOptions = {
moduleResolution: ts.ModuleResolutionKind.NodeJs,
moduleResolution: ts.ModuleResolutionKind.Node10,
rootDirs: [
"/root",
"/root/generated/"
Expand Down Expand Up @@ -890,7 +890,7 @@ describe("unittests:: moduleResolution:: baseUrl augmented module resolution", (
const libsTypings: File = { name: "/root/src/libs/guid/dist/guid.d.ts" };
const host = createModuleResolutionHost(baselines, hasDirectoryExists, app, libsPackage, libsTypings);
const options: ts.CompilerOptions = {
moduleResolution: ts.ModuleResolutionKind.NodeJs,
moduleResolution: ts.ModuleResolutionKind.Node10,
baseUrl: "/root",
paths: {
"libs/guid": [ "src/libs/guid" ]
Expand All @@ -912,7 +912,7 @@ describe("unittests:: moduleResolution:: ModuleResolutionHost.directoryExists",
directoryExists: _ => false
};

const result = ts.resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host);
const result = ts.resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ts.ModuleResolutionKind.Node10 }, host);
assert(!result.resolvedModule);
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/testRunner/unittests/reuseProgramStructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe("unittests:: Reuse program structure:: General", () => {
{ name: "/node_modules/b/package.json", text: SourceText.New("", "", JSON.stringify({ name: "b", version: "1.2.3" })) },
];

const options: ts.CompilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.NodeJs };
const options: ts.CompilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.Node10 };
const program1 = newProgram(files, ["/a.ts"], options);
const baselines: string[] = [];
baselineProgram(baselines, program1);
Expand Down Expand Up @@ -313,7 +313,7 @@ describe("unittests:: Reuse program structure:: General", () => {
const file1Ts = { name: "file1.ts", text: SourceText.New("", `import * as a from "a";`, "const myX: number = a.x;") };
const file2Ts = { name: "file2.ts", text: SourceText.New("", "", "") };
const indexDTS = { name: "node_modules/a/index.d.ts", text: SourceText.New("", "export declare let x: number;", "") };
const options: ts.CompilerOptions = { target: ts.ScriptTarget.ES2015, traceResolution: true, moduleResolution: ts.ModuleResolutionKind.NodeJs };
const options: ts.CompilerOptions = { target: ts.ScriptTarget.ES2015, traceResolution: true, moduleResolution: ts.ModuleResolutionKind.Node10 };
const rootFiles = [file1Ts, file2Ts];
const filesAfterNpmInstall = [file1Ts, file2Ts, indexDTS];
const initialProgram = newProgram(rootFiles, rootFiles.map(f => f.name), options);
Expand Down Expand Up @@ -425,7 +425,7 @@ describe("unittests:: Reuse program structure:: General", () => {
const bxIndex = "/node_modules/b/node_modules/x/index.d.ts";
const bxPackage = "/node_modules/b/node_modules/x/package.json";
const root = "/a.ts";
const compilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.NodeJs };
const compilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.Node10 };

function createRedirectProgram(useGetSourceFileByPath: boolean, options?: { bText: string, bVersion: string }): ProgramWithSourceTexts {
const files: NamedSourceText[] = [
Expand Down