@angular-devkit/build-angular 13.0.4 → 13.1.0-next.3

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 (57) hide show
  1. package/package.json +37 -37
  2. package/src/babel/presets/application.d.ts +1 -0
  3. package/src/babel/webpack-loader.js +9 -0
  4. package/src/builders/browser/index.js +7 -9
  5. package/src/builders/dev-server/index.js +31 -6
  6. package/src/builders/extract-i18n/index.js +1 -4
  7. package/src/builders/karma/index.d.ts +2 -2
  8. package/src/builders/karma/index.js +1 -7
  9. package/src/builders/server/index.js +1 -7
  10. package/src/utils/build-options.d.ts +1 -2
  11. package/src/utils/bundle-calculator.d.ts +6 -7
  12. package/src/utils/bundle-calculator.js +3 -1
  13. package/src/utils/i18n-inlining.js +18 -2
  14. package/src/utils/i18n-options.d.ts +16 -10
  15. package/src/utils/i18n-options.js +45 -34
  16. package/src/utils/index-file/augment-index-html.d.ts +5 -1
  17. package/src/utils/index-file/augment-index-html.js +25 -5
  18. package/src/utils/index.d.ts +0 -1
  19. package/src/utils/index.js +0 -1
  20. package/src/utils/normalize-builder-schema.js +2 -0
  21. package/src/{webpack/configs/worker.d.ts → utils/supported-browsers.d.ts} +1 -3
  22. package/src/utils/supported-browsers.js +26 -0
  23. package/src/webpack/configs/common.d.ts +2 -2
  24. package/src/webpack/configs/common.js +135 -158
  25. package/src/webpack/configs/dev-server.d.ts +2 -2
  26. package/src/webpack/configs/dev-server.js +74 -19
  27. package/src/webpack/configs/index.d.ts +0 -6
  28. package/src/webpack/configs/index.js +0 -6
  29. package/src/webpack/configs/styles.d.ts +2 -2
  30. package/src/webpack/configs/styles.js +2 -4
  31. package/src/webpack/plugins/index.d.ts +2 -0
  32. package/src/webpack/plugins/index.js +5 -1
  33. package/src/webpack/plugins/json-stats-plugin.d.ts +13 -0
  34. package/src/webpack/plugins/json-stats-plugin.js +54 -0
  35. package/src/webpack/plugins/named-chunks-plugin.d.ts +17 -0
  36. package/src/webpack/plugins/named-chunks-plugin.js +49 -0
  37. package/src/webpack/plugins/progress-plugin.d.ts +11 -0
  38. package/src/webpack/plugins/progress-plugin.js +38 -0
  39. package/src/webpack/plugins/transfer-size-plugin.d.ts +12 -0
  40. package/src/webpack/plugins/transfer-size-plugin.js +47 -0
  41. package/src/webpack/{configs/browser.d.ts → plugins/typescript.d.ts} +2 -2
  42. package/src/webpack/{configs → plugins}/typescript.js +5 -24
  43. package/src/webpack/utils/helpers.d.ts +15 -5
  44. package/src/webpack/utils/helpers.js +159 -34
  45. package/src/webpack/utils/stats.d.ts +10 -3
  46. package/src/webpack/utils/stats.js +112 -35
  47. package/src/utils/build-browser-features.d.ts +0 -16
  48. package/src/utils/build-browser-features.js +0 -54
  49. package/src/webpack/configs/browser.js +0 -81
  50. package/src/webpack/configs/server.d.ts +0 -14
  51. package/src/webpack/configs/server.js +0 -73
  52. package/src/webpack/configs/stats.d.ts +0 -38
  53. package/src/webpack/configs/stats.js +0 -53
  54. package/src/webpack/configs/test.d.ts +0 -10
  55. package/src/webpack/configs/test.js +0 -77
  56. package/src/webpack/configs/typescript.d.ts +0 -12
  57. package/src/webpack/configs/worker.js +0 -22
package/package.json CHANGED
@@ -1,85 +1,85 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "13.0.4",
3
+ "version": "13.1.0-next.3",
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
- "@ampproject/remapping": "1.0.1",
10
- "@angular-devkit/architect": "0.1300.4",
11
- "@angular-devkit/build-webpack": "0.1300.4",
12
- "@angular-devkit/core": "13.0.4",
13
- "@babel/core": "7.15.8",
14
- "@babel/generator": "7.15.8",
15
- "@babel/helper-annotate-as-pure": "7.15.4",
16
- "@babel/plugin-proposal-async-generator-functions": "7.15.8",
17
- "@babel/plugin-transform-async-to-generator": "7.14.5",
18
- "@babel/plugin-transform-runtime": "7.15.8",
19
- "@babel/preset-env": "7.15.8",
20
- "@babel/runtime": "7.15.4",
21
- "@babel/template": "7.15.4",
22
- "@discoveryjs/json-ext": "0.5.5",
23
- "@ngtools/webpack": "13.0.4",
9
+ "@ampproject/remapping": "1.0.2",
10
+ "@angular-devkit/architect": "0.1301.0-next.3",
11
+ "@angular-devkit/build-webpack": "0.1301.0-next.3",
12
+ "@angular-devkit/core": "13.1.0-next.3",
13
+ "@babel/core": "7.16.0",
14
+ "@babel/generator": "7.16.0",
15
+ "@babel/helper-annotate-as-pure": "7.16.0",
16
+ "@babel/plugin-proposal-async-generator-functions": "7.16.4",
17
+ "@babel/plugin-transform-async-to-generator": "7.16.0",
18
+ "@babel/plugin-transform-runtime": "7.16.4",
19
+ "@babel/preset-env": "7.16.4",
20
+ "@babel/runtime": "7.16.3",
21
+ "@babel/template": "7.16.0",
22
+ "@discoveryjs/json-ext": "0.5.6",
23
+ "@ngtools/webpack": "13.1.0-next.3",
24
24
  "ansi-colors": "4.1.1",
25
25
  "babel-loader": "8.2.3",
26
26
  "babel-plugin-istanbul": "6.1.1",
27
27
  "browserslist": "^4.9.1",
28
28
  "cacache": "15.3.0",
29
- "caniuse-lite": "^1.0.30001032",
30
29
  "circular-dependency-plugin": "5.2.2",
31
- "copy-webpack-plugin": "9.0.1",
32
- "core-js": "3.19.0",
33
- "critters": "0.0.14",
34
- "css-loader": "6.5.0",
35
- "esbuild-wasm": "0.13.12",
30
+ "copy-webpack-plugin": "10.0.0",
31
+ "core-js": "3.19.2",
32
+ "critters": "0.0.15",
33
+ "css-loader": "6.5.1",
34
+ "esbuild-wasm": "0.14.1",
36
35
  "glob": "7.2.0",
37
36
  "https-proxy-agent": "5.0.0",
38
37
  "inquirer": "8.2.0",
38
+ "jsonc-parser": "3.0.0",
39
39
  "karma-source-map-support": "1.4.0",
40
40
  "less": "4.1.2",
41
41
  "less-loader": "10.2.0",
42
42
  "license-webpack-plugin": "4.0.0",
43
- "loader-utils": "3.0.0",
44
- "mini-css-extract-plugin": "2.4.3",
43
+ "loader-utils": "3.2.0",
44
+ "mini-css-extract-plugin": "2.4.5",
45
45
  "minimatch": "3.0.4",
46
46
  "open": "8.4.0",
47
47
  "ora": "5.4.1",
48
48
  "parse5-html-rewriting-stream": "6.0.1",
49
49
  "piscina": "3.1.0",
50
- "postcss": "8.3.11",
50
+ "postcss": "8.4.4",
51
51
  "postcss-import": "14.0.2",
52
- "postcss-loader": "6.2.0",
52
+ "postcss-loader": "6.2.1",
53
53
  "postcss-preset-env": "6.7.0",
54
54
  "regenerator-runtime": "0.13.9",
55
55
  "resolve-url-loader": "4.0.0",
56
56
  "rxjs": "6.6.7",
57
- "sass": "1.43.4",
57
+ "sass": "1.44.0",
58
58
  "sass-loader": "12.3.0",
59
59
  "semver": "7.3.5",
60
60
  "source-map-loader": "3.0.0",
61
- "source-map-support": "0.5.20",
61
+ "source-map-support": "0.5.21",
62
62
  "stylus": "0.55.0",
63
63
  "stylus-loader": "6.2.0",
64
- "terser": "5.9.0",
64
+ "terser": "5.10.0",
65
65
  "text-table": "0.2.0",
66
66
  "tree-kill": "1.2.2",
67
67
  "tslib": "2.3.1",
68
- "webpack": "5.64.1",
69
- "webpack-dev-middleware": "5.2.1",
70
- "webpack-dev-server": "4.4.0",
68
+ "webpack": "5.64.4",
69
+ "webpack-dev-middleware": "5.2.2",
70
+ "webpack-dev-server": "4.6.0",
71
71
  "webpack-merge": "5.8.0",
72
72
  "webpack-subresource-integrity": "5.0.0"
73
73
  },
74
74
  "optionalDependencies": {
75
- "esbuild": "0.13.12"
75
+ "esbuild": "0.14.1"
76
76
  },
77
77
  "peerDependencies": {
78
- "@angular/compiler-cli": "^13.0.0",
79
- "@angular/localize": "^13.0.0",
80
- "@angular/service-worker": "^13.0.0",
78
+ "@angular/compiler-cli": "^13.0.0 || ^13.1.0-next",
79
+ "@angular/localize": "^13.0.0 || ^13.1.0-next",
80
+ "@angular/service-worker": "^13.0.0 || ^13.1.0-next",
81
81
  "karma": "^6.3.0",
82
- "ng-packagr": "^13.0.0",
82
+ "ng-packagr": "^13.0.0 || ^13.1.0-next",
83
83
  "protractor": "^7.0.0",
84
84
  "tailwindcss": "^2.0.0",
85
85
  "typescript": "~4.4.3"
@@ -23,6 +23,7 @@ export interface ApplicationPresetOptions {
23
23
  locale: string;
24
24
  missingTranslationBehavior?: 'error' | 'warning' | 'ignore';
25
25
  translation?: unknown;
26
+ translationFiles?: string[];
26
27
  pluginCreators?: I18nPluginCreators;
27
28
  };
28
29
  angularLinker?: {
@@ -41,6 +41,7 @@ async function requiresLinking(path, source) {
41
41
  }
42
42
  return needsLinking(path, source);
43
43
  }
44
+ // eslint-disable-next-line max-lines-per-function
44
45
  exports.default = (0, babel_loader_1.custom)(() => {
45
46
  const baseOptions = Object.freeze({
46
47
  babelrc: false,
@@ -118,6 +119,14 @@ exports.default = (0, babel_loader_1.custom)(() => {
118
119
  ...i18n,
119
120
  pluginCreators: i18nPluginCreators,
120
121
  };
122
+ // Add translation files as dependencies of the file to support rebuilds
123
+ // Except for `@angular/core` which needs locale injection but has no translations
124
+ if (customOptions.i18n.translationFiles &&
125
+ !/[\\/]@angular[\\/]core/.test(this.resourcePath)) {
126
+ for (const file of customOptions.i18n.translationFiles) {
127
+ this.addDependency(file);
128
+ }
129
+ }
121
130
  shouldProcess = true;
122
131
  }
123
132
  if (optimize) {
@@ -46,6 +46,7 @@ const output_paths_1 = require("../../utils/output-paths");
46
46
  const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
47
47
  const service_worker_1 = require("../../utils/service-worker");
48
48
  const spinner_1 = require("../../utils/spinner");
49
+ const supported_browsers_1 = require("../../utils/supported-browsers");
49
50
  const version_1 = require("../../utils/version");
50
51
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
51
52
  const configs_1 = require("../../webpack/configs");
@@ -59,12 +60,8 @@ async function initialize(options, context, webpackConfigurationTransform) {
59
60
  const adjustedOptions = options.watch ? options : { ...options, assets: [] };
60
61
  const { config, projectRoot, projectSourceRoot, i18n, target } = await (0, webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext)(adjustedOptions, context, (wco) => [
61
62
  (0, configs_1.getCommonConfig)(wco),
62
- (0, configs_1.getBrowserConfig)(wco),
63
63
  (0, configs_1.getStylesConfig)(wco),
64
- (0, configs_1.getStatsConfig)(wco),
65
64
  (0, configs_1.getAnalyticsConfig)(wco, context),
66
- (0, configs_1.getTypeScriptConfig)(wco),
67
- wco.buildOptions.webWorkerTsConfig ? (0, configs_1.getWorkerConfig)(wco) : {},
68
65
  ]);
69
66
  // Validate asset option values if processed directly
70
67
  if (((_a = options.assets) === null || _a === void 0 ? void 0 : _a.length) && !((_b = adjustedOptions.assets) === null || _b === void 0 ? void 0 : _b.length)) {
@@ -101,8 +98,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
101
98
  return (0, rxjs_1.from)(context.getProjectMetadata(projectName)).pipe((0, operators_1.switchMap)(async (projectMetadata) => {
102
99
  var _a;
103
100
  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 : '')));
104
- const buildBrowserFeatures = new utils_1.BuildBrowserFeatures(sysProjectRoot);
105
- checkInternetExplorerSupport(buildBrowserFeatures.supportedBrowsers, context.logger);
101
+ checkInternetExplorerSupport(sysProjectRoot, context.logger);
106
102
  return {
107
103
  ...(await initialize(options, context, transforms.webpackConfiguration)),
108
104
  cacheOptions: (0, normalize_cache_1.normalizeCacheOptions)(projectMetadata, context.workspaceRoot),
@@ -159,8 +155,9 @@ function buildWebpackBrowser(options, context, transforms = {}) {
159
155
  }
160
156
  // Check for budget errors and display them to the user.
161
157
  const budgets = options.budgets;
158
+ let budgetFailures;
162
159
  if (budgets === null || budgets === void 0 ? void 0 : budgets.length) {
163
- const budgetFailures = (0, bundle_calculator_1.checkBudgets)(budgets, webpackStats);
160
+ budgetFailures = [...(0, bundle_calculator_1.checkBudgets)(budgets, webpackStats)];
164
161
  for (const { severity, message } of budgetFailures) {
165
162
  switch (severity) {
166
163
  case bundle_calculator_1.ThresholdSeverity.Warning:
@@ -254,7 +251,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
254
251
  spinner.succeed('Service worker generation complete.');
255
252
  }
256
253
  }
257
- (0, stats_1.webpackStatsLogger)(context.logger, webpackStats, config);
254
+ (0, stats_1.webpackStatsLogger)(context.logger, webpackStats, config, budgetFailures);
258
255
  return { success: buildSuccess };
259
256
  }
260
257
  }), (0, operators_1.map)((event) => ({
@@ -294,7 +291,8 @@ function mapEmittedFilesToFileInfo(files = []) {
294
291
  }
295
292
  return filteredFiles;
296
293
  }
297
- function checkInternetExplorerSupport(supportedBrowsers, logger) {
294
+ function checkInternetExplorerSupport(projectRoot, logger) {
295
+ const supportedBrowsers = (0, supported_browsers_1.getSupportedBrowsers)(projectRoot);
298
296
  if (supportedBrowsers.some((b) => b === 'ie 9' || b === 'ie 10' || b === 'ie 11')) {
299
297
  logger.warn(`Warning: Support was requested for Internet Explorer in the project's browserslist configuration. ` +
300
298
  'Internet Explorer is no longer officially supported.' +
@@ -37,10 +37,13 @@ const url = __importStar(require("url"));
37
37
  const utils_1 = require("../../utils");
38
38
  const check_port_1 = require("../../utils/check-port");
39
39
  const color_1 = require("../../utils/color");
40
+ const i18n_options_1 = require("../../utils/i18n-options");
41
+ const load_translations_1 = require("../../utils/load-translations");
40
42
  const normalize_cache_1 = require("../../utils/normalize-cache");
41
43
  const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
42
44
  const version_1 = require("../../utils/version");
43
45
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
46
+ const webpack_diagnostics_1 = require("../../utils/webpack-diagnostics");
44
47
  const configs_1 = require("../../webpack/configs");
45
48
  const index_html_webpack_plugin_1 = require("../../webpack/plugins/index-html-webpack-plugin");
46
49
  const stats_1 = require("../../webpack/utils/stats");
@@ -124,12 +127,8 @@ function serveWebpackBrowser(options, context, transforms = {}) {
124
127
  const { config, projectRoot, i18n } = await (0, webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext)(browserOptions, context, (wco) => [
125
128
  (0, configs_1.getDevServerConfig)(wco),
126
129
  (0, configs_1.getCommonConfig)(wco),
127
- (0, configs_1.getBrowserConfig)(wco),
128
130
  (0, configs_1.getStylesConfig)(wco),
129
- (0, configs_1.getStatsConfig)(wco),
130
131
  (0, configs_1.getAnalyticsConfig)(wco, context),
131
- (0, configs_1.getTypeScriptConfig)(wco),
132
- browserOptions.webWorkerTsConfig ? (0, configs_1.getWorkerConfig)(wco) : {},
133
132
  ], options);
134
133
  if (!config.devServer) {
135
134
  throw new Error('Webpack Dev Server configuration was not set.');
@@ -149,7 +148,7 @@ function serveWebpackBrowser(options, context, transforms = {}) {
149
148
  if (i18n.inlineLocales.size > 1) {
150
149
  throw new Error('The development server only supports localizing a single locale per build.');
151
150
  }
152
- await setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions);
151
+ await setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions, context);
153
152
  }
154
153
  if (transforms.webpackConfiguration) {
155
154
  webpackConfig = await transforms.webpackConfiguration(webpackConfig);
@@ -224,7 +223,7 @@ function serveWebpackBrowser(options, context, transforms = {}) {
224
223
  }));
225
224
  }
226
225
  exports.serveWebpackBrowser = serveWebpackBrowser;
227
- async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions) {
226
+ async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheOptions, context) {
228
227
  var _a;
229
228
  const localeDescription = i18n.locales[locale];
230
229
  // Modify main entrypoint to include locale data
@@ -252,6 +251,7 @@ async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheO
252
251
  locale,
253
252
  missingTranslationBehavior,
254
253
  translation: i18n.shouldInline ? translation : undefined,
254
+ translationFiles: localeDescription === null || localeDescription === void 0 ? void 0 : localeDescription.files.map((file) => path.resolve(context.workspaceRoot, file.path)),
255
255
  };
256
256
  const i18nRule = {
257
257
  test: /\.[cm]?[tj]sx?$/,
@@ -280,5 +280,30 @@ async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheO
280
280
  webpackConfig.module.rules = rules;
281
281
  }
282
282
  rules.push(i18nRule);
283
+ // Add a plugin to reload translation files on rebuilds
284
+ const loader = await (0, load_translations_1.createTranslationLoader)();
285
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
286
+ webpackConfig.plugins.push({
287
+ apply: (compiler) => {
288
+ compiler.hooks.thisCompilation.tap('build-angular', (compilation) => {
289
+ if (i18n.shouldInline && i18nLoaderOptions.translation === undefined) {
290
+ // Reload translations
291
+ (0, i18n_options_1.loadTranslations)(locale, localeDescription, context.workspaceRoot, loader, {
292
+ warn(message) {
293
+ (0, webpack_diagnostics_1.addWarning)(compilation, message);
294
+ },
295
+ error(message) {
296
+ (0, webpack_diagnostics_1.addError)(compilation, message);
297
+ },
298
+ });
299
+ i18nLoaderOptions.translation = localeDescription.translation;
300
+ }
301
+ compilation.hooks.finishModules.tap('build-angular', () => {
302
+ // After loaders are finished, clear out the now unneeded translations
303
+ i18nLoaderOptions.translation = undefined;
304
+ });
305
+ });
306
+ },
307
+ });
283
308
  }
284
309
  exports.default = (0, architect_1.createBuilder)(serveWebpackBrowser);
@@ -166,6 +166,7 @@ async function execute(options, context, transforms) {
166
166
  subresourceIntegrity: false,
167
167
  outputHashing: schema_1.OutputHashing.None,
168
168
  namedChunks: true,
169
+ allowedCommonJsDependencies: undefined,
169
170
  };
170
171
  const { config, projectRoot } = await (0, webpack_browser_config_1.generateBrowserWebpackConfigFromContext)(builderOptions, context, (wco) => {
171
172
  var _a;
@@ -174,10 +175,6 @@ async function execute(options, context, transforms) {
174
175
  const partials = [
175
176
  { plugins: [new NoEmitPlugin()] },
176
177
  (0, configs_1.getCommonConfig)(wco),
177
- (0, configs_1.getBrowserConfig)(wco),
178
- (0, configs_1.getTypeScriptConfig)(wco),
179
- (0, configs_1.getWorkerConfig)(wco),
180
- (0, configs_1.getStatsConfig)(wco),
181
178
  ];
182
179
  // Add Ivy application file extractor support
183
180
  partials.unshift({
@@ -8,7 +8,7 @@
8
8
  import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
9
9
  import { ConfigOptions } from 'karma';
10
10
  import { Observable } from 'rxjs';
11
- import * as webpack from 'webpack';
11
+ import { Configuration } from 'webpack';
12
12
  import { ExecutionTransformer } from '../../transforms';
13
13
  import { Schema as KarmaBuilderOptions } from './schema';
14
14
  export declare type KarmaConfigOptions = ConfigOptions & {
@@ -19,7 +19,7 @@ export declare type KarmaConfigOptions = ConfigOptions & {
19
19
  * @experimental Direct usage of this function is considered experimental.
20
20
  */
21
21
  export declare function execute(options: KarmaBuilderOptions, context: BuilderContext, transforms?: {
22
- webpackConfiguration?: ExecutionTransformer<webpack.Configuration>;
22
+ webpackConfiguration?: ExecutionTransformer<Configuration>;
23
23
  karmaOptions?: (options: KarmaConfigOptions) => KarmaConfigOptions;
24
24
  }): Observable<BuilderOutput>;
25
25
  export { KarmaBuilderOptions };
@@ -59,13 +59,7 @@ async function initialize(options, context, webpackConfigurationTransformer) {
59
59
  // https://github.com/webpack/webpack-dev-middleware/blob/698c9ae5e9bb9a013985add6189ff21c1a1ec185/src/index.js#L65
60
60
  // https://github.com/webpack/webpack/blob/cde1b73e12eb8a77eb9ba42e7920c9ec5d29c2c9/lib/Compiler.js#L379-L388
61
61
  watch: true,
62
- }, context, (wco) => [
63
- (0, configs_1.getCommonConfig)(wco),
64
- (0, configs_1.getStylesConfig)(wco),
65
- (0, configs_1.getTypeScriptConfig)(wco),
66
- (0, configs_1.getTestConfig)(wco),
67
- (0, configs_1.getWorkerConfig)(wco),
68
- ]);
62
+ }, context, (wco) => [(0, configs_1.getCommonConfig)(wco), (0, configs_1.getStylesConfig)(wco)]);
69
63
  const karma = await Promise.resolve().then(() => __importStar(require('karma')));
70
64
  return [
71
65
  karma,
@@ -109,13 +109,7 @@ async function initialize(options, context, webpackConfigurationTransform) {
109
109
  buildOptimizer: false,
110
110
  aot: true,
111
111
  platform: 'server',
112
- }, context, (wco) => [
113
- (0, configs_1.getCommonConfig)(wco),
114
- (0, configs_1.getServerConfig)(wco),
115
- (0, configs_1.getStylesConfig)(wco),
116
- (0, configs_1.getStatsConfig)(wco),
117
- (0, configs_1.getTypeScriptConfig)(wco),
118
- ]);
112
+ }, context, (wco) => [(0, configs_1.getCommonConfig)(wco), (0, configs_1.getStylesConfig)(wco)]);
119
113
  let transformedConfig;
120
114
  if (webpackConfigurationTransform) {
121
115
  transformedConfig = await webpackConfigurationTransform(config);
@@ -59,10 +59,9 @@ export interface BuildOptions {
59
59
  inlineStyleLanguage?: InlineStyleLanguage;
60
60
  allowedCommonJsDependencies?: string[];
61
61
  cache: NormalizedCachedOptions;
62
- }
63
- export interface WebpackTestOptions extends BuildOptions {
64
62
  codeCoverage?: boolean;
65
63
  codeCoverageExclude?: string[];
64
+ supportedBrowsers: string[];
66
65
  }
67
66
  export interface WebpackDevServerOptions extends BuildOptions, Omit<DevServerSchema, 'optimization' | 'sourceMap' | 'browserTarget'> {
68
67
  }
@@ -20,13 +20,12 @@ export declare enum ThresholdSeverity {
20
20
  Warning = "warning",
21
21
  Error = "error"
22
22
  }
23
- export declare function calculateThresholds(budget: Budget): IterableIterator<Threshold>;
24
- export declare function checkBudgets(budgets: Budget[], webpackStats: StatsCompilation): IterableIterator<{
25
- severity: ThresholdSeverity;
26
- message: string;
27
- }>;
28
- export declare function checkThresholds(thresholds: IterableIterator<Threshold>, size: number, label?: string): IterableIterator<{
23
+ export interface BudgetCalculatorResult {
29
24
  severity: ThresholdSeverity;
30
25
  message: string;
31
- }>;
26
+ label?: string;
27
+ }
28
+ export declare function calculateThresholds(budget: Budget): IterableIterator<Threshold>;
29
+ export declare function checkBudgets(budgets: Budget[], webpackStats: StatsCompilation): IterableIterator<BudgetCalculatorResult>;
30
+ export declare function checkThresholds(thresholds: IterableIterator<Threshold>, size: number, label?: string): IterableIterator<BudgetCalculatorResult>;
32
31
  export {};
@@ -143,7 +143,7 @@ class BundleCalculator extends Calculator {
143
143
  .filter((chunk) => { var _a; return (_a = chunk === null || chunk === void 0 ? void 0 : chunk.names) === null || _a === void 0 ? void 0 : _a.includes(budgetName); })
144
144
  .map((chunk) => this.calculateChunkSize(chunk))
145
145
  .reduce((l, r) => l + r, 0);
146
- return [{ size, label: `bundle ${this.budget.name}` }];
146
+ return [{ size, label: this.budget.name }];
147
147
  }
148
148
  }
149
149
  /**
@@ -262,6 +262,7 @@ function* checkThresholds(thresholds, size, label) {
262
262
  const sizeDifference = (0, stats_1.formatSize)(size - threshold.limit);
263
263
  yield {
264
264
  severity: threshold.severity,
265
+ label,
265
266
  message: `${label} exceeded maximum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
266
267
  };
267
268
  break;
@@ -273,6 +274,7 @@ function* checkThresholds(thresholds, size, label) {
273
274
  const sizeDifference = (0, stats_1.formatSize)(threshold.limit - size);
274
275
  yield {
275
276
  severity: threshold.severity,
277
+ label,
276
278
  message: `${label} failed to meet minimum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
277
279
  };
278
280
  break;
@@ -32,7 +32,7 @@ const path = __importStar(require("path"));
32
32
  const action_executor_1 = require("./action-executor");
33
33
  const copy_assets_1 = require("./copy-assets");
34
34
  const spinner_1 = require("./spinner");
35
- function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emittedPath, outputPath, es5, missingTranslation) {
35
+ function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emittedPath, outputPath, es5, missingTranslation, context) {
36
36
  const options = [];
37
37
  const originalFiles = [];
38
38
  for (const emittedFile of emittedFiles) {
@@ -51,16 +51,31 @@ function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emitte
51
51
  setLocale: emittedFile.name === 'main' || emittedFile.name === 'vendor',
52
52
  };
53
53
  originalFiles.push(originalPath);
54
+ // Remove temporary original file as the content has now been read
55
+ try {
56
+ fs.unlinkSync(originalPath);
57
+ }
58
+ catch (e) {
59
+ context.logger.debug(`Unable to delete i18n temporary file [${originalPath}]: ${e.toString()}`);
60
+ }
54
61
  try {
55
62
  const originalMapPath = originalPath + '.map';
56
63
  action.map = fs.readFileSync(originalMapPath, 'utf8');
57
64
  originalFiles.push(originalMapPath);
65
+ // Remove temporary original map file as the content has now been read
66
+ try {
67
+ fs.unlinkSync(originalMapPath);
68
+ }
69
+ catch (e) {
70
+ context.logger.debug(`Unable to delete i18n temporary file [${originalMapPath}]: ${e.toString()}`);
71
+ }
58
72
  }
59
73
  catch (err) {
60
74
  if (err.code !== 'ENOENT') {
61
75
  throw err;
62
76
  }
63
77
  }
78
+ context.logger.debug(`i18n file queued for processing: ${action.filename}`);
64
79
  options.push(action);
65
80
  }
66
81
  return { options, originalFiles };
@@ -71,8 +86,9 @@ async function i18nInlineEmittedFiles(context, emittedFiles, i18n, baseOutputPat
71
86
  const spinner = new spinner_1.Spinner();
72
87
  spinner.start('Generating localized bundles...');
73
88
  try {
74
- const { options, originalFiles: processedFiles } = emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emittedPath, baseOutputPath, es5, missingTranslation);
89
+ const { options, originalFiles: processedFiles } = emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emittedPath, baseOutputPath, es5, missingTranslation, context);
75
90
  for await (const result of executor.inlineAll(options)) {
91
+ context.logger.debug(`i18n file processed: ${result.file}`);
76
92
  for (const diagnostic of result.diagnostics) {
77
93
  spinner.stop();
78
94
  if (diagnostic.type === 'error') {
@@ -9,19 +9,21 @@ import { BuilderContext } from '@angular-devkit/architect';
9
9
  import { json } from '@angular-devkit/core';
10
10
  import { Schema as BrowserBuilderSchema } from '../builders/browser/schema';
11
11
  import { Schema as ServerBuilderSchema } from '../builders/server/schema';
12
+ import { TranslationLoader } from './load-translations';
13
+ export interface LocaleDescription {
14
+ files: {
15
+ path: string;
16
+ integrity?: string;
17
+ format?: string;
18
+ }[];
19
+ translation?: Record<string, unknown>;
20
+ dataPath?: string;
21
+ baseHref?: string;
22
+ }
12
23
  export interface I18nOptions {
13
24
  inlineLocales: Set<string>;
14
25
  sourceLocale: string;
15
- locales: Record<string, {
16
- files: {
17
- path: string;
18
- integrity?: string;
19
- format?: string;
20
- }[];
21
- translation?: Record<string, unknown>;
22
- dataPath?: string;
23
- baseHref?: string;
24
- }>;
26
+ locales: Record<string, LocaleDescription>;
25
27
  flatOutput?: boolean;
26
28
  readonly shouldInline: boolean;
27
29
  hasDefinedSourceLocale?: boolean;
@@ -31,3 +33,7 @@ export declare function configureI18nBuild<T extends BrowserBuilderSchema | Serv
31
33
  buildOptions: T;
32
34
  i18n: I18nOptions;
33
35
  }>;
36
+ export declare function loadTranslations(locale: string, desc: LocaleDescription, workspaceRoot: string, loader: TranslationLoader, logger: {
37
+ warn: (message: string) => void;
38
+ error: (message: string) => void;
39
+ }, usedFormats?: Set<string>): void;
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.configureI18nBuild = exports.createI18nOptions = void 0;
13
+ exports.loadTranslations = exports.configureI18nBuild = exports.createI18nOptions = void 0;
14
14
  const core_1 = require("@angular-devkit/core");
15
15
  const fs_1 = __importDefault(require("fs"));
16
16
  const module_1 = __importDefault(require("module"));
@@ -161,39 +161,17 @@ async function configureI18nBuild(context, options) {
161
161
  if (!loader) {
162
162
  loader = await (0, load_translations_1.createTranslationLoader)();
163
163
  }
164
- for (const file of desc.files) {
165
- const loadResult = loader(path_1.default.join(context.workspaceRoot, file.path));
166
- for (const diagnostics of loadResult.diagnostics.messages) {
167
- if (diagnostics.type === 'error') {
168
- throw new Error(`Error parsing translation file '${file.path}': ${diagnostics.message}`);
169
- }
170
- else {
171
- context.logger.warn(`WARNING [${file.path}]: ${diagnostics.message}`);
172
- }
173
- }
174
- if (loadResult.locale !== undefined && loadResult.locale !== locale) {
175
- context.logger.warn(`WARNING [${file.path}]: File target locale ('${loadResult.locale}') does not match configured locale ('${locale}')`);
176
- }
177
- usedFormats.add(loadResult.format);
178
- if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
179
- // This limitation is only for legacy message id support (defaults to true as of 9.0)
180
- throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
181
- }
182
- file.format = loadResult.format;
183
- file.integrity = loadResult.integrity;
184
- if (desc.translation) {
185
- // Merge translations
186
- for (const [id, message] of Object.entries(loadResult.translations)) {
187
- if (desc.translation[id] !== undefined) {
188
- context.logger.warn(`WARNING [${file.path}]: Duplicate translations for message '${id}' when merging`);
189
- }
190
- desc.translation[id] = message;
191
- }
192
- }
193
- else {
194
- // First or only translation file
195
- desc.translation = loadResult.translations;
196
- }
164
+ loadTranslations(locale, desc, context.workspaceRoot, loader, {
165
+ warn(message) {
166
+ context.logger.warn(message);
167
+ },
168
+ error(message) {
169
+ throw new Error(message);
170
+ },
171
+ }, usedFormats);
172
+ if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
173
+ // This limitation is only for legacy message id support (defaults to true as of 9.0)
174
+ throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
197
175
  }
198
176
  }
199
177
  // If inlining store the output in a temporary location to facilitate post-processing
@@ -225,3 +203,36 @@ function findLocaleDataPath(locale, resolver) {
225
203
  return null;
226
204
  }
227
205
  }
206
+ function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedFormats) {
207
+ for (const file of desc.files) {
208
+ const loadResult = loader(path_1.default.join(workspaceRoot, file.path));
209
+ for (const diagnostics of loadResult.diagnostics.messages) {
210
+ if (diagnostics.type === 'error') {
211
+ logger.error(`Error parsing translation file '${file.path}': ${diagnostics.message}`);
212
+ }
213
+ else {
214
+ logger.warn(`WARNING [${file.path}]: ${diagnostics.message}`);
215
+ }
216
+ }
217
+ if (loadResult.locale !== undefined && loadResult.locale !== locale) {
218
+ logger.warn(`WARNING [${file.path}]: File target locale ('${loadResult.locale}') does not match configured locale ('${locale}')`);
219
+ }
220
+ usedFormats === null || usedFormats === void 0 ? void 0 : usedFormats.add(loadResult.format);
221
+ file.format = loadResult.format;
222
+ file.integrity = loadResult.integrity;
223
+ if (desc.translation) {
224
+ // Merge translations
225
+ for (const [id, message] of Object.entries(loadResult.translations)) {
226
+ if (desc.translation[id] !== undefined) {
227
+ logger.warn(`WARNING [${file.path}]: Duplicate translations for message '${id}' when merging`);
228
+ }
229
+ desc.translation[id] = message;
230
+ }
231
+ }
232
+ else {
233
+ // First or only translation file
234
+ desc.translation = loadResult.translations;
235
+ }
236
+ }
237
+ }
238
+ exports.loadTranslations = loadTranslations;
@@ -27,4 +27,8 @@ export interface FileInfo {
27
27
  name: string;
28
28
  extension: string;
29
29
  }
30
- export declare function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise<string>;
30
+ export declare function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise<{
31
+ content: string;
32
+ warnings: string[];
33
+ errors: string[];
34
+ }>;