mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-18 07:29:16 -05:00
When installing unrelated package inside scoped packages dont invalidate resolutions from everything in the scoped package (#53873)
This commit is contained in:
@@ -1889,7 +1889,7 @@ export function pathContainsNodeModules(path: string): boolean {
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function parseNodeModuleFromPath(resolved: string): string | undefined {
|
||||
export function parseNodeModuleFromPath(resolved: string, isFolder?: boolean): string | undefined {
|
||||
const path = normalizePath(resolved);
|
||||
const idx = path.lastIndexOf(nodeModulesPathPart);
|
||||
if (idx === -1) {
|
||||
@@ -1897,16 +1897,16 @@ export function parseNodeModuleFromPath(resolved: string): string | undefined {
|
||||
}
|
||||
|
||||
const indexAfterNodeModules = idx + nodeModulesPathPart.length;
|
||||
let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules);
|
||||
let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules, isFolder);
|
||||
if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) {
|
||||
indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
|
||||
indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName, isFolder);
|
||||
}
|
||||
return path.slice(0, indexAfterPackageName);
|
||||
}
|
||||
|
||||
function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number {
|
||||
function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number, isFolder: boolean | undefined): number {
|
||||
const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1);
|
||||
return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
|
||||
return nextSeparatorIndex === -1 ? isFolder ? path.length : prevSeparatorIndex : nextSeparatorIndex;
|
||||
}
|
||||
|
||||
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
@@ -1152,7 +1152,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
// If the invalidated file is from a node_modules package, invalidate everything else
|
||||
// in the package since we might not get notifications for other files in the package.
|
||||
// This hardens our logic against unreliable file watchers.
|
||||
const packagePath = parseNodeModuleFromPath(fileOrDirectoryPath);
|
||||
const packagePath = parseNodeModuleFromPath(fileOrDirectoryPath, /*isFolder*/ true);
|
||||
if (packagePath) (startsWithPathChecks ||= new Set()).add(packagePath as Path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as Utils from "../../_namespaces/Utils";
|
||||
import { libContent } from "../tsc/helpers";
|
||||
import {
|
||||
createWatchedSystem,
|
||||
File,
|
||||
@@ -621,4 +622,64 @@ declare namespace NodeJS {
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
verifyTscWatch({
|
||||
scenario,
|
||||
subScenario: "scoped package installation",
|
||||
commandLineArgs: ["--w", "-p", `.`, "--traceResolution", "--extendedDiagnostics"],
|
||||
sys: () => createWatchedSystem({
|
||||
"/user/username/projects/myproject/lib/app.ts": Utils.dedent`
|
||||
import { myapp } from "@myapp/ts-types";
|
||||
const x: 10 = myapp;
|
||||
`,
|
||||
"/user/username/projects/myproject/tsconfig.json": "{}",
|
||||
[libFile.path]: libContent,
|
||||
}, { currentDirectory: "/user/username/projects/myproject" }),
|
||||
edits: [
|
||||
{
|
||||
caption: "npm install unrelated non scoped",
|
||||
edit: sys => sys.ensureFileOrFolder({
|
||||
path: `/user/username/projects/myproject/node_modules/unrelated/index.d.ts`,
|
||||
content: `export const unrelated = 10;`
|
||||
}),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
},
|
||||
},
|
||||
{
|
||||
caption: "npm install unrelated scoped in myapp",
|
||||
edit: sys => sys.ensureFileOrFolder({
|
||||
path: `/user/username/projects/myproject/node_modules/@myapp/unrelated/index.d.ts`,
|
||||
content: `export const myappUnrelated = 10;`
|
||||
}),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
},
|
||||
},
|
||||
{
|
||||
caption: "npm install unrelated2 scoped in myapp",
|
||||
edit: sys => sys.ensureFileOrFolder({
|
||||
path: `/user/username/projects/myproject/node_modules/@myapp/unrelated2/index.d.ts`,
|
||||
content: `export const myappUnrelated2 = 10;`
|
||||
}),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
},
|
||||
},
|
||||
{
|
||||
caption: "npm install ts-types",
|
||||
edit: sys => sys.ensureFileOrFolder({
|
||||
path: `/user/username/projects/myproject/node_modules/@myapp/ts-types/index.d.ts`,
|
||||
content: `export const myapp = 10;`
|
||||
}),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
},
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user