Skip to content

Commit 5904afd

Browse files
alan-agius4filipesilva
authored andcommitted
feat(@angular-devkit/build-angular): enable disk cache by default and provide configurable options
Persistent disk build cache is now enabled by default. A number of options have been added to allow fine tuning of the cache. The options can be configuration in `cli.cache` section in the `angular.json` as shown below. - `enabled`: Configure whether disk caching is enabled. Defaults to `true` - `environment`: Configure in which environment disk cache is enabled. Valid values `ci`, `local` or `all`. Defaults to: `local` - `path`: cache base path. Defaults to `.angular/cache` DEPRECATED: `NG_BUILD_CACHE` environment variable option will be removed in the next major version. Configure `cli.cache` in the workspace configuration instead. BREAKING CHANGE: `NG_PERSISTENT_BUILD_CACHE` environment variable option no longer have effect. Configure `cli.cache` in the workspace configuration instead. ```json { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "cache": { "enabled": true, "path": ".custom-cache-path", "environment": "all" } } ... } ```
1 parent 09e0395 commit 5904afd

File tree

20 files changed

+281
-128
lines changed

20 files changed

+281
-128
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@
100100
"@types/copy-webpack-plugin": "^8.0.0",
101101
"@types/debug": "^4.1.2",
102102
"@types/express": "^4.16.0",
103-
"@types/find-cache-dir": "^3.0.0",
104103
"@types/glob": "^7.1.1",
105104
"@types/http-proxy": "^1.17.4",
106105
"@types/inquirer": "^8.0.0",
@@ -149,7 +148,6 @@
149148
"eslint-plugin-import": "2.24.2",
150149
"express": "4.17.1",
151150
"fast-json-stable-stringify": "2.1.0",
152-
"find-cache-dir": "3.3.2",
153151
"font-awesome": "^4.7.0",
154152
"gh-got": "^9.0.0",
155153
"git-raw-commits": "^2.0.0",

packages/angular/cli/commands/config-impl.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ const validCliPaths = new Map<
2121
['cli.warnings.versionMismatch', undefined],
2222
['cli.defaultCollection', undefined],
2323
['cli.packageManager', undefined],
24-
2524
['cli.analytics', undefined],
25+
2626
['cli.analyticsSharing.tracking', undefined],
2727
['cli.analyticsSharing.uuid', (v) => (v ? `${v}` : uuidV4())],
28+
29+
['cli.cache.enabled', undefined],
30+
['cli.cache.environment', undefined],
31+
['cli.cache.path', undefined],
2832
]);
2933

3034
/**

packages/angular/cli/lib/config/workspace-schema.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@
7676
"type": "string"
7777
}
7878
}
79+
},
80+
"cache": {
81+
"description": "Control disk cache.",
82+
"type": "object",
83+
"properties": {
84+
"environment": {
85+
"description": "Configure in which environment disk cache is enabled.",
86+
"type": "string",
87+
"enum": ["local", "ci", "all"]
88+
},
89+
"enabled": {
90+
"description": "Configure whether disk caching is enabled.",
91+
"type": "boolean"
92+
},
93+
"path": {
94+
"description": "Cache base path.",
95+
"type": "string"
96+
}
97+
}
7998
}
8099
},
81100
"additionalProperties": false

packages/angular_devkit/build_angular/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ ts_library(
119119
"@npm//@types/cacache",
120120
"@npm//@types/caniuse-lite",
121121
"@npm//@types/copy-webpack-plugin",
122-
"@npm//@types/find-cache-dir",
123122
"@npm//@types/glob",
124123
"@npm//@types/inquirer",
125124
"@npm//@types/karma",
@@ -145,7 +144,6 @@ ts_library(
145144
"@npm//css-loader",
146145
"@npm//esbuild",
147146
"@npm//esbuild-wasm",
148-
"@npm//find-cache-dir",
149147
"@npm//glob",
150148
"@npm//https-proxy-agent",
151149
"@npm//inquirer",

packages/angular_devkit/build_angular/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"critters": "0.0.10",
3434
"css-loader": "6.3.0",
3535
"esbuild-wasm": "0.13.4",
36-
"find-cache-dir": "3.3.2",
3736
"glob": "7.2.0",
3837
"https-proxy-agent": "5.0.0",
3938
"inquirer": "8.2.0",

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
IndexHtmlGenerator,
3434
IndexHtmlTransform,
3535
} from '../../utils/index-file/index-html-generator';
36+
import { normalizeCacheOptions } from '../../utils/normalize-cache';
3637
import { ensureOutputPaths } from '../../utils/output-paths';
3738
import { generateEntryPoints } from '../../utils/package-chunk-sort';
3839
import { augmentAppWithServiceWorker } from '../../utils/service-worker';
@@ -168,11 +169,14 @@ export function buildWebpackBrowser(
168169

169170
checkInternetExplorerSupport(buildBrowserFeatures.supportedBrowsers, context.logger);
170171

171-
return initialize(options, context, transforms.webpackConfiguration);
172+
return {
173+
...(await initialize(options, context, transforms.webpackConfiguration)),
174+
cacheOptions: normalizeCacheOptions(projectMetadata, context.workspaceRoot),
175+
};
172176
}),
173177
switchMap(
174178
// eslint-disable-next-line max-lines-per-function
175-
({ config, projectRoot, projectSourceRoot, i18n, target }) => {
179+
({ config, projectRoot, projectSourceRoot, i18n, target, cacheOptions }) => {
176180
const normalizedOptimization = normalizeOptimization(options.optimization);
177181

178182
return runWebpack(config, context, {
@@ -293,6 +297,7 @@ export function buildWebpackBrowser(
293297
});
294298

295299
const indexHtmlGenerator = new IndexHtmlGenerator({
300+
cache: cacheOptions,
296301
indexPath: path.join(context.workspaceRoot, getIndexInputFile(options.index)),
297302
entrypoints,
298303
deployUrl: options.deployUrl,

packages/angular_devkit/build_angular/src/builders/dev-server/index.ts

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import webpack from 'webpack';
2121
import webpackDevServer from 'webpack-dev-server';
2222
import { ExecutionTransformer } from '../../transforms';
2323
import { normalizeOptimization } from '../../utils';
24-
import { findCachePath } from '../../utils/cache-path';
2524
import { checkPort } from '../../utils/check-port';
2625
import { colors } from '../../utils/color';
2726
import { I18nOptions } from '../../utils/i18n-options';
2827
import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
28+
import { NormalizedCachedOptions, normalizeCacheOptions } from '../../utils/normalize-cache';
2929
import { generateEntryPoints } from '../../utils/package-chunk-sort';
3030
import { assertCompatibleAngularVersion } from '../../utils/version';
3131
import {
@@ -86,8 +86,12 @@ export function serveWebpackBrowser(
8686
browserOptions: json.JsonObject & BrowserBuilderSchema;
8787
webpackConfig: webpack.Configuration;
8888
projectRoot: string;
89-
locale: string | undefined;
9089
}> {
90+
const projectName = context.target?.project;
91+
if (!projectName) {
92+
throw new Error('The builder requires a target.');
93+
}
94+
9195
options.port = await checkPort(options.port ?? 4200, options.host || 'localhost');
9296

9397
if (options.hmr) {
@@ -130,6 +134,9 @@ export function serveWebpackBrowser(
130134
logger.warn(`Warning: 'outputHashing' option is disabled when using the dev-server.`);
131135
}
132136

137+
const metadata = await context.getProjectMetadata(projectName);
138+
const cacheOptions = normalizeCacheOptions(metadata, context.workspaceRoot);
139+
133140
const browserName = await context.getBuilderNameForTarget(browserTarget);
134141
const browserOptions = (await context.validateOptions(
135142
{
@@ -193,51 +200,51 @@ export function serveWebpackBrowser(
193200
);
194201
}
195202

196-
await setupLocalize(locale, i18n, browserOptions, webpackConfig);
203+
await setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions);
197204
}
198205

199206
if (transforms.webpackConfiguration) {
200207
webpackConfig = await transforms.webpackConfiguration(webpackConfig);
201208
}
202209

210+
if (browserOptions.index) {
211+
const { scripts = [], styles = [], baseHref } = browserOptions;
212+
const entrypoints = generateEntryPoints({
213+
scripts,
214+
styles,
215+
// The below is needed as otherwise HMR for CSS will break.
216+
// styles.js and runtime.js needs to be loaded as a non-module scripts as otherwise `document.currentScript` will be null.
217+
// https://github.com/webpack-contrib/mini-css-extract-plugin/blob/90445dd1d81da0c10b9b0e8a17b417d0651816b8/src/hmr/hotModuleReplacement.js#L39
218+
isHMREnabled: !!webpackConfig.devServer?.hot,
219+
});
220+
221+
webpackConfig.plugins ??= [];
222+
webpackConfig.plugins.push(
223+
new IndexHtmlWebpackPlugin({
224+
indexPath: path.resolve(workspaceRoot, getIndexInputFile(browserOptions.index)),
225+
outputPath: getIndexOutputFile(browserOptions.index),
226+
baseHref,
227+
entrypoints,
228+
deployUrl: browserOptions.deployUrl,
229+
sri: browserOptions.subresourceIntegrity,
230+
cache: cacheOptions,
231+
postTransform: transforms.indexHtml,
232+
optimization: normalizeOptimization(browserOptions.optimization),
233+
crossOrigin: browserOptions.crossOrigin,
234+
lang: locale,
235+
}),
236+
);
237+
}
238+
203239
return {
204240
browserOptions,
205241
webpackConfig,
206242
projectRoot,
207-
locale,
208243
};
209244
}
210245

211246
return from(setup()).pipe(
212-
switchMap(({ browserOptions, webpackConfig, locale }) => {
213-
if (browserOptions.index) {
214-
const { scripts = [], styles = [], baseHref } = browserOptions;
215-
const entrypoints = generateEntryPoints({
216-
scripts,
217-
styles,
218-
// The below is needed as otherwise HMR for CSS will break.
219-
// styles.js and runtime.js needs to be loaded as a non-module scripts as otherwise `document.currentScript` will be null.
220-
// https://github.com/webpack-contrib/mini-css-extract-plugin/blob/90445dd1d81da0c10b9b0e8a17b417d0651816b8/src/hmr/hotModuleReplacement.js#L39
221-
isHMREnabled: !!webpackConfig.devServer?.hot,
222-
});
223-
224-
webpackConfig.plugins ??= [];
225-
webpackConfig.plugins.push(
226-
new IndexHtmlWebpackPlugin({
227-
indexPath: path.resolve(workspaceRoot, getIndexInputFile(browserOptions.index)),
228-
outputPath: getIndexOutputFile(browserOptions.index),
229-
baseHref,
230-
entrypoints,
231-
deployUrl: browserOptions.deployUrl,
232-
sri: browserOptions.subresourceIntegrity,
233-
postTransform: transforms.indexHtml,
234-
optimization: normalizeOptimization(browserOptions.optimization),
235-
crossOrigin: browserOptions.crossOrigin,
236-
lang: locale,
237-
}),
238-
);
239-
}
240-
247+
switchMap(({ browserOptions, webpackConfig }) => {
241248
return runWebpackDevServer(webpackConfig, context, {
242249
logging: transforms.logging || createWebpackLoggingCallback(browserOptions, logger),
243250
webpackFactory: require('webpack') as typeof webpack,
@@ -286,6 +293,7 @@ async function setupLocalize(
286293
i18n: I18nOptions,
287294
browserOptions: BrowserBuilderSchema,
288295
webpackConfig: webpack.Configuration,
296+
cacheOptions: NormalizedCachedOptions,
289297
) {
290298
const localeDescription = i18n.locales[locale];
291299

@@ -327,7 +335,9 @@ async function setupLocalize(
327335
{
328336
loader: require.resolve('../../babel/webpack-loader'),
329337
options: {
330-
cacheDirectory: findCachePath('babel-dev-server-i18n'),
338+
cacheDirectory:
339+
(cacheOptions.enabled && path.join(cacheOptions.path, 'babel-dev-server-i18n')) ||
340+
false,
331341
cacheIdentifier: JSON.stringify({
332342
locale,
333343
translationIntegrity: localeDescription?.files.map((file) => file.integrity),

packages/angular_devkit/build_angular/src/builders/ng-packagr/index.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,52 @@
77
*/
88

99
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
10-
import { resolve } from 'path';
10+
import { join, resolve } from 'path';
1111
import { Observable, from, of } from 'rxjs';
1212
import { catchError, mapTo, switchMap } from 'rxjs/operators';
13+
import { normalizeCacheOptions } from '../../utils/normalize-cache';
1314
import { Schema as NgPackagrBuilderOptions } from './schema';
1415

15-
async function initialize(
16-
options: NgPackagrBuilderOptions,
17-
root: string,
18-
): Promise<import('ng-packagr').NgPackagr> {
19-
const packager = (await import('ng-packagr')).ngPackagr();
20-
21-
packager.forProject(resolve(root, options.project));
22-
23-
if (options.tsConfig) {
24-
packager.withTsConfig(resolve(root, options.tsConfig));
25-
}
26-
27-
return packager;
28-
}
29-
3016
/**
3117
* @experimental Direct usage of this function is considered experimental.
3218
*/
3319
export function execute(
3420
options: NgPackagrBuilderOptions,
3521
context: BuilderContext,
3622
): Observable<BuilderOutput> {
37-
return from(initialize(options, context.workspaceRoot)).pipe(
38-
switchMap((packager) => (options.watch ? packager.watch() : packager.build())),
23+
return from(
24+
(async () => {
25+
const root = context.workspaceRoot;
26+
const packager = (await import('ng-packagr')).ngPackagr();
27+
28+
packager.forProject(resolve(root, options.project));
29+
30+
if (options.tsConfig) {
31+
packager.withTsConfig(resolve(root, options.tsConfig));
32+
}
33+
34+
const projectName = context.target?.project;
35+
if (!projectName) {
36+
throw new Error('The builder requires a target.');
37+
}
38+
39+
const metadata = await context.getProjectMetadata(projectName);
40+
const { enabled: cacheEnabled, path: cacheDirectory } = normalizeCacheOptions(
41+
metadata,
42+
context.workspaceRoot,
43+
);
44+
45+
const ngPackagrOptions = {
46+
cacheEnabled,
47+
cacheDirectory: join(cacheDirectory, 'ng-packagr'),
48+
};
49+
50+
return { packager, ngPackagrOptions };
51+
})(),
52+
).pipe(
53+
switchMap(({ packager, ngPackagrOptions }) =>
54+
options.watch ? packager.watch(ngPackagrOptions) : packager.build(ngPackagrOptions),
55+
),
3956
mapTo({ success: true }),
4057
catchError((err) => of({ success: false, error: err.message })),
4158
);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
SourceMapClass,
2121
} from '../builders/browser/schema';
2222
import { Schema as DevServerSchema } from '../builders/dev-server/schema';
23+
import { NormalizedCachedOptions } from './normalize-cache';
2324
import { NormalizedFileReplacement } from './normalize-file-replacements';
2425
import { NormalizedOptimizationOptions } from './normalize-optimization';
2526

@@ -66,8 +67,8 @@ export interface BuildOptions {
6667
platform?: 'browser' | 'server';
6768
fileReplacements: NormalizedFileReplacement[];
6869
inlineStyleLanguage?: InlineStyleLanguage;
69-
7070
allowedCommonJsDependencies?: string[];
71+
cache: NormalizedCachedOptions;
7172
}
7273

7374
export interface WebpackTestOptions extends BuildOptions {

packages/angular_devkit/build_angular/src/utils/cache-path.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)