From 385db449f5395ab4d8f24c5f531e85aebbe228c7 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 10 Jan 2024 10:15:58 -0800 Subject: [PATCH] With `allowJs`, process JS files found searching node_modules when they have a realpath outside node_modules (#56946) --- src/compiler/program.ts | 3 +- .../allowJsCrossMonorepoPackage.symbols | 22 +++ .../allowJsCrossMonorepoPackage.trace.json | 159 ++++++++++++++++++ .../allowJsCrossMonorepoPackage.types | 23 +++ .../compiler/allowJsCrossMonorepoPackage.ts | 44 +++++ 5 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/allowJsCrossMonorepoPackage.symbols create mode 100644 tests/baselines/reference/allowJsCrossMonorepoPackage.trace.json create mode 100644 tests/baselines/reference/allowJsCrossMonorepoPackage.types create mode 100644 tests/cases/compiler/allowJsCrossMonorepoPackage.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 067b66dca57..6dd6cb6de43 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -254,6 +254,7 @@ import { parseJsonSourceFileConfigFileContent, parseNodeFactory, Path, + pathContainsNodeModules, pathIsAbsolute, pathIsRelative, Program, @@ -4039,7 +4040,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg const isFromNodeModulesSearch = resolution.isExternalLibraryImport; const isJsFile = !resolutionExtensionIsTSOrJson(resolution.extension); - const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; + const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile && (!resolution.originalPath || pathContainsNodeModules(resolution.resolvedFileName)); const resolvedFileName = resolution.resolvedFileName; if (isFromNodeModulesSearch) { diff --git a/tests/baselines/reference/allowJsCrossMonorepoPackage.symbols b/tests/baselines/reference/allowJsCrossMonorepoPackage.symbols new file mode 100644 index 00000000000..dbdc37a135b --- /dev/null +++ b/tests/baselines/reference/allowJsCrossMonorepoPackage.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/allowJsCrossMonorepoPackage.ts] //// + +=== /packages/main/index.ts === +import { x } from "shared"; +>x : Symbol(x, Decl(index.ts, 0, 8)) + +=== /node_modules/pkg/index.d.ts === +export declare function pkg(): "pkg"; +>pkg : Symbol(pkg, Decl(index.d.ts, 0, 0)) + +=== /packages/shared/utils.js === +export { pkg } from "pkg"; +>pkg : Symbol(pkg, Decl(utils.js, 0, 8)) + +=== /packages/shared/index.js === +import { pkg } from "./utils.js"; +>pkg : Symbol(pkg, Decl(index.js, 0, 8)) + +export const x = pkg(); +>x : Symbol(x, Decl(index.js, 1, 12)) +>pkg : Symbol(pkg, Decl(index.js, 0, 8)) + diff --git a/tests/baselines/reference/allowJsCrossMonorepoPackage.trace.json b/tests/baselines/reference/allowJsCrossMonorepoPackage.trace.json new file mode 100644 index 00000000000..17b86da7c4b --- /dev/null +++ b/tests/baselines/reference/allowJsCrossMonorepoPackage.trace.json @@ -0,0 +1,159 @@ +[ + "======== Resolving module 'shared' from '/packages/main/index.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Resolving in CJS mode with conditions 'import', 'types'.", + "Found 'package.json' at '/packages/main/package.json'.", + "Loading module 'shared' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Found 'package.json' at '/packages/main/node_modules/shared/package.json'.", + "Using 'exports' subpath '.' with target './index.js'.", + "File name '/packages/main/node_modules/shared/index.js' has a '.js' extension - stripping it.", + "File '/packages/main/node_modules/shared/index.ts' does not exist.", + "File '/packages/main/node_modules/shared/index.tsx' does not exist.", + "File '/packages/main/node_modules/shared/index.d.ts' does not exist.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "File '/node_modules/shared.ts' does not exist.", + "File '/node_modules/shared.tsx' does not exist.", + "File '/node_modules/shared.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript, JSON.", + "File '/packages/main/node_modules/shared/package.json' exists according to earlier cached lookups.", + "Using 'exports' subpath '.' with target './index.js'.", + "File name '/packages/main/node_modules/shared/index.js' has a '.js' extension - stripping it.", + "File '/packages/main/node_modules/shared/index.js' exists - use it as a name resolution result.", + "Resolution of non-relative name failed; trying with modern Node resolution features disabled to see if npm library needs configuration update.", + "File '/packages/main/package.json' exists according to earlier cached lookups.", + "Loading module 'shared' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "File '/packages/main/node_modules/shared/package.json' exists according to earlier cached lookups.", + "File '/packages/main/node_modules/shared.ts' does not exist.", + "File '/packages/main/node_modules/shared.tsx' does not exist.", + "File '/packages/main/node_modules/shared.d.ts' does not exist.", + "'package.json' does not have a 'typesVersions' field.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' does not have a 'main' field.", + "File '/packages/main/node_modules/shared/index.ts' does not exist.", + "File '/packages/main/node_modules/shared/index.tsx' does not exist.", + "File '/packages/main/node_modules/shared/index.d.ts' does not exist.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "File '/node_modules/shared.ts' does not exist.", + "File '/node_modules/shared.tsx' does not exist.", + "File '/node_modules/shared.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Resolving real path for '/packages/main/node_modules/shared/index.js', result '/packages/shared/index.js'.", + "======== Module name 'shared' was successfully resolved to '/packages/shared/index.js' with Package ID 'shared/index.js@1.0.0'. ========", + "======== Resolving module './utils.js' from '/packages/shared/index.js'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Resolving in CJS mode with conditions 'import', 'types'.", + "Loading module as file / folder, candidate module location '/packages/shared/utils.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/packages/shared/utils.js' has a '.js' extension - stripping it.", + "File '/packages/shared/utils.ts' does not exist.", + "File '/packages/shared/utils.tsx' does not exist.", + "File '/packages/shared/utils.d.ts' does not exist.", + "File '/packages/shared/utils.js' exists - use it as a name resolution result.", + "======== Module name './utils.js' was successfully resolved to '/packages/shared/utils.js'. ========", + "======== Resolving module 'pkg' from '/packages/shared/utils.js'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Resolving in CJS mode with conditions 'import', 'types'.", + "Found 'package.json' at '/packages/shared/package.json'.", + "Loading module 'pkg' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/shared/node_modules' does not exist, skipping all lookups in it.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "File '/node_modules/pkg/package.json' does not exist.", + "File '/node_modules/pkg.ts' does not exist.", + "File '/node_modules/pkg.tsx' does not exist.", + "File '/node_modules/pkg.d.ts' does not exist.", + "File '/node_modules/pkg/index.ts' does not exist.", + "File '/node_modules/pkg/index.tsx' does not exist.", + "File '/node_modules/pkg/index.d.ts' exists - use it as a name resolution result.", + "Resolving real path for '/node_modules/pkg/index.d.ts', result '/node_modules/pkg/index.d.ts'.", + "======== Module name 'pkg' was successfully resolved to '/node_modules/pkg/index.d.ts'. ========", + "======== Resolving module '@typescript/lib-es5' from '/packages/main/__lib_node_modules_lookup_lib.es5.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-es5'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-es5'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-es5'", + "Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-es5' was not resolved. ========", + "======== Resolving module '@typescript/lib-decorators' from '/packages/main/__lib_node_modules_lookup_lib.decorators.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators'", + "Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-decorators' was not resolved. ========", + "======== Resolving module '@typescript/lib-decorators/legacy' from '/packages/main/__lib_node_modules_lookup_lib.decorators.legacy.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators/legacy'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators/legacy'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators/legacy'", + "Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-decorators/legacy' was not resolved. ========", + "======== Resolving module '@typescript/lib-dom' from '/packages/main/__lib_node_modules_lookup_lib.dom.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-dom'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-dom'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-dom'", + "Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-dom' was not resolved. ========", + "======== Resolving module '@typescript/lib-webworker/importscripts' from '/packages/main/__lib_node_modules_lookup_lib.webworker.importscripts.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-webworker/importscripts'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-webworker/importscripts'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-webworker/importscripts'", + "Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-webworker/importscripts' was not resolved. ========", + "======== Resolving module '@typescript/lib-scripthost' from '/packages/main/__lib_node_modules_lookup_lib.scripthost.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/packages/main/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-scripthost'", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-scripthost'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-scripthost'", + "Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/packages/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-scripthost' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/allowJsCrossMonorepoPackage.types b/tests/baselines/reference/allowJsCrossMonorepoPackage.types new file mode 100644 index 00000000000..8a0ecbf1036 --- /dev/null +++ b/tests/baselines/reference/allowJsCrossMonorepoPackage.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/allowJsCrossMonorepoPackage.ts] //// + +=== /packages/main/index.ts === +import { x } from "shared"; +>x : "pkg" + +=== /node_modules/pkg/index.d.ts === +export declare function pkg(): "pkg"; +>pkg : () => "pkg" + +=== /packages/shared/utils.js === +export { pkg } from "pkg"; +>pkg : () => "pkg" + +=== /packages/shared/index.js === +import { pkg } from "./utils.js"; +>pkg : () => "pkg" + +export const x = pkg(); +>x : "pkg" +>pkg() : "pkg" +>pkg : () => "pkg" + diff --git a/tests/cases/compiler/allowJsCrossMonorepoPackage.ts b/tests/cases/compiler/allowJsCrossMonorepoPackage.ts new file mode 100644 index 00000000000..2af955d311d --- /dev/null +++ b/tests/cases/compiler/allowJsCrossMonorepoPackage.ts @@ -0,0 +1,44 @@ +// @Filename: /node_modules/pkg/index.d.ts +export declare function pkg(): "pkg"; + +// @Filename: /packages/shared/package.json +{ + "name": "shared", + "version": "1.0.0", + "type": "module", + "exports": "./index.js" +} + +// @Filename: /packages/shared/utils.js +export { pkg } from "pkg"; + +// @Filename: /packages/shared/index.js +import { pkg } from "./utils.js"; +export const x = pkg(); + +// @Filename: /packages/main/package.json +{ + "name": "main", + "version": "1.0.0", + "type": "module", + "dependencies": { + "shared": "workspace:*" + } +} + +// @Filename: /packages/main/tsconfig.json +{ + "compilerOptions": { + "noEmit": true, + "checkJs": true, + "strict": true, + "module": "esnext", + "moduleResolution": "bundler", + "traceResolution": true, + } +} + +// @link: /packages/shared -> /packages/main/node_modules/shared + +// @Filename: /packages/main/index.ts +import { x } from "shared";