Skip to content

Commit 5597f7f

Browse files
clydinvikerman
authored andcommitted
refactor(@angular-devkit/build-angular): allow control of cache location
`NG_BUILD_CACHE` can specify an absolute path to be used as the cache location. Caching can also be disabled by setting the variable to 0 or false.
1 parent 5260bbb commit 5597f7f

File tree

8 files changed

+79
-35
lines changed

8 files changed

+79
-35
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import {
2626
import { RawSource } from 'webpack-sources';
2727
import { AssetPatternClass, ExtraEntryPoint } from '../../../browser/schema';
2828
import { BuildBrowserFeatures } from '../../../utils';
29-
import { manglingDisabled } from '../../../utils/mangle-options';
29+
import { findCachePath } from '../../../utils/cache-path';
30+
import { cachingDisabled, manglingDisabled } from '../../../utils/environment-options';
3031
import { BundleBudgetPlugin } from '../../plugins/bundle-budget';
3132
import { CleanCssWebpackPlugin } from '../../plugins/cleancss-webpack-plugin';
3233
import { NamedLazyChunksPlugin } from '../../plugins/named-chunks-plugin';
@@ -411,7 +412,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
411412
new TerserPlugin({
412413
sourceMap: scriptsSourceMap,
413414
parallel: true,
414-
cache: true,
415+
cache: !cachingDisabled && findCachePath('terser-webpack'),
415416
extractComments: false,
416417
chunkFilter: (chunk: compilation.Chunk) =>
417418
!globalScriptsByBundleName.some(s => s.bundleName === chunk.name),
@@ -422,7 +423,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
422423
new TerserPlugin({
423424
sourceMap: scriptsSourceMap,
424425
parallel: true,
425-
cache: true,
426+
cache: !cachingDisabled && findCachePath('terser-webpack'),
426427
extractComments: false,
427428
chunkFilter: (chunk: compilation.Chunk) =>
428429
globalScriptsByBundleName.some(s => s.bundleName === chunk.name),

packages/angular_devkit/build_angular/src/browser/action-cache.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { createHash } from 'crypto';
9-
import * as findCacheDirectory from 'find-cache-dir';
109
import * as fs from 'fs';
1110
import { copyFile } from '../utils/copy-file';
12-
import { manglingDisabled } from '../utils/mangle-options';
11+
import { manglingDisabled } from '../utils/environment-options';
1312
import { CacheKey, ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
1413

1514
const cacache = require('cacache');
16-
const cacheDownlevelPath = findCacheDirectory({ name: 'angular-build-dl' });
1715
const packageVersion = require('../../package.json').version;
1816

1917
export interface CacheEntry {
@@ -23,7 +21,7 @@ export interface CacheEntry {
2321
}
2422

2523
export class BundleActionCache {
26-
constructor(private readonly integrityAlgorithm?: string) {}
24+
constructor(private readonly cachePath: string, private readonly integrityAlgorithm?: string) {}
2725

2826
static copyEntryContent(entry: CacheEntry | string, dest: fs.PathLike): void {
2927
copyFile(typeof entry === 'string' ? entry : entry.path, dest);
@@ -88,7 +86,7 @@ export class BundleActionCache {
8886
const cacheEntries = [];
8987
for (const key of cacheKeys) {
9088
if (key) {
91-
const entry = await cacache.get.info(cacheDownlevelPath, key);
89+
const entry = await cacache.get.info(this.cachePath, key);
9290
if (!entry) {
9391
return false;
9492
}

packages/angular_devkit/build_angular/src/browser/action-executor.ts

+19-14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import JestWorker from 'jest-worker';
99
import * as os from 'os';
1010
import * as path from 'path';
1111
import * as v8 from 'v8';
12+
import { I18nOptions } from '../utils/i18n-options';
1213
import { InlineOptions, ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
1314
import { BundleActionCache } from './action-cache';
1415

@@ -36,14 +37,16 @@ workerFile =
3637
export class BundleActionExecutor {
3738
private largeWorker?: JestWorker;
3839
private smallWorker?: JestWorker;
39-
private cache: BundleActionCache;
40+
private cache?: BundleActionCache;
4041

4142
constructor(
42-
private workerOptions: unknown,
43+
private workerOptions: { cachePath?: string; i18n: I18nOptions },
4344
integrityAlgorithm?: string,
4445
private readonly sizeThreshold = 32 * 1024,
4546
) {
46-
this.cache = new BundleActionCache(integrityAlgorithm);
47+
if (workerOptions.cachePath) {
48+
this.cache = new BundleActionCache(workerOptions.cachePath, integrityAlgorithm);
49+
}
4750
}
4851

4952
private static executeMethod<O>(worker: JestWorker, method: string, input: unknown): Promise<O> {
@@ -87,16 +90,18 @@ export class BundleActionExecutor {
8790
}
8891

8992
async process(action: ProcessBundleOptions): Promise<ProcessBundleResult> {
90-
const cacheKeys = this.cache.generateCacheKeys(action);
91-
action.cacheKeys = cacheKeys;
92-
93-
// Try to get cached data, if it fails fallback to processing
94-
try {
95-
const cachedResult = await this.cache.getCachedBundleResult(action);
96-
if (cachedResult) {
97-
return cachedResult;
98-
}
99-
} catch {}
93+
if (this.cache) {
94+
const cacheKeys = this.cache.generateCacheKeys(action);
95+
action.cacheKeys = cacheKeys;
96+
97+
// Try to get cached data, if it fails fallback to processing
98+
try {
99+
const cachedResult = await this.cache.getCachedBundleResult(action);
100+
if (cachedResult) {
101+
return cachedResult;
102+
}
103+
} catch {}
104+
}
100105

101106
return this.executeAction<ProcessBundleResult>('process', action);
102107
}
@@ -107,7 +112,7 @@ export class BundleActionExecutor {
107112

108113
async inline(
109114
action: InlineOptions,
110-
): Promise<{ file: string; diagnostics: { type: string; message: string }[]; count: number; }> {
115+
): Promise<{ file: string; diagnostics: { type: string; message: string }[]; count: number }> {
111116
return this.executeAction('inlineLocales', action);
112117
}
113118

packages/angular_devkit/build_angular/src/browser/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/ar
99
import { EmittedFiles, WebpackLoggingCallback, runWebpack } from '@angular-devkit/build-webpack';
1010
import { join, json, logging, normalize, tags, virtualFs } from '@angular-devkit/core';
1111
import { NodeJsSyncHost } from '@angular-devkit/core/node';
12-
import * as findCacheDirectory from 'find-cache-dir';
1312
import * as fs from 'fs';
1413
import * as os from 'os';
1514
import * as path from 'path';
@@ -50,7 +49,9 @@ import {
5049
normalizeOptimization,
5150
normalizeSourceMaps,
5251
} from '../utils';
52+
import { findCachePath } from '../utils/cache-path';
5353
import { copyAssets } from '../utils/copy-assets';
54+
import { cachingDisabled } from '../utils/environment-options';
5455
import { emittedFilesToInlineOptions } from '../utils/i18n-inlining';
5556
import { I18nOptions, createI18nOptions, mergeDeprecatedI18nOptions } from '../utils/i18n-options';
5657
import { createTranslationLoader } from '../utils/load-translations';
@@ -69,7 +70,7 @@ import {
6970
import { BundleActionExecutor } from './action-executor';
7071
import { Schema as BrowserBuilderSchema } from './schema';
7172

72-
const cacheDownlevelPath = findCacheDirectory({ name: 'angular-build-dl' });
73+
const cacheDownlevelPath = cachingDisabled ? undefined : findCachePath('angular-build-dl');
7374

7475
export type BrowserBuilderOutput = json.JsonObject &
7576
BuilderOutput & {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import * as findCacheDirectory from 'find-cache-dir';
9+
import { tmpdir } from 'os';
10+
import { resolve } from 'path';
11+
import { cachingBasePath } from './environment-options';
12+
13+
export function findCachePath(name: string): string {
14+
if (cachingBasePath) {
15+
return resolve(cachingBasePath, name);
16+
}
17+
18+
return findCacheDirectory({ name }) || tmpdir();
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import * as path from 'path';
9+
10+
const mangleVariable = process.env['NG_BUILD_MANGLE'];
11+
export const manglingDisabled =
12+
!!mangleVariable && (mangleVariable === '0' || mangleVariable.toLowerCase() === 'false');
13+
14+
const cacheVariable = process.env['NG_BUILD_CACHE'];
15+
export const cachingDisabled =
16+
!!cacheVariable && (cacheVariable === '0' || cacheVariable.toLowerCase() === 'false');
17+
export const cachingBasePath = (() => {
18+
if (
19+
cachingDisabled ||
20+
!cacheVariable ||
21+
(cacheVariable === '1' || cacheVariable.toLowerCase() === 'true')
22+
) {
23+
return null;
24+
}
25+
if (!path.isAbsolute(cacheVariable)) {
26+
throw new Error('NG_BUILD_CACHE path value must be absolute.');
27+
}
28+
29+
return cacheVariable;
30+
})();

packages/angular_devkit/build_angular/src/utils/mangle-options.ts

-10
This file was deleted.

packages/angular_devkit/build_angular/src/utils/process-bundle.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { RawSourceMap, SourceMapConsumer, SourceMapGenerator } from 'source-map'
1313
import { minify } from 'terser';
1414
import * as v8 from 'v8';
1515
import { SourceMapSource } from 'webpack-sources';
16+
import { manglingDisabled } from './environment-options';
1617
import { I18nOptions } from './i18n-options';
17-
import { manglingDisabled } from './mangle-options';
1818

1919
const cacache = require('cacache');
2020
const deserialize = ((v8 as unknown) as { deserialize(buffer: Buffer): unknown }).deserialize;

0 commit comments

Comments
 (0)