




























@@ -76,12 +76,26 @@ const BUNDLED_RUNTIME_MIRROR_PLUGIN_REGION_RE = /(?:^|\n)\/\/#region extensions\
7676const BUNDLED_RUNTIME_MIRROR_IMPORT_SPECIFIER_RE =
7777/(?:^|[;\n])\s*(?:import|export)\s+(?:[^'"()]+?\s+from\s+)?["']([^"']+)["']|\bimport\(\s*["']([^"']+)["']\s*\)|\brequire\(\s*["']([^"']+)["']\s*\)/g;
7878const NPM_EXECPATH_ENV_KEY = "npm_execpath";
79+const MAX_RUNTIME_DEPS_FILE_CACHE_ENTRIES = 2048;
79808081const registeredBundledRuntimeDepNodePaths = new Set<string>();
8182const bundledRuntimeMirrorMaterializeCache = new Map<
8283string,
8384{ signature: string; materialize: boolean }
8485>();
86+const runtimeDepsTextFileCache = new Map<string, { signature: string; value: string }>();
87+const runtimeDepsJsonObjectCache = new Map<
88+string,
89+{ signature: string; value: JsonObject | null }
90+>();
91+const runtimeDepsImportSpecifierCache = new Map<
92+string,
93+{ signature: string; value: readonly string[] }
94+>();
95+const runtimeMirrorMaterializeImportSpecifierCache = new Map<
96+string,
97+{ signature: string; value: readonly string[] }
98+>();
859986100export type BundledRuntimeDepsNpmRunner = {
87101command: string;
@@ -98,17 +112,19 @@ function statSignature(stat: Pick<fs.Stats, "dev" | "ino" | "size" | "mtimeMs">)
98112}
99113100114function computeBundledRuntimeMirrorDistFileMaterialization(sourcePath: string): boolean {
101-let source: string;
102-try {
103-source = fs.readFileSync(sourcePath, "utf8");
104-} catch {
115+const signature = getRuntimeDepsFileSignature(sourcePath);
116+const source = readRuntimeDepsTextFile(sourcePath, signature);
117+if (source === null) {
105118return false;
106119}
107120if (BUNDLED_RUNTIME_MIRROR_PLUGIN_REGION_RE.test(source)) {
108121return true;
109122}
110-for (const match of source.matchAll(BUNDLED_RUNTIME_MIRROR_IMPORT_SPECIFIER_RE)) {
111-const specifier = match[1] ?? match[2] ?? match[3] ?? "";
123+for (const specifier of readRuntimeMirrorMaterializeImportSpecifiers(
124+sourcePath,
125+signature,
126+source,
127+)) {
112128if (
113129specifier !== "" &&
114130!specifier.startsWith(".") &&
@@ -279,17 +295,132 @@ function readInstalledDependencyVersion(rootDir: string, depName: string): strin
279295}
280296281297function readJsonObject(filePath: string): JsonObject | null {
298+const signature = getRuntimeDepsFileSignature(filePath);
299+const cached = signature ? runtimeDepsJsonObjectCache.get(filePath) : undefined;
300+if (cached?.signature === signature) {
301+return cached.value;
302+}
303+const source = readRuntimeDepsTextFile(filePath, signature);
304+if (source === null) {
305+cacheRuntimeDepsJsonObject(filePath, signature, null);
306+return null;
307+}
282308try {
283-const parsed = JSON.parse(fs.readFileSync(filePath, "utf8")) as unknown;
309+const parsed = JSON.parse(source) as unknown;
284310if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
311+cacheRuntimeDepsJsonObject(filePath, signature, null);
285312return null;
286313}
287-return parsed as JsonObject;
314+const value = parsed as JsonObject;
315+cacheRuntimeDepsJsonObject(filePath, signature, value);
316+return value;
317+} catch {
318+cacheRuntimeDepsJsonObject(filePath, signature, null);
319+return null;
320+}
321+}
322+323+function readRuntimeDepsTextFile(filePath: string, signature?: string | null): string | null {
324+const fileSignature = signature ?? getRuntimeDepsFileSignature(filePath);
325+const cached = fileSignature ? runtimeDepsTextFileCache.get(filePath) : undefined;
326+if (cached?.signature === fileSignature) {
327+return cached.value;
328+}
329+try {
330+const value = fs.readFileSync(filePath, "utf8");
331+if (fileSignature) {
332+rememberRuntimeDepsCacheEntry(runtimeDepsTextFileCache, filePath, {
333+signature: fileSignature,
334+ value,
335+});
336+}
337+return value;
288338} catch {
289339return null;
290340}
291341}
292342343+function readRuntimeDepsImportSpecifiers(
344+filePath: string,
345+signature: string | null,
346+source: string,
347+): readonly string[] {
348+const cached = signature ? runtimeDepsImportSpecifierCache.get(filePath) : undefined;
349+if (cached?.signature === signature) {
350+return cached.value;
351+}
352+const value = extractStaticRuntimeImportSpecifiers(source);
353+if (signature) {
354+rememberRuntimeDepsCacheEntry(runtimeDepsImportSpecifierCache, filePath, { signature, value });
355+}
356+return value;
357+}
358+359+function readRuntimeMirrorMaterializeImportSpecifiers(
360+filePath: string,
361+signature: string | null,
362+source: string,
363+): readonly string[] {
364+const cached = signature ? runtimeMirrorMaterializeImportSpecifierCache.get(filePath) : undefined;
365+if (cached?.signature === signature) {
366+return cached.value;
367+}
368+const value = extractRuntimeMirrorMaterializeImportSpecifiers(source);
369+if (signature) {
370+rememberRuntimeDepsCacheEntry(runtimeMirrorMaterializeImportSpecifierCache, filePath, {
371+ signature,
372+ value,
373+});
374+}
375+return value;
376+}
377+378+function extractRuntimeMirrorMaterializeImportSpecifiers(source: string): string[] {
379+const specifiers = new Set<string>();
380+for (const match of source.matchAll(BUNDLED_RUNTIME_MIRROR_IMPORT_SPECIFIER_RE)) {
381+const specifier = match[1] ?? match[2] ?? match[3];
382+if (specifier) {
383+specifiers.add(specifier);
384+}
385+}
386+return [...specifiers];
387+}
388+389+function getRuntimeDepsFileSignature(filePath: string): string | null {
390+try {
391+const stat = fs.statSync(filePath, { bigint: true });
392+if (!stat.isFile()) {
393+return null;
394+}
395+return [
396+stat.dev.toString(),
397+stat.ino.toString(),
398+stat.size.toString(),
399+stat.mtimeNs.toString(),
400+].join(":");
401+} catch {
402+return null;
403+}
404+}
405+406+function cacheRuntimeDepsJsonObject(
407+filePath: string,
408+signature: string | null,
409+value: JsonObject | null,
410+): void {
411+if (!signature) {
412+return;
413+}
414+rememberRuntimeDepsCacheEntry(runtimeDepsJsonObjectCache, filePath, { signature, value });
415+}
416+417+function rememberRuntimeDepsCacheEntry<T>(cache: Map<string, T>, key: string, value: T): void {
418+if (cache.size >= MAX_RUNTIME_DEPS_FILE_CACHE_ENTRIES && !cache.has(key)) {
419+cache.delete(cache.keys().next().value as string);
420+}
421+cache.set(key, value);
422+}
423+293424function sleepSync(ms: number): void {
294425Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
295426}
@@ -686,9 +817,13 @@ function collectRootDistMirroredRuntimeDeps(params: {
686817rootDir: distDir,
687818skipTopLevelDirs: new Set(["extensions"]),
688819})) {
689-const source = fs.readFileSync(filePath, "utf8");
820+const signature = getRuntimeDepsFileSignature(filePath);
821+const source = readRuntimeDepsTextFile(filePath, signature);
822+if (source === null) {
823+continue;
824+}
690825const relativePath = path.relative(distDir, filePath).replaceAll(path.sep, "/");
691-for (const specifier of extractStaticRuntimeImportSpecifiers(source)) {
826+for (const specifier of readRuntimeDepsImportSpecifiers(filePath, signature, source)) {
692827const dependencyName = packageNameFromSpecifier(specifier);
693828if (!dependencyName) {
694829continue;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。