@angular-devkit/build-angular 13.0.0-next.8 → 13.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +33 -34
  2. package/src/babel/babel-loader.d.ts +12 -3
  3. package/src/babel/presets/application.d.ts +8 -0
  4. package/src/babel/presets/application.js +18 -0
  5. package/src/babel/webpack-loader.d.ts +9 -0
  6. package/src/babel/webpack-loader.js +32 -20
  7. package/src/builders/app-shell/index.js +1 -1
  8. package/src/builders/browser/index.js +8 -3
  9. package/src/builders/dev-server/index.js +26 -17
  10. package/src/builders/ng-packagr/index.js +21 -9
  11. package/src/utils/build-options.d.ts +3 -0
  12. package/src/utils/environment-options.d.ts +1 -3
  13. package/src/utils/environment-options.js +13 -38
  14. package/src/utils/index-file/index-html-generator.d.ts +2 -0
  15. package/src/utils/index-file/inline-fonts.d.ts +3 -0
  16. package/src/utils/index-file/inline-fonts.js +9 -9
  17. package/src/utils/normalize-builder-schema.d.ts +2 -2
  18. package/src/utils/normalize-builder-schema.js +4 -1
  19. package/src/utils/normalize-cache.d.ts +13 -0
  20. package/src/utils/normalize-cache.js +40 -0
  21. package/src/utils/service-worker.d.ts +1 -1
  22. package/src/utils/service-worker.js +7 -20
  23. package/src/utils/webpack-browser-config.d.ts +1 -1
  24. package/src/utils/webpack-browser-config.js +4 -3
  25. package/src/webpack/configs/analytics.js +4 -1
  26. package/src/webpack/configs/browser.js +1 -0
  27. package/src/webpack/configs/common.d.ts +2 -2
  28. package/src/webpack/configs/common.js +15 -23
  29. package/src/webpack/configs/test.js +2 -22
  30. package/src/webpack/plugins/analytics.d.ts +2 -2
  31. package/src/webpack/plugins/analytics.js +3 -3
  32. package/src/webpack/utils/helpers.d.ts +1 -0
  33. package/src/webpack/utils/helpers.js +15 -1
  34. package/src/utils/cache-path.d.ts +0 -8
  35. package/src/utils/cache-path.js +0 -24
package/package.json CHANGED
@@ -1,79 +1,78 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "13.0.0-next.8",
3
+ "version": "13.0.0-rc.2",
4
4
  "description": "Angular Webpack Build Facade",
5
5
  "main": "src/index.js",
6
6
  "typings": "src/index.d.ts",
7
7
  "builders": "builders.json",
8
8
  "dependencies": {
9
9
  "@ampproject/remapping": "1.0.1",
10
- "@angular-devkit/architect": "0.1300.0-next.8",
11
- "@angular-devkit/build-webpack": "0.1300.0-next.8",
12
- "@angular-devkit/core": "13.0.0-next.8",
13
- "@babel/core": "7.15.5",
14
- "@babel/generator": "7.15.4",
10
+ "@angular-devkit/architect": "0.1300.0-rc.2",
11
+ "@angular-devkit/build-webpack": "0.1300.0-rc.2",
12
+ "@angular-devkit/core": "13.0.0-rc.2",
13
+ "@babel/core": "7.15.8",
14
+ "@babel/generator": "7.15.8",
15
15
  "@babel/helper-annotate-as-pure": "7.15.4",
16
- "@babel/plugin-proposal-async-generator-functions": "7.15.4",
16
+ "@babel/plugin-proposal-async-generator-functions": "7.15.8",
17
17
  "@babel/plugin-transform-async-to-generator": "7.14.5",
18
- "@babel/plugin-transform-runtime": "7.15.0",
19
- "@babel/preset-env": "7.15.6",
18
+ "@babel/plugin-transform-runtime": "7.15.8",
19
+ "@babel/preset-env": "7.15.8",
20
20
  "@babel/runtime": "7.15.4",
21
21
  "@babel/template": "7.15.4",
22
22
  "@discoveryjs/json-ext": "0.5.5",
23
- "@jsdevtools/coverage-istanbul-loader": "3.0.5",
24
- "@ngtools/webpack": "13.0.0-next.8",
23
+ "@ngtools/webpack": "13.0.0-rc.2",
25
24
  "ansi-colors": "4.1.1",
26
- "babel-loader": "8.2.2",
25
+ "babel-loader": "8.2.3",
26
+ "babel-plugin-istanbul": "6.1.1",
27
27
  "browserslist": "^4.9.1",
28
28
  "cacache": "15.3.0",
29
29
  "caniuse-lite": "^1.0.30001032",
30
30
  "circular-dependency-plugin": "5.2.2",
31
31
  "copy-webpack-plugin": "9.0.1",
32
- "core-js": "3.18.1",
33
- "critters": "0.0.10",
34
- "css-loader": "6.3.0",
35
- "esbuild-wasm": "0.13.3",
36
- "find-cache-dir": "3.3.2",
32
+ "core-js": "3.19.0",
33
+ "critters": "0.0.14",
34
+ "css-loader": "6.5.0",
35
+ "esbuild-wasm": "0.13.9",
37
36
  "glob": "7.2.0",
38
37
  "https-proxy-agent": "5.0.0",
39
- "inquirer": "8.1.5",
38
+ "inquirer": "8.2.0",
40
39
  "karma-source-map-support": "1.4.0",
41
- "less": "4.1.1",
42
- "less-loader": "10.0.1",
43
- "license-webpack-plugin": "2.3.21",
44
- "loader-utils": "2.0.0",
45
- "mini-css-extract-plugin": "2.3.0",
40
+ "less": "4.1.2",
41
+ "less-loader": "10.2.0",
42
+ "license-webpack-plugin": "3.0.0",
43
+ "loader-utils": "3.0.0",
44
+ "mini-css-extract-plugin": "2.4.3",
46
45
  "minimatch": "3.0.4",
47
- "open": "8.2.1",
46
+ "open": "8.4.0",
48
47
  "ora": "5.4.1",
49
48
  "parse5-html-rewriting-stream": "6.0.1",
50
49
  "piscina": "3.1.0",
51
- "postcss": "8.3.8",
50
+ "postcss": "8.3.11",
52
51
  "postcss-import": "14.0.2",
53
- "postcss-loader": "6.1.1",
52
+ "postcss-loader": "6.2.0",
54
53
  "postcss-preset-env": "6.7.0",
55
54
  "regenerator-runtime": "0.13.9",
56
55
  "resolve-url-loader": "4.0.0",
57
56
  "rxjs": "6.6.7",
58
- "sass": "1.42.1",
59
- "sass-loader": "12.1.0",
57
+ "sass": "1.43.4",
58
+ "sass-loader": "12.2.0",
60
59
  "semver": "7.3.5",
61
60
  "source-map-loader": "3.0.0",
62
61
  "source-map-support": "0.5.20",
63
62
  "stylus": "0.55.0",
64
- "stylus-loader": "6.1.0",
63
+ "stylus-loader": "6.2.0",
65
64
  "terser": "5.9.0",
66
65
  "text-table": "0.2.0",
67
66
  "tree-kill": "1.2.2",
68
67
  "tslib": "2.3.1",
69
- "webpack": "5.55.1",
68
+ "webpack": "5.60.0",
70
69
  "webpack-dev-middleware": "5.2.1",
71
- "webpack-dev-server": "4.3.0",
70
+ "webpack-dev-server": "4.3.1",
72
71
  "webpack-merge": "5.8.0",
73
72
  "webpack-subresource-integrity": "5.0.0"
74
73
  },
75
74
  "optionalDependencies": {
76
- "esbuild": "0.13.3"
75
+ "esbuild": "0.13.9"
77
76
  },
78
77
  "peerDependencies": {
79
78
  "@angular/compiler-cli": "^13.0.0 || ^13.0.0-next",
@@ -117,8 +116,8 @@
117
116
  "url": "https://github.com/angular/angular-cli.git"
118
117
  },
119
118
  "engines": {
120
- "node": "^12.20.0 || >=14.0.0",
121
- "npm": "^6.11.0 || ^7.5.6",
119
+ "node": "^12.20.0 || ^14.15.0 || >=16.10.0",
120
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
122
121
  "yarn": ">= 1.13.0"
123
122
  },
124
123
  "author": "Angular Authors",
@@ -7,9 +7,7 @@
7
7
  */
8
8
 
9
9
  declare module 'babel-loader' {
10
- type BabelLoaderCustomizer<T> = (
11
- babel: typeof import('@babel/core'),
12
- ) => {
10
+ type BabelLoaderCustomizer<T> = (babel: typeof import('@babel/core')) => {
13
11
  customOptions?(
14
12
  this: import('webpack').loader.LoaderContext,
15
13
  loaderOptions: Record<string, unknown>,
@@ -20,6 +18,17 @@ declare module 'babel-loader' {
20
18
  configuration: import('@babel/core').PartialConfig,
21
19
  loaderArguments: { source: string; map?: unknown; customOptions: T },
22
20
  ): import('@babel/core').TransformOptions;
21
+ result?(
22
+ this: import('webpack').loader.LoaderContext,
23
+ result: import('@babel/core').BabelFileResult,
24
+ context: {
25
+ source: string;
26
+ map?: unknown;
27
+ customOptions: T;
28
+ configuration: import('@babel/core').PartialConfig;
29
+ options: import('@babel/core').TransformOptions;
30
+ },
31
+ ): import('@babel/core').BabelFileResult;
23
32
  };
24
33
  function custom<T>(customizer: BabelLoaderCustomizer<T>): import('webpack').loader.Loader;
25
34
  }
@@ -32,6 +32,14 @@ export interface ApplicationPresetOptions {
32
32
  };
33
33
  forceES5?: boolean;
34
34
  forceAsyncTransformation?: boolean;
35
+ instrumentCode?: {
36
+ includedBasePath: string;
37
+ };
38
+ optimize?: {
39
+ looseEnums: boolean;
40
+ pureTopLevel: boolean;
41
+ wrapDecorators: boolean;
42
+ };
35
43
  diagnosticReporter?: DiagnosticReporter;
36
44
  }
37
45
  export default function (api: unknown, options: ApplicationPresetOptions): {
@@ -145,6 +145,24 @@ function default_1(api, options) {
145
145
  plugins.push(require('@babel/plugin-transform-async-to-generator').default, require('@babel/plugin-proposal-async-generator-functions').default);
146
146
  needRuntimeTransform = true;
147
147
  }
148
+ if (options.optimize) {
149
+ if (options.optimize.pureTopLevel) {
150
+ plugins.push(require('../plugins/pure-toplevel-functions').default);
151
+ }
152
+ plugins.push(require('../plugins/elide-angular-metadata').default, [
153
+ require('../plugins/adjust-typescript-enums').default,
154
+ { loose: options.optimize.looseEnums },
155
+ ], [
156
+ require('../plugins/adjust-static-class-members').default,
157
+ { wrapDecorators: options.optimize.wrapDecorators },
158
+ ]);
159
+ }
160
+ if (options.instrumentCode) {
161
+ plugins.push([
162
+ require('babel-plugin-istanbul').default,
163
+ { inputSourceMap: false, cwd: options.instrumentCode.includedBasePath },
164
+ ]);
165
+ }
148
166
  if (needRuntimeTransform) {
149
167
  // Babel equivalent to TypeScript's `importHelpers` option
150
168
  plugins.push([
@@ -5,5 +5,14 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { ApplicationPresetOptions } from './presets/application';
9
+ interface AngularCustomOptions extends Omit<ApplicationPresetOptions, 'instrumentCode'> {
10
+ instrumentCode?: {
11
+ /** node_modules and test files are always excluded. */
12
+ excludedPaths: Set<String>;
13
+ includedBasePath: string;
14
+ };
15
+ }
16
+ export declare type AngularBabelLoaderOptions = AngularCustomOptions & Record<string, unknown>;
8
17
  declare const _default: any;
9
18
  export default _default;
@@ -6,7 +6,11 @@
6
6
  * Use of this source code is governed by an MIT-style license that can be
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
9
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
+ const remapping_1 = __importDefault(require("@ampproject/remapping"));
10
14
  const babel_loader_1 = require("babel-loader");
11
15
  const typescript_1 = require("typescript");
12
16
  const load_esm_1 = require("../utils/load-esm");
@@ -47,8 +51,9 @@ exports.default = (0, babel_loader_1.custom)(() => {
47
51
  inputSourceMap: false,
48
52
  });
49
53
  return {
50
- async customOptions({ i18n, scriptTarget, aot, optimize, ...rawOptions }, { source }) {
54
+ async customOptions(options, { source }) {
51
55
  var _a, _b;
56
+ const { i18n, scriptTarget, aot, optimize, instrumentCode, ...rawOptions } = options;
52
57
  // Must process file if plugins are added
53
58
  let shouldProcess = Array.isArray(rawOptions.plugins) && rawOptions.plugins.length > 0;
54
59
  const customOptions = {
@@ -56,6 +61,7 @@ exports.default = (0, babel_loader_1.custom)(() => {
56
61
  forceES5: false,
57
62
  angularLinker: undefined,
58
63
  i18n: undefined,
64
+ instrumentCode: undefined,
59
65
  };
60
66
  // Analyze file for linking
61
67
  if (await requiresLinking(this.resourcePath, source)) {
@@ -87,7 +93,7 @@ exports.default = (0, babel_loader_1.custom)(() => {
87
93
  customOptions.forceAsyncTransformation =
88
94
  !/[\\/][_f]?esm2015[\\/]/.test(this.resourcePath) && source.includes('async');
89
95
  }
90
- shouldProcess || (shouldProcess = customOptions.forceAsyncTransformation || customOptions.forceES5);
96
+ shouldProcess || (shouldProcess = customOptions.forceAsyncTransformation || customOptions.forceES5 || false);
91
97
  }
92
98
  // Analyze for i18n inlining
93
99
  if (i18n &&
@@ -127,6 +133,16 @@ exports.default = (0, babel_loader_1.custom)(() => {
127
133
  };
128
134
  shouldProcess = true;
129
135
  }
136
+ if (instrumentCode &&
137
+ !instrumentCode.excludedPaths.has(this.resourcePath) &&
138
+ !/\.(e2e|spec)\.tsx?$|[\\/]node_modules[\\/]/.test(this.resourcePath) &&
139
+ this.resourcePath.startsWith(instrumentCode.includedBasePath)) {
140
+ // `babel-plugin-istanbul` has it's own includes but we do the below so that we avoid running the the loader.
141
+ customOptions.instrumentCode = {
142
+ includedBasePath: instrumentCode.includedBasePath,
143
+ };
144
+ shouldProcess = true;
145
+ }
130
146
  // Add provided loader options to default base options
131
147
  const loaderOptions = {
132
148
  ...baseOptions,
@@ -146,27 +162,12 @@ exports.default = (0, babel_loader_1.custom)(() => {
146
162
  return { custom: customOptions, loader: loaderOptions };
147
163
  },
148
164
  config(configuration, { customOptions }) {
149
- var _a;
150
- const plugins = (_a = configuration.options.plugins) !== null && _a !== void 0 ? _a : [];
151
- if (customOptions.optimize) {
152
- if (customOptions.optimize.pureTopLevel) {
153
- plugins.push(require('./plugins/pure-toplevel-functions').default);
154
- }
155
- plugins.push(require('./plugins/elide-angular-metadata').default, [
156
- require('./plugins/adjust-typescript-enums').default,
157
- { loose: customOptions.optimize.looseEnums },
158
- ], [
159
- require('./plugins/adjust-static-class-members').default,
160
- { wrapDecorators: customOptions.optimize.wrapDecorators },
161
- ]);
162
- }
163
165
  return {
164
166
  ...configuration.options,
165
- // Workaround for https://github.com/babel/babel-loader/pull/896 is available
166
- // Delete once the above PR is released
167
+ // Using `false` disables babel from attempting to locate sourcemaps or process any inline maps.
168
+ // The babel types do not include the false option even though it is valid
167
169
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
- inputSourceMap: configuration.options.inputSourceMap || false,
169
- plugins,
170
+ inputSourceMap: false,
170
171
  presets: [
171
172
  ...(configuration.options.presets || []),
172
173
  [
@@ -190,5 +191,16 @@ exports.default = (0, babel_loader_1.custom)(() => {
190
191
  ],
191
192
  };
192
193
  },
194
+ result(result, { map: inputSourceMap }) {
195
+ if (result.map && inputSourceMap) {
196
+ // Merge the intermediate sourcemap generated by babel with the input source map.
197
+ // The casting is required due to slight differences in the types for babel and
198
+ // `@ampproject/remapping` source map objects but both are compatible with Webpack.
199
+ // This method for merging is used because it provides more accurate output
200
+ // and is faster while using less memory.
201
+ result.map = (0, remapping_1.default)([result.map, inputSourceMap], () => null);
202
+ }
203
+ return result;
204
+ },
193
205
  };
194
206
  });
@@ -91,7 +91,7 @@ async function _renderUniversal(options, context, browserResult, serverResult, s
91
91
  }
92
92
  await fs.promises.writeFile(outputIndexPath, html);
93
93
  if (browserOptions.serviceWorker) {
94
- await (0, service_worker_1.augmentAppWithServiceWorker)((0, core_1.normalize)(root), projectRoot, (0, core_1.normalize)(outputPath), browserOptions.baseHref || '/', browserOptions.ngswConfigPath);
94
+ await (0, service_worker_1.augmentAppWithServiceWorker)(projectRoot, (0, core_1.normalize)(outputPath), browserOptions.baseHref || '/', browserOptions.ngswConfigPath);
95
95
  }
96
96
  }
97
97
  return browserResult;
@@ -41,6 +41,7 @@ const color_1 = require("../../utils/color");
41
41
  const copy_assets_1 = require("../../utils/copy-assets");
42
42
  const i18n_inlining_1 = require("../../utils/i18n-inlining");
43
43
  const index_html_generator_1 = require("../../utils/index-file/index-html-generator");
44
+ const normalize_cache_1 = require("../../utils/normalize-cache");
44
45
  const output_paths_1 = require("../../utils/output-paths");
45
46
  const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
46
47
  const service_worker_1 = require("../../utils/service-worker");
@@ -102,10 +103,13 @@ function buildWebpackBrowser(options, context, transforms = {}) {
102
103
  const sysProjectRoot = (0, core_1.getSystemPath)((0, core_1.resolve)((0, core_1.normalize)(context.workspaceRoot), (0, core_1.normalize)((_a = projectMetadata.root) !== null && _a !== void 0 ? _a : '')));
103
104
  const buildBrowserFeatures = new utils_1.BuildBrowserFeatures(sysProjectRoot);
104
105
  checkInternetExplorerSupport(buildBrowserFeatures.supportedBrowsers, context.logger);
105
- return initialize(options, context, transforms.webpackConfiguration);
106
+ return {
107
+ ...(await initialize(options, context, transforms.webpackConfiguration)),
108
+ cacheOptions: (0, normalize_cache_1.normalizeCacheOptions)(projectMetadata, context.workspaceRoot),
109
+ };
106
110
  }), (0, operators_1.switchMap)(
107
111
  // eslint-disable-next-line max-lines-per-function
108
- ({ config, projectRoot, projectSourceRoot, i18n, target }) => {
112
+ ({ config, projectRoot, projectSourceRoot, i18n, target, cacheOptions }) => {
109
113
  const normalizedOptimization = (0, utils_1.normalizeOptimization)(options.optimization);
110
114
  return (0, build_webpack_1.runWebpack)(config, context, {
111
115
  webpackFactory: require('webpack'),
@@ -191,6 +195,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
191
195
  styles: (_e = options.styles) !== null && _e !== void 0 ? _e : [],
192
196
  });
193
197
  const indexHtmlGenerator = new index_html_generator_1.IndexHtmlGenerator({
198
+ cache: cacheOptions,
194
199
  indexPath: path.join(context.workspaceRoot, (0, webpack_browser_config_1.getIndexInputFile)(options.index)),
195
200
  entrypoints,
196
201
  deployUrl: options.deployUrl,
@@ -239,7 +244,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
239
244
  spinner.start('Generating service worker...');
240
245
  for (const [locale, outputPath] of outputPaths.entries()) {
241
246
  try {
242
- await (0, service_worker_1.augmentAppWithServiceWorker)(root, (0, core_1.normalize)(projectRoot), (0, core_1.normalize)(outputPath), getLocaleBaseHref(i18n, locale) || options.baseHref || '/', options.ngswConfigPath);
247
+ await (0, service_worker_1.augmentAppWithServiceWorker)((0, core_1.normalize)(projectRoot), (0, core_1.normalize)(outputPath), getLocaleBaseHref(i18n, locale) || options.baseHref || '/', options.ngswConfigPath);
243
248
  }
244
249
  catch (error) {
245
250
  spinner.fail('Service worker generation failed.');
@@ -35,9 +35,9 @@ const rxjs_1 = require("rxjs");
35
35
  const operators_1 = require("rxjs/operators");
36
36
  const url = __importStar(require("url"));
37
37
  const utils_1 = require("../../utils");
38
- const cache_path_1 = require("../../utils/cache-path");
39
38
  const check_port_1 = require("../../utils/check-port");
40
39
  const color_1 = require("../../utils/color");
40
+ const normalize_cache_1 = require("../../utils/normalize-cache");
41
41
  const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
42
42
  const version_1 = require("../../utils/version");
43
43
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
@@ -61,8 +61,12 @@ function serveWebpackBrowser(options, context, transforms = {}) {
61
61
  (0, version_1.assertCompatibleAngularVersion)(workspaceRoot);
62
62
  const browserTarget = (0, architect_1.targetFromTargetString)(options.browserTarget);
63
63
  async function setup() {
64
- var _a;
65
- options.port = await (0, check_port_1.checkPort)((_a = options.port) !== null && _a !== void 0 ? _a : 4200, options.host || 'localhost');
64
+ var _a, _b, _c, _d;
65
+ const projectName = (_a = context.target) === null || _a === void 0 ? void 0 : _a.project;
66
+ if (!projectName) {
67
+ throw new Error('The builder requires a target.');
68
+ }
69
+ options.port = await (0, check_port_1.checkPort)((_b = options.port) !== null && _b !== void 0 ? _b : 4200, options.host || 'localhost');
66
70
  if (options.hmr) {
67
71
  logger.warn(core_1.tags.stripIndents `NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.
68
72
  See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.`);
@@ -96,6 +100,8 @@ function serveWebpackBrowser(options, context, transforms = {}) {
96
100
  rawBrowserOptions.outputHashing = schema_1.OutputHashing.None;
97
101
  logger.warn(`Warning: 'outputHashing' option is disabled when using the dev-server.`);
98
102
  }
103
+ const metadata = await context.getProjectMetadata(projectName);
104
+ const cacheOptions = (0, normalize_cache_1.normalizeCacheOptions)(metadata, context.workspaceRoot);
99
105
  const browserName = await context.getBuilderNameForTarget(browserTarget);
100
106
  const browserOptions = (await context.validateOptions({
101
107
  ...rawBrowserOptions,
@@ -143,20 +149,11 @@ function serveWebpackBrowser(options, context, transforms = {}) {
143
149
  if (i18n.inlineLocales.size > 1) {
144
150
  throw new Error('The development server only supports localizing a single locale per build.');
145
151
  }
146
- await setupLocalize(locale, i18n, browserOptions, webpackConfig);
152
+ await setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions);
147
153
  }
148
154
  if (transforms.webpackConfiguration) {
149
155
  webpackConfig = await transforms.webpackConfiguration(webpackConfig);
150
156
  }
151
- return {
152
- browserOptions,
153
- webpackConfig,
154
- projectRoot,
155
- locale,
156
- };
157
- }
158
- return (0, rxjs_1.from)(setup()).pipe((0, operators_1.switchMap)(({ browserOptions, webpackConfig, locale }) => {
159
- var _a, _b;
160
157
  if (browserOptions.index) {
161
158
  const { scripts = [], styles = [], baseHref } = browserOptions;
162
159
  const entrypoints = (0, package_chunk_sort_1.generateEntryPoints)({
@@ -165,9 +162,9 @@ function serveWebpackBrowser(options, context, transforms = {}) {
165
162
  // The below is needed as otherwise HMR for CSS will break.
166
163
  // styles.js and runtime.js needs to be loaded as a non-module scripts as otherwise `document.currentScript` will be null.
167
164
  // https://github.com/webpack-contrib/mini-css-extract-plugin/blob/90445dd1d81da0c10b9b0e8a17b417d0651816b8/src/hmr/hotModuleReplacement.js#L39
168
- isHMREnabled: !!((_a = webpackConfig.devServer) === null || _a === void 0 ? void 0 : _a.hot),
165
+ isHMREnabled: !!((_c = webpackConfig.devServer) === null || _c === void 0 ? void 0 : _c.hot),
169
166
  });
170
- (_b = webpackConfig.plugins) !== null && _b !== void 0 ? _b : (webpackConfig.plugins = []);
167
+ (_d = webpackConfig.plugins) !== null && _d !== void 0 ? _d : (webpackConfig.plugins = []);
171
168
  webpackConfig.plugins.push(new index_html_webpack_plugin_1.IndexHtmlWebpackPlugin({
172
169
  indexPath: path.resolve(workspaceRoot, (0, webpack_browser_config_1.getIndexInputFile)(browserOptions.index)),
173
170
  outputPath: (0, webpack_browser_config_1.getIndexOutputFile)(browserOptions.index),
@@ -175,12 +172,20 @@ function serveWebpackBrowser(options, context, transforms = {}) {
175
172
  entrypoints,
176
173
  deployUrl: browserOptions.deployUrl,
177
174
  sri: browserOptions.subresourceIntegrity,
175
+ cache: cacheOptions,
178
176
  postTransform: transforms.indexHtml,
179
177
  optimization: (0, utils_1.normalizeOptimization)(browserOptions.optimization),
180
178
  crossOrigin: browserOptions.crossOrigin,
181
179
  lang: locale,
182
180
  }));
183
181
  }
182
+ return {
183
+ browserOptions,
184
+ webpackConfig,
185
+ projectRoot,
186
+ };
187
+ }
188
+ return (0, rxjs_1.from)(setup()).pipe((0, operators_1.switchMap)(({ browserOptions, webpackConfig }) => {
184
189
  return (0, build_webpack_1.runWebpackDevServer)(webpackConfig, context, {
185
190
  logging: transforms.logging || (0, stats_1.createWebpackLoggingCallback)(browserOptions, logger),
186
191
  webpackFactory: require('webpack'),
@@ -211,12 +216,15 @@ function serveWebpackBrowser(options, context, transforms = {}) {
211
216
  if (buildEvent.success) {
212
217
  logger.info(`\n${color_1.colors.greenBright(color_1.colors.symbols.check)} Compiled successfully.`);
213
218
  }
219
+ else {
220
+ logger.info(`\n${color_1.colors.redBright(color_1.colors.symbols.cross)} Failed to compile.`);
221
+ }
214
222
  return { ...buildEvent, baseUrl: serverAddress };
215
223
  }));
216
224
  }));
217
225
  }
218
226
  exports.serveWebpackBrowser = serveWebpackBrowser;
219
- async function setupLocalize(locale, i18n, browserOptions, webpackConfig) {
227
+ async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions) {
220
228
  var _a;
221
229
  const localeDescription = i18n.locales[locale];
222
230
  // Modify main entrypoint to include locale data
@@ -252,7 +260,8 @@ async function setupLocalize(locale, i18n, browserOptions, webpackConfig) {
252
260
  {
253
261
  loader: require.resolve('../../babel/webpack-loader'),
254
262
  options: {
255
- cacheDirectory: (0, cache_path_1.findCachePath)('babel-dev-server-i18n'),
263
+ cacheDirectory: (cacheOptions.enabled && path.join(cacheOptions.path, 'babel-dev-server-i18n')) ||
264
+ false,
256
265
  cacheIdentifier: JSON.stringify({
257
266
  locale,
258
267
  translationIntegrity: localeDescription === null || localeDescription === void 0 ? void 0 : localeDescription.files.map((file) => file.integrity),
@@ -31,19 +31,31 @@ const architect_1 = require("@angular-devkit/architect");
31
31
  const path_1 = require("path");
32
32
  const rxjs_1 = require("rxjs");
33
33
  const operators_1 = require("rxjs/operators");
34
- async function initialize(options, root) {
35
- const packager = (await Promise.resolve().then(() => __importStar(require('ng-packagr')))).ngPackagr();
36
- packager.forProject((0, path_1.resolve)(root, options.project));
37
- if (options.tsConfig) {
38
- packager.withTsConfig((0, path_1.resolve)(root, options.tsConfig));
39
- }
40
- return packager;
41
- }
34
+ const normalize_cache_1 = require("../../utils/normalize-cache");
42
35
  /**
43
36
  * @experimental Direct usage of this function is considered experimental.
44
37
  */
45
38
  function execute(options, context) {
46
- return (0, rxjs_1.from)(initialize(options, context.workspaceRoot)).pipe((0, operators_1.switchMap)((packager) => (options.watch ? packager.watch() : packager.build())), (0, operators_1.mapTo)({ success: true }), (0, operators_1.catchError)((err) => (0, rxjs_1.of)({ success: false, error: err.message })));
39
+ return (0, rxjs_1.from)((async () => {
40
+ var _a;
41
+ const root = context.workspaceRoot;
42
+ const packager = (await Promise.resolve().then(() => __importStar(require('ng-packagr')))).ngPackagr();
43
+ packager.forProject((0, path_1.resolve)(root, options.project));
44
+ if (options.tsConfig) {
45
+ packager.withTsConfig((0, path_1.resolve)(root, options.tsConfig));
46
+ }
47
+ const projectName = (_a = context.target) === null || _a === void 0 ? void 0 : _a.project;
48
+ if (!projectName) {
49
+ throw new Error('The builder requires a target.');
50
+ }
51
+ const metadata = await context.getProjectMetadata(projectName);
52
+ const { enabled: cacheEnabled, path: cacheDirectory } = (0, normalize_cache_1.normalizeCacheOptions)(metadata, context.workspaceRoot);
53
+ const ngPackagrOptions = {
54
+ cacheEnabled,
55
+ cacheDirectory: (0, path_1.join)(cacheDirectory, 'ng-packagr'),
56
+ };
57
+ return { packager, ngPackagrOptions };
58
+ })()).pipe((0, operators_1.switchMap)(({ packager, ngPackagrOptions }) => options.watch ? packager.watch(ngPackagrOptions) : packager.build(ngPackagrOptions)), (0, operators_1.mapTo)({ success: true }), (0, operators_1.catchError)((err) => (0, rxjs_1.of)({ success: false, error: err.message })));
47
59
  }
48
60
  exports.execute = execute;
49
61
  exports.default = (0, architect_1.createBuilder)(execute);
@@ -9,6 +9,7 @@ import { logging } from '@angular-devkit/core';
9
9
  import type { ParsedConfiguration } from '@angular/compiler-cli';
10
10
  import { AssetPatternClass, Budget, CrossOrigin, ExtraEntryPoint, I18NMissingTranslation, IndexUnion, InlineStyleLanguage, Localize, SourceMapClass } from '../builders/browser/schema';
11
11
  import { Schema as DevServerSchema } from '../builders/dev-server/schema';
12
+ import { NormalizedCachedOptions } from './normalize-cache';
12
13
  import { NormalizedFileReplacement } from './normalize-file-replacements';
13
14
  import { NormalizedOptimizationOptions } from './normalize-optimization';
14
15
  export interface BuildOptions {
@@ -57,6 +58,7 @@ export interface BuildOptions {
57
58
  fileReplacements: NormalizedFileReplacement[];
58
59
  inlineStyleLanguage?: InlineStyleLanguage;
59
60
  allowedCommonJsDependencies?: string[];
61
+ cache: NormalizedCachedOptions;
60
62
  }
61
63
  export interface WebpackTestOptions extends BuildOptions {
62
64
  codeCoverage?: boolean;
@@ -73,4 +75,5 @@ export interface WebpackConfigOptions<T = BuildOptions> {
73
75
  tsConfig: ParsedConfiguration;
74
76
  tsConfigPath: string;
75
77
  scriptTarget: import('typescript').ScriptTarget;
78
+ projectName: string;
76
79
  }
@@ -8,8 +8,6 @@
8
8
  export declare const allowMangle: boolean;
9
9
  export declare const shouldBeautify: boolean;
10
10
  export declare const allowMinify: boolean;
11
- export declare const cachingDisabled: boolean;
12
- export declare const cachingBasePath: string | null;
13
- export declare const persistentBuildCacheEnabled: boolean;
14
11
  export declare const profilingEnabled: boolean;
15
12
  export declare const maxWorkers: number;
13
+ export declare const cachingDisabled: boolean | null;
@@ -6,28 +6,9 @@
6
6
  * Use of this source code is governed by an MIT-style license that can be
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || function (mod) {
22
- if (mod && mod.__esModule) return mod;
23
- var result = {};
24
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
- __setModuleDefault(result, mod);
26
- return result;
27
- };
28
9
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.maxWorkers = exports.profilingEnabled = exports.persistentBuildCacheEnabled = exports.cachingBasePath = exports.cachingDisabled = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
30
- const path = __importStar(require("path"));
10
+ exports.cachingDisabled = exports.maxWorkers = exports.profilingEnabled = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
11
+ const color_1 = require("./color");
31
12
  function isDisabled(variable) {
32
13
  return variable === '0' || variable.toLowerCase() === 'false';
33
14
  }
@@ -76,23 +57,6 @@ exports.allowMangle = isPresent(mangleVariable)
76
57
  : debugOptimize.mangle;
77
58
  exports.shouldBeautify = debugOptimize.beautify;
78
59
  exports.allowMinify = debugOptimize.minify;
79
- // Build cache
80
- const cacheVariable = process.env['NG_BUILD_CACHE'];
81
- exports.cachingDisabled = isPresent(cacheVariable) && isDisabled(cacheVariable);
82
- exports.cachingBasePath = (() => {
83
- if (exports.cachingDisabled || !isPresent(cacheVariable) || isEnabled(cacheVariable)) {
84
- return null;
85
- }
86
- if (!path.isAbsolute(cacheVariable)) {
87
- throw new Error('NG_BUILD_CACHE path value must be absolute.');
88
- }
89
- return cacheVariable;
90
- })();
91
- // Persistent build cache
92
- const persistentBuildCacheVariable = process.env['NG_PERSISTENT_BUILD_CACHE'];
93
- exports.persistentBuildCacheEnabled = !exports.cachingDisabled &&
94
- isPresent(persistentBuildCacheVariable) &&
95
- isEnabled(persistentBuildCacheVariable);
96
60
  // Build profiling
97
61
  const profilingVariable = process.env['NG_BUILD_PROFILING'];
98
62
  exports.profilingEnabled = isPresent(profilingVariable) && isEnabled(profilingVariable);
@@ -107,3 +71,14 @@ exports.profilingEnabled = isPresent(profilingVariable) && isEnabled(profilingVa
107
71
  */
108
72
  const maxWorkersVariable = process.env['NG_BUILD_MAX_WORKERS'];
109
73
  exports.maxWorkers = isPresent(maxWorkersVariable) ? +maxWorkersVariable : 4;
74
+ // Build cache
75
+ const cacheVariable = process.env['NG_BUILD_CACHE'];
76
+ exports.cachingDisabled = (() => {
77
+ if (!isPresent(cacheVariable)) {
78
+ return null;
79
+ }
80
+ // eslint-disable-next-line no-console
81
+ console.warn(color_1.colors.yellow(`Warning: 'NG_BUILD_CACHE' environment variable support will be removed in version 14.\n` +
82
+ `Configure 'cli.cache' in the workspace configuration instead.`));
83
+ return isDisabled(cacheVariable);
84
+ })();
@@ -5,6 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { NormalizedCachedOptions } from '../normalize-cache';
8
9
  import { NormalizedOptimizationOptions } from '../normalize-optimization';
9
10
  import { CrossOriginValue, Entrypoint, FileInfo } from './augment-index-html';
10
11
  export interface IndexHtmlGeneratorProcessOptions {
@@ -21,6 +22,7 @@ export interface IndexHtmlGeneratorOptions {
21
22
  postTransform?: IndexHtmlTransform;
22
23
  crossOrigin?: CrossOriginValue;
23
24
  optimization?: NormalizedOptimizationOptions;
25
+ cache?: NormalizedCachedOptions;
24
26
  }
25
27
  export declare type IndexHtmlTransform = (content: string) => Promise<string>;
26
28
  export interface IndexHtmlTransformResult {
@@ -5,11 +5,14 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { NormalizedCachedOptions } from '../normalize-cache';
8
9
  export interface InlineFontsOptions {
9
10
  minify?: boolean;
11
+ cache?: NormalizedCachedOptions;
10
12
  }
11
13
  export declare class InlineFontsProcessor {
12
14
  private options;
15
+ private readonly cachePath;
13
16
  constructor(options: InlineFontsOptions);
14
17
  process(content: string): Promise<string>;
15
18
  private getResponse;
@@ -34,13 +34,9 @@ const cacache = __importStar(require("cacache"));
34
34
  const fs = __importStar(require("fs"));
35
35
  const https = __importStar(require("https"));
36
36
  const https_proxy_agent_1 = __importDefault(require("https-proxy-agent"));
37
+ const path_1 = require("path");
37
38
  const url_1 = require("url");
38
- const cache_path_1 = require("../cache-path");
39
- const environment_options_1 = require("../environment-options");
40
39
  const html_rewriting_stream_1 = require("./html-rewriting-stream");
41
- const cacheFontsPath = environment_options_1.cachingDisabled
42
- ? undefined
43
- : (0, cache_path_1.findCachePath)('angular-build-fonts');
44
40
  const packageVersion = require('../../../package.json').version;
45
41
  const SUPPORTED_PROVIDERS = {
46
42
  'fonts.googleapis.com': {
@@ -53,6 +49,10 @@ const SUPPORTED_PROVIDERS = {
53
49
  class InlineFontsProcessor {
54
50
  constructor(options) {
55
51
  this.options = options;
52
+ const { path: cacheDirectory, enabled } = this.options.cache || {};
53
+ if (cacheDirectory && enabled) {
54
+ this.cachePath = (0, path_1.join)(cacheDirectory, 'angular-build-fonts');
55
+ }
56
56
  }
57
57
  async process(content) {
58
58
  var _a;
@@ -147,8 +147,8 @@ class InlineFontsProcessor {
147
147
  async getResponse(url) {
148
148
  var _a;
149
149
  const key = `${packageVersion}|${url}`;
150
- if (cacheFontsPath) {
151
- const entry = await cacache.get.info(cacheFontsPath, key);
150
+ if (this.cachePath) {
151
+ const entry = await cacache.get.info(this.cachePath, key);
152
152
  if (entry) {
153
153
  return fs.promises.readFile(entry.path, 'utf8');
154
154
  }
@@ -177,8 +177,8 @@ class InlineFontsProcessor {
177
177
  .on('error', (e) => reject(new Error(`Inlining of fonts failed. An error has occurred while retrieving ${url} over the internet.\n` +
178
178
  e.message)));
179
179
  });
180
- if (cacheFontsPath) {
181
- await cacache.put(cacheFontsPath, key, data);
180
+ if (this.cachePath) {
181
+ await cacache.put(this.cachePath, key, data);
182
182
  }
183
183
  return data;
184
184
  }
@@ -5,7 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { Path } from '@angular-devkit/core';
8
+ import { Path, json } from '@angular-devkit/core';
9
9
  import { AssetPatternClass, Schema as BrowserBuilderSchema, SourceMapClass } from '../builders/browser/schema';
10
10
  import { BuildOptions } from './build-options';
11
11
  import { NormalizedFileReplacement } from './normalize-file-replacements';
@@ -19,4 +19,4 @@ export declare type NormalizedBrowserBuilderSchema = BrowserBuilderSchema & Buil
19
19
  fileReplacements: NormalizedFileReplacement[];
20
20
  optimization: NormalizedOptimizationOptions;
21
21
  };
22
- export declare function normalizeBrowserSchema(root: Path, projectRoot: Path, sourceRoot: Path | undefined, options: BrowserBuilderSchema): NormalizedBrowserBuilderSchema;
22
+ export declare function normalizeBrowserSchema(root: Path, projectRoot: Path, sourceRoot: Path | undefined, options: BrowserBuilderSchema, metadata: json.JsonObject): NormalizedBrowserBuilderSchema;
@@ -8,14 +8,17 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.normalizeBrowserSchema = void 0;
11
+ const core_1 = require("@angular-devkit/core");
11
12
  const normalize_asset_patterns_1 = require("./normalize-asset-patterns");
13
+ const normalize_cache_1 = require("./normalize-cache");
12
14
  const normalize_file_replacements_1 = require("./normalize-file-replacements");
13
15
  const normalize_optimization_1 = require("./normalize-optimization");
14
16
  const normalize_source_maps_1 = require("./normalize-source-maps");
15
- function normalizeBrowserSchema(root, projectRoot, sourceRoot, options) {
17
+ function normalizeBrowserSchema(root, projectRoot, sourceRoot, options, metadata) {
16
18
  const normalizedSourceMapOptions = (0, normalize_source_maps_1.normalizeSourceMaps)(options.sourceMap || false);
17
19
  return {
18
20
  ...options,
21
+ cache: (0, normalize_cache_1.normalizeCacheOptions)(metadata, (0, core_1.getSystemPath)(root)),
19
22
  assets: (0, normalize_asset_patterns_1.normalizeAssetPatterns)(options.assets || [], root, projectRoot, sourceRoot),
20
23
  fileReplacements: (0, normalize_file_replacements_1.normalizeFileReplacements)(options.fileReplacements || [], root),
21
24
  optimization: (0, normalize_optimization_1.normalizeOptimization)(options.optimization),
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC 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 { json } from '@angular-devkit/core';
9
+ export interface NormalizedCachedOptions {
10
+ enabled: boolean;
11
+ path: string;
12
+ }
13
+ export declare function normalizeCacheOptions(metadata: json.JsonObject, worspaceRoot: string): NormalizedCachedOptions;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.io/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.normalizeCacheOptions = void 0;
11
+ const core_1 = require("@angular-devkit/core");
12
+ const path_1 = require("path");
13
+ const environment_options_1 = require("./environment-options");
14
+ function normalizeCacheOptions(metadata, worspaceRoot) {
15
+ var _a;
16
+ const cacheMetadata = core_1.json.isJsonObject(metadata.cli) && core_1.json.isJsonObject(metadata.cli.cache)
17
+ ? metadata.cli.cache
18
+ : {};
19
+ const { enabled = true, environment = 'local', path = '.angular/cache' } = cacheMetadata;
20
+ const isCI = process.env['CI'] === '1' || ((_a = process.env['CI']) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true';
21
+ let cacheEnabled = enabled;
22
+ if (environment_options_1.cachingDisabled !== null) {
23
+ cacheEnabled = !environment_options_1.cachingDisabled;
24
+ }
25
+ if (cacheEnabled) {
26
+ switch (environment) {
27
+ case 'ci':
28
+ cacheEnabled = isCI;
29
+ break;
30
+ case 'local':
31
+ cacheEnabled = !isCI;
32
+ break;
33
+ }
34
+ }
35
+ return {
36
+ enabled: cacheEnabled,
37
+ path: (0, path_1.resolve)(worspaceRoot, path),
38
+ };
39
+ }
40
+ exports.normalizeCacheOptions = normalizeCacheOptions;
@@ -6,4 +6,4 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { Path } from '@angular-devkit/core';
9
- export declare function augmentAppWithServiceWorker(projectRoot: Path, appRoot: Path, outputPath: Path, baseHref: string, ngswConfigPath?: string): Promise<void>;
9
+ export declare function augmentAppWithServiceWorker(appRoot: Path, outputPath: Path, baseHref: string, ngswConfigPath?: string): Promise<void>;
@@ -32,7 +32,6 @@ const crypto = __importStar(require("crypto"));
32
32
  const fs_1 = require("fs");
33
33
  const path = __importStar(require("path"));
34
34
  const stream_1 = require("stream");
35
- const url_1 = require("url");
36
35
  const load_esm_1 = require("./load-esm");
37
36
  class CliFilesystem {
38
37
  constructor(base) {
@@ -73,26 +72,12 @@ class CliFilesystem {
73
72
  return items;
74
73
  }
75
74
  }
76
- async function augmentAppWithServiceWorker(projectRoot, appRoot, outputPath, baseHref, ngswConfigPath) {
75
+ async function augmentAppWithServiceWorker(appRoot, outputPath, baseHref, ngswConfigPath) {
77
76
  const distPath = (0, core_1.getSystemPath)((0, core_1.normalize)(outputPath));
78
- const systemProjectRoot = (0, core_1.getSystemPath)(projectRoot);
79
- // Find the service worker package
80
- const workerPath = require.resolve('@angular/service-worker/ngsw-worker.js', {
81
- paths: [systemProjectRoot],
82
- });
83
- // Absolute paths on Windows must be `file://` URLs when using ESM. Otherwise,
84
- // `c:` would be interpreted as a protocol instead of a drive letter.
85
- const swConfigPath = (0, url_1.pathToFileURL)(require.resolve('@angular/service-worker/config', {
86
- paths: [systemProjectRoot],
87
- }));
88
77
  // Determine the configuration file path
89
- let configPath;
90
- if (ngswConfigPath) {
91
- configPath = (0, core_1.getSystemPath)((0, core_1.normalize)(ngswConfigPath));
92
- }
93
- else {
94
- configPath = path.join((0, core_1.getSystemPath)(appRoot), 'ngsw-config.json');
95
- }
78
+ const configPath = ngswConfigPath
79
+ ? (0, core_1.getSystemPath)((0, core_1.normalize)(ngswConfigPath))
80
+ : path.join((0, core_1.getSystemPath)(appRoot), 'ngsw-config.json');
96
81
  // Read the configuration file
97
82
  let config;
98
83
  try {
@@ -112,13 +97,15 @@ async function augmentAppWithServiceWorker(projectRoot, appRoot, outputPath, bas
112
97
  // Load ESM `@angular/service-worker/config` using the TypeScript dynamic import workaround.
113
98
  // Once TypeScript provides support for keeping the dynamic import this workaround can be
114
99
  // changed to a direct dynamic import.
115
- const GeneratorConstructor = (await (0, load_esm_1.loadEsmModule)(swConfigPath)).Generator;
100
+ const GeneratorConstructor = (await (0, load_esm_1.loadEsmModule)('@angular/service-worker/config')).Generator;
116
101
  // Generate the manifest
117
102
  const generator = new GeneratorConstructor(new CliFilesystem(distPath), baseHref);
118
103
  const output = await generator.process(config);
119
104
  // Write the manifest
120
105
  const manifest = JSON.stringify(output, null, 2);
121
106
  await fs_1.promises.writeFile(path.join(distPath, 'ngsw.json'), manifest);
107
+ // Find the service worker package
108
+ const workerPath = require.resolve('@angular/service-worker/ngsw-worker.js');
122
109
  // Write the worker code
123
110
  await fs_1.promises.copyFile(workerPath, path.join(distPath, 'ngsw-worker.js'), fs_1.constants.COPYFILE_FICLONE);
124
111
  // If present, write the safety worker code
@@ -15,7 +15,7 @@ import { WebpackConfigOptions } from '../utils/build-options';
15
15
  import { I18nOptions } from './i18n-options';
16
16
  export declare type BrowserWebpackConfigOptions = WebpackConfigOptions<NormalizedBrowserBuilderSchema>;
17
17
  export declare type WebpackPartialGenerator = (configurationOptions: BrowserWebpackConfigOptions) => (Promise<Configuration> | Configuration)[];
18
- export declare function generateWebpackConfig(workspaceRoot: string, projectRoot: string, sourceRoot: string | undefined, options: NormalizedBrowserBuilderSchema, webpackPartialGenerator: WebpackPartialGenerator, logger: logging.LoggerApi, extraBuildOptions: Partial<NormalizedBrowserBuilderSchema>): Promise<Configuration>;
18
+ export declare function generateWebpackConfig(workspaceRoot: string, projectRoot: string, sourceRoot: string | undefined, projectName: string, options: NormalizedBrowserBuilderSchema, webpackPartialGenerator: WebpackPartialGenerator, logger: logging.LoggerApi, extraBuildOptions: Partial<NormalizedBrowserBuilderSchema>): Promise<Configuration>;
19
19
  export declare function generateI18nBrowserWebpackConfigFromContext(options: BrowserBuilderSchema, context: BuilderContext, webpackPartialGenerator: WebpackPartialGenerator, extraBuildOptions?: Partial<NormalizedBrowserBuilderSchema>): Promise<{
20
20
  config: Configuration;
21
21
  projectRoot: string;
@@ -36,7 +36,7 @@ const utils_1 = require("../utils");
36
36
  const read_tsconfig_1 = require("../utils/read-tsconfig");
37
37
  const builder_watch_plugin_1 = require("../webpack/plugins/builder-watch-plugin");
38
38
  const i18n_options_1 = require("./i18n-options");
39
- async function generateWebpackConfig(workspaceRoot, projectRoot, sourceRoot, options, webpackPartialGenerator, logger, extraBuildOptions) {
39
+ async function generateWebpackConfig(workspaceRoot, projectRoot, sourceRoot, projectName, options, webpackPartialGenerator, logger, extraBuildOptions) {
40
40
  // Ensure Build Optimizer is only used with AOT.
41
41
  if (options.buildOptimizer && !options.aot) {
42
42
  throw new Error(`The 'buildOptimizer' option cannot be used without 'aot'.`);
@@ -54,6 +54,7 @@ async function generateWebpackConfig(workspaceRoot, projectRoot, sourceRoot, opt
54
54
  buildOptions,
55
55
  tsConfig,
56
56
  tsConfigPath,
57
+ projectName,
57
58
  scriptTarget,
58
59
  };
59
60
  wco.buildOptions.progress = (0, utils_1.defaultProgress)(wco.buildOptions.progress);
@@ -118,8 +119,8 @@ async function generateBrowserWebpackConfigFromContext(options, context, webpack
118
119
  const sourceRoot = projectSourceRoot
119
120
  ? (0, core_1.resolve)(workspaceRoot, (0, core_1.normalize)(projectSourceRoot))
120
121
  : undefined;
121
- const normalizedOptions = (0, utils_1.normalizeBrowserSchema)(workspaceRoot, projectRoot, sourceRoot, options);
122
- const config = await generateWebpackConfig((0, core_1.getSystemPath)(workspaceRoot), (0, core_1.getSystemPath)(projectRoot), sourceRoot && (0, core_1.getSystemPath)(sourceRoot), normalizedOptions, webpackPartialGenerator, context.logger, extraBuildOptions);
122
+ const normalizedOptions = (0, utils_1.normalizeBrowserSchema)(workspaceRoot, projectRoot, sourceRoot, options, projectMetadata);
123
+ const config = await generateWebpackConfig((0, core_1.getSystemPath)(workspaceRoot), (0, core_1.getSystemPath)(projectRoot), sourceRoot && (0, core_1.getSystemPath)(sourceRoot), projectName, normalizedOptions, webpackPartialGenerator, context.logger, extraBuildOptions);
123
124
  // If builder watch support is present in the context, add watch plugin
124
125
  // This is internal only and currently only used for testing
125
126
  const watcherFactory = context.watcherFactory;
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.getAnalyticsConfig = void 0;
11
11
  const analytics_1 = require("../plugins/analytics");
12
12
  function getAnalyticsConfig(wco, context) {
13
+ var _a;
13
14
  if (!context.analytics) {
14
15
  return {};
15
16
  }
@@ -21,7 +22,9 @@ function getAnalyticsConfig(wco, context) {
21
22
  }
22
23
  // The category is the builder name if it's an angular builder.
23
24
  return {
24
- plugins: [new analytics_1.NgBuildAnalyticsPlugin(wco.projectRoot, context.analytics, category, true)],
25
+ plugins: [
26
+ new analytics_1.NgBuildAnalyticsPlugin(wco.projectRoot, context.analytics, category, (_a = wco.buildOptions.aot) !== null && _a !== void 0 ? _a : false),
27
+ ],
25
28
  };
26
29
  }
27
30
  exports.getAnalyticsConfig = getAnalyticsConfig;
@@ -35,6 +35,7 @@ function getBrowserConfig(wco) {
35
35
  devtool: false,
36
36
  resolve: {
37
37
  mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'],
38
+ conditionNames: ['es2020', 'es2015', '...'],
38
39
  },
39
40
  output: {
40
41
  crossOriginLoading,
@@ -6,5 +6,5 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { Configuration } from 'webpack';
9
- import { WebpackConfigOptions } from '../../utils/build-options';
10
- export declare function getCommonConfig(wco: WebpackConfigOptions): Promise<Configuration>;
9
+ import { WebpackConfigOptions, WebpackTestOptions } from '../../utils/build-options';
10
+ export declare function getCommonConfig(wco: WebpackConfigOptions<WebpackTestOptions>): Promise<Configuration>;
@@ -37,7 +37,6 @@ const path = __importStar(require("path"));
37
37
  const typescript_1 = require("typescript");
38
38
  const webpack_1 = require("webpack");
39
39
  const utils_1 = require("../../utils");
40
- const cache_path_1 = require("../../utils/cache-path");
41
40
  const environment_options_1 = require("../../utils/environment-options");
42
41
  const load_esm_1 = require("../../utils/load-esm");
43
42
  const spinner_1 = require("../../utils/spinner");
@@ -48,8 +47,8 @@ const helpers_1 = require("../utils/helpers");
48
47
  // eslint-disable-next-line max-lines-per-function
49
48
  async function getCommonConfig(wco) {
50
49
  var _a, _b;
51
- const { root, projectRoot, buildOptions, tsConfig } = wco;
52
- const { platform = 'browser', sourceMap: { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap }, optimization: { styles: stylesOptimization, scripts: scriptsOptimization }, } = buildOptions;
50
+ const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot } = wco;
51
+ const { cache, codeCoverage, codeCoverageExclude = [], platform = 'browser', sourceMap: { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap }, optimization: { styles: stylesOptimization, scripts: scriptsOptimization }, } = buildOptions;
53
52
  const extraPlugins = [];
54
53
  const extraRules = [];
55
54
  const entryPoints = {};
@@ -283,6 +282,7 @@ async function getCommonConfig(wco) {
283
282
  context: root,
284
283
  entry: entryPoints,
285
284
  output: {
285
+ uniqueName: projectName,
286
286
  hashFunction: 'xxhash64',
287
287
  clean: (_a = buildOptions.deleteOutputPath) !== null && _a !== void 0 ? _a : true,
288
288
  path: path.resolve(root, buildOptions.outputPath),
@@ -296,9 +296,6 @@ async function getCommonConfig(wco) {
296
296
  hints: false,
297
297
  },
298
298
  ignoreWarnings: [
299
- // Webpack 5+ has no facility to disable this warning.
300
- // System.import is used in @angular/core for deprecated string-form lazy routes
301
- /System.import\(\) is deprecated and will be removed soon/i,
302
299
  // https://github.com/webpack-contrib/source-map-loader/blob/b2de4249c7431dd8432da607e08f0f65e9d64219/src/index.js#L83
303
300
  /Failed to parse source map from/,
304
301
  // https://github.com/webpack-contrib/postcss-loader/blob/bd261875fdf9c596af4ffb3a1a73fe3c549befda/src/index.js#L153-L158
@@ -308,12 +305,6 @@ async function getCommonConfig(wco) {
308
305
  // Show an error for missing exports instead of a warning.
309
306
  strictExportPresence: true,
310
307
  rules: [
311
- {
312
- // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
313
- // Removing this will cause deprecation warnings to appear.
314
- test: /[/\\]@angular[/\\]core[/\\].+\.js$/,
315
- parser: { system: true },
316
- },
317
308
  {
318
309
  // Mark files inside `rxjs/add` as containing side effects.
319
310
  // If this is fixed upstream and the fixed version becomes the minimum
@@ -330,10 +321,16 @@ async function getCommonConfig(wco) {
330
321
  {
331
322
  loader: require.resolve('../../babel/webpack-loader'),
332
323
  options: {
333
- cacheDirectory: (0, cache_path_1.findCachePath)('babel-webpack'),
324
+ cacheDirectory: (cache.enabled && path.join(cache.path, 'babel-webpack')) || false,
334
325
  scriptTarget: wco.scriptTarget,
335
326
  aot: buildOptions.aot,
336
327
  optimize: buildOptions.buildOptimizer,
328
+ instrumentCode: codeCoverage
329
+ ? {
330
+ includedBasePath: sourceRoot,
331
+ excludedPaths: (0, helpers_1.getInstrumentationExcludedPaths)(root, codeCoverageExclude),
332
+ }
333
+ : undefined,
337
334
  },
338
335
  },
339
336
  ],
@@ -355,22 +352,17 @@ async function getCommonConfig(wco) {
355
352
  chunkIds: buildOptions.namedChunks ? 'named' : 'deterministic',
356
353
  emitOnErrors: false,
357
354
  },
358
- plugins: [
359
- // Always replace the context for the System.import in angular/core to prevent warnings.
360
- // https://github.com/angular/angular/issues/11580
361
- new webpack_1.ContextReplacementPlugin(/@angular[\\/]core[\\/]/, path.join(projectRoot, '$_lazy_route_resources'), {}),
362
- new plugins_1.DedupeModuleResolvePlugin({ verbose: buildOptions.verbose }),
363
- ...extraPlugins,
364
- ],
355
+ plugins: [new plugins_1.DedupeModuleResolvePlugin({ verbose: buildOptions.verbose }), ...extraPlugins],
365
356
  };
366
357
  }
367
358
  exports.getCommonConfig = getCommonConfig;
368
359
  function getCacheSettings(wco, supportedBrowsers, angularVersion) {
369
- if (environment_options_1.persistentBuildCacheEnabled) {
360
+ const { enabled, path: cacheDirectory } = wco.buildOptions.cache;
361
+ if (enabled) {
370
362
  const packageVersion = require('../../../package.json').version;
371
363
  return {
372
364
  type: 'filesystem',
373
- cacheDirectory: (0, cache_path_1.findCachePath)('angular-webpack'),
365
+ cacheDirectory: path.join(cacheDirectory, 'angular-webpack'),
374
366
  maxMemoryGenerations: 1,
375
367
  // We use the versions and build options as the cache name. The Webpack configurations are too
376
368
  // dynamic and shared among different build types: test, build and serve.
@@ -390,7 +382,7 @@ function getCacheSettings(wco, supportedBrowsers, angularVersion) {
390
382
  .digest('hex'),
391
383
  };
392
384
  }
393
- if (wco.buildOptions.watch && !environment_options_1.cachingDisabled) {
385
+ if (wco.buildOptions.watch) {
394
386
  return {
395
387
  type: 'memory',
396
388
  maxGenerations: 1,
@@ -27,32 +27,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.getTestConfig = void 0;
30
- const glob = __importStar(require("glob"));
31
30
  const path = __importStar(require("path"));
32
31
  const typescript_1 = require("typescript");
33
32
  const helpers_1 = require("../utils/helpers");
34
33
  function getTestConfig(wco) {
35
- const { buildOptions: { codeCoverage, codeCoverageExclude, main, sourceMap, webWorkerTsConfig }, root, sourceRoot, } = wco;
36
- const extraRules = [];
34
+ const { buildOptions: { main, sourceMap, webWorkerTsConfig }, root, } = wco;
37
35
  const extraPlugins = [];
38
- if (codeCoverage) {
39
- const exclude = [/\.(e2e|spec)\.tsx?$/, /node_modules/];
40
- if (codeCoverageExclude) {
41
- for (const excludeGlob of codeCoverageExclude) {
42
- glob
43
- .sync(path.join(root, excludeGlob), { nodir: true })
44
- .forEach((file) => exclude.push(path.normalize(file)));
45
- }
46
- }
47
- extraRules.push({
48
- test: /\.[cm]?[tj]sx?$/,
49
- loader: require.resolve('@jsdevtools/coverage-istanbul-loader'),
50
- options: { esModules: true },
51
- enforce: 'post',
52
- exclude,
53
- include: sourceRoot,
54
- });
55
- }
56
36
  if (sourceMap.scripts || sourceMap.styles) {
57
37
  extraPlugins.push((0, helpers_1.getSourceMapDevTool)(sourceMap.scripts, sourceMap.styles, false, true));
58
38
  }
@@ -61,13 +41,13 @@ function getTestConfig(wco) {
61
41
  target: wco.tsConfig.options.target === typescript_1.ScriptTarget.ES5 ? ['web', 'es5'] : 'web',
62
42
  resolve: {
63
43
  mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'],
44
+ conditionNames: ['es2020', 'es2015', '...'],
64
45
  },
65
46
  devtool: false,
66
47
  entry: {
67
48
  main: path.resolve(root, main),
68
49
  },
69
50
  module: {
70
- rules: extraRules,
71
51
  parser: webWorkerTsConfig === undefined
72
52
  ? {
73
53
  javascript: {
@@ -40,10 +40,10 @@ export declare class NgBuildAnalyticsPlugin {
40
40
  protected _projectRoot: string;
41
41
  protected _analytics: analytics.Analytics;
42
42
  protected _category: string;
43
- private _isIvy;
43
+ private aotEnabled;
44
44
  protected _built: boolean;
45
45
  protected _stats: AnalyticsBuildStats;
46
- constructor(_projectRoot: string, _analytics: analytics.Analytics, _category: string, _isIvy: boolean);
46
+ constructor(_projectRoot: string, _analytics: analytics.Analytics, _category: string, aotEnabled: boolean);
47
47
  protected _reset(): void;
48
48
  protected _getMetrics(stats: Stats): (string | number)[];
49
49
  protected _getDimensions(): (string | number | boolean)[];
@@ -73,11 +73,11 @@ class AnalyticsBuildStats {
73
73
  * Analytics plugin that reports the analytics we want from the CLI.
74
74
  */
75
75
  class NgBuildAnalyticsPlugin {
76
- constructor(_projectRoot, _analytics, _category, _isIvy) {
76
+ constructor(_projectRoot, _analytics, _category, aotEnabled) {
77
77
  this._projectRoot = _projectRoot;
78
78
  this._analytics = _analytics;
79
79
  this._category = _category;
80
- this._isIvy = _isIvy;
80
+ this.aotEnabled = aotEnabled;
81
81
  this._built = false;
82
82
  this._stats = new AnalyticsBuildStats();
83
83
  }
@@ -108,7 +108,7 @@ class NgBuildAnalyticsPlugin {
108
108
  // Adding commas before and after so the regex are easier to define filters.
109
109
  dimensions[core_1.analytics.NgCliAnalyticsDimensions.BuildErrors] = `,${this._stats.errors.join()},`;
110
110
  }
111
- dimensions[core_1.analytics.NgCliAnalyticsDimensions.NgIvyEnabled] = this._isIvy;
111
+ dimensions[core_1.analytics.NgCliAnalyticsDimensions.AotEnabled] = this.aotEnabled;
112
112
  return dimensions;
113
113
  }
114
114
  _reportBuildMetrics(stats) {
@@ -20,3 +20,4 @@ export declare function getSourceMapDevTool(scriptsSourceMap: boolean | undefine
20
20
  export declare function isPolyfillsEntry(name: string): boolean;
21
21
  export declare function getWatchOptions(poll: number | undefined): NonNullable<Configuration['watchOptions']>;
22
22
  export declare function assetNameTemplateFactory(hashFormat: HashFormat): (resourcePath: string) => string;
23
+ export declare function getInstrumentationExcludedPaths(sourceRoot: string, excludedPaths: string[]): Set<string>;
@@ -25,8 +25,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  __setModuleDefault(result, mod);
26
26
  return result;
27
27
  };
28
+ var __importDefault = (this && this.__importDefault) || function (mod) {
29
+ return (mod && mod.__esModule) ? mod : { "default": mod };
30
+ };
28
31
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.assetNameTemplateFactory = exports.getWatchOptions = exports.isPolyfillsEntry = exports.getSourceMapDevTool = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
32
+ exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.getWatchOptions = exports.isPolyfillsEntry = exports.getSourceMapDevTool = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
33
+ const glob_1 = __importDefault(require("glob"));
30
34
  const path = __importStar(require("path"));
31
35
  const webpack_1 = require("webpack");
32
36
  function getOutputHashFormat(option, length = 20) {
@@ -126,3 +130,13 @@ function assetNameTemplateFactory(hashFormat) {
126
130
  };
127
131
  }
128
132
  exports.assetNameTemplateFactory = assetNameTemplateFactory;
133
+ function getInstrumentationExcludedPaths(sourceRoot, excludedPaths) {
134
+ const excluded = new Set();
135
+ for (const excludeGlob of excludedPaths) {
136
+ glob_1.default
137
+ .sync(path.join(sourceRoot, excludeGlob), { nodir: true })
138
+ .forEach((p) => excluded.add(path.normalize(p)));
139
+ }
140
+ return excluded;
141
+ }
142
+ exports.getInstrumentationExcludedPaths = getInstrumentationExcludedPaths;
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC 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
- export declare function findCachePath(name: string): string;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
- var __importDefault = (this && this.__importDefault) || function (mod) {
10
- return (mod && mod.__esModule) ? mod : { "default": mod };
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.findCachePath = void 0;
14
- const find_cache_dir_1 = __importDefault(require("find-cache-dir"));
15
- const os_1 = require("os");
16
- const path_1 = require("path");
17
- const environment_options_1 = require("./environment-options");
18
- function findCachePath(name) {
19
- if (environment_options_1.cachingBasePath) {
20
- return (0, path_1.resolve)(environment_options_1.cachingBasePath, name);
21
- }
22
- return (0, find_cache_dir_1.default)({ name }) || (0, os_1.tmpdir)();
23
- }
24
- exports.findCachePath = findCachePath;