Skip to content

Commit 7f7bb99

Browse files
committed
fixup! fix(@angular/build): scope BundlerContext invalidation and cache one-shot bundle results
1 parent 72cc982 commit 7f7bb99

2 files changed

Lines changed: 24 additions & 60 deletions

File tree

‎packages/angular/build/src/tools/esbuild/bundler-context.ts‎

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class BundlerContext {
8181
#optionsFactory: BundlerOptionsFactory<BuildOptions & { metafile: true; write: false }>;
8282
#shouldCacheResult: boolean;
8383
#loadCache?: LoadResultCache;
84-
readonly #loadCacheKeys = new Set<string>();
84+
#loadCacheKeys?: Set<string>;
8585
#invalidationEpoch = 0;
8686
readonly watchFiles = new Set<string>();
8787

@@ -94,9 +94,8 @@ export class BundlerContext {
9494
sharedLoadCache?: LoadResultCache,
9595
) {
9696
this.#loadCache = sharedLoadCache;
97-
// In incremental mode, an option factory is needed to capture the full set of dependencies.
98-
// In non-incremental mode, results can always be cached for the duration of the build.
99-
this.#shouldCacheResult = !incremental || typeof options === 'function';
97+
// To cache the results an option factory is needed to capture the full set of dependencies
98+
this.#shouldCacheResult = incremental && typeof options === 'function';
10099
this.#optionsFactory = (...args) => {
101100
const baseOptions = typeof options === 'function' ? options(...args) : options;
102101

@@ -230,22 +229,25 @@ export class BundlerContext {
230229
this.#loadCache = new MemoryLoadResultCache();
231230
}
232231
const loadCache = this.#loadCache;
233-
const scopedLoadCache: LoadResultCache | undefined = loadCache && {
234-
get: (path) => {
235-
this.#loadCacheKeys.add(path);
236-
237-
return loadCache.get(path);
238-
},
239-
put: (path, result) => {
240-
this.#loadCacheKeys.add(path);
241-
242-
return loadCache.put(path, result);
243-
},
244-
invalidate: (path) => loadCache.invalidate(path),
245-
get watchFiles() {
246-
return loadCache.watchFiles;
247-
},
248-
};
232+
const scopedLoadCache: LoadResultCache | undefined =
233+
this.incremental && loadCache
234+
? {
235+
get: (path) => {
236+
(this.#loadCacheKeys ??= new Set()).add(path);
237+
238+
return loadCache.get(path);
239+
},
240+
put: (path, result) => {
241+
(this.#loadCacheKeys ??= new Set()).add(path);
242+
243+
return loadCache.put(path, result);
244+
},
245+
invalidate: (path) => loadCache.invalidate(path),
246+
get watchFiles() {
247+
return loadCache.watchFiles;
248+
},
249+
}
250+
: loadCache;
249251
this.#esbuildOptions = this.#optionsFactory(scopedLoadCache);
250252
}
251253

@@ -476,7 +478,7 @@ export class BundlerContext {
476478
}
477479

478480
async #addLoadCacheFilesToWatch(): Promise<void> {
479-
if (this.incremental && this.#loadCache) {
481+
if (this.incremental && this.#loadCache && this.#loadCacheKeys) {
480482
for (const key of this.#loadCacheKeys) {
481483
const cachedResult = await this.#loadCache.get(key);
482484
if (cachedResult?.watchFiles) {
@@ -585,7 +587,7 @@ export class BundlerContext {
585587
this.#esbuildResult = undefined;
586588
this.#activeBundlePromise = undefined;
587589
this.#loadCache = undefined;
588-
this.#loadCacheKeys.clear();
590+
this.#loadCacheKeys = undefined;
589591
await this.#esbuildContext?.dispose();
590592
} finally {
591593
this.#esbuildContext = undefined;

‎packages/angular/build/src/tools/esbuild/bundler-context_spec.ts‎

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -222,43 +222,5 @@ describe('BundlerContext', () => {
222222
expect(recoveredResult.outputFiles[0].text).toContain('purple');
223223
}
224224
});
225-
226-
it('should reuse cached result when calling bundle() twice on a non-incremental context', async () => {
227-
const workspaceDir = await mkdtemp(join(tempRoot, 'non-incremental-cache-'));
228-
const stylePath = join(workspaceDir, 'shared.css');
229-
await writeFile(stylePath, '.shared { color: orange; }');
230-
231-
let loadCount = 0;
232-
const context = new BundlerContext(
233-
workspaceDir,
234-
/* incremental */ false,
235-
() => ({
236-
absWorkingDir: workspaceDir,
237-
bundle: true,
238-
entryPoints: [stylePath],
239-
outdir: workspaceDir,
240-
plugins: [
241-
{
242-
name: 'count-loads',
243-
setup(build) {
244-
build.onLoad({ filter: /\.css$/ }, async () => {
245-
loadCount++;
246-
247-
return null;
248-
});
249-
},
250-
},
251-
],
252-
}),
253-
/* useContext */ false,
254-
);
255-
256-
const firstResult = await context.bundle();
257-
const secondResult = await context.bundle();
258-
259-
expect(firstResult.errors).toBeUndefined();
260-
expect(secondResult).toBe(firstResult);
261-
expect(loadCount).toBe(1);
262-
});
263225
});
264226
});

0 commit comments

Comments
 (0)