@angular-devkit/build-angular 14.1.0-next.0 → 14.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 (34) hide show
  1. package/builders.json +1 -1
  2. package/package.json +24 -24
  3. package/src/babel/webpack-loader.js +3 -3
  4. package/src/builders/app-shell/index.js +4 -2
  5. package/src/builders/browser/index.d.ts +9 -1
  6. package/src/builders/browser/index.js +19 -3
  7. package/src/builders/browser-esbuild/experimental-warnings.js +0 -3
  8. package/src/builders/browser-esbuild/index.d.ts +2 -2
  9. package/src/builders/browser-esbuild/index.js +21 -7
  10. package/src/builders/browser-esbuild/schema.d.ts +428 -0
  11. package/src/builders/browser-esbuild/schema.js +58 -0
  12. package/src/builders/browser-esbuild/schema.json +542 -0
  13. package/src/builders/extract-i18n/index.js +3 -1
  14. package/src/builders/karma/index.js +2 -2
  15. package/src/builders/protractor/index.js +2 -0
  16. package/src/builders/server/index.d.ts +8 -1
  17. package/src/builders/server/index.js +7 -0
  18. package/src/sass/worker.js +1 -0
  19. package/src/utils/color.js +0 -1
  20. package/src/utils/error.d.ts +10 -0
  21. package/src/utils/error.js +18 -0
  22. package/src/utils/i18n-inlining.js +3 -0
  23. package/src/utils/i18n-options.js +11 -19
  24. package/src/utils/process-bundle.js +8 -8
  25. package/src/utils/service-worker.js +3 -0
  26. package/src/webpack/configs/dev-server.js +6 -0
  27. package/src/webpack/plugins/index-html-webpack-plugin.js +2 -0
  28. package/src/webpack/plugins/json-stats-plugin.js +2 -0
  29. package/src/webpack/plugins/postcss-cli-resources.js +2 -0
  30. package/src/webpack/plugins/typescript.js +1 -5
  31. package/src/webpack/utils/helpers.d.ts +1 -2
  32. package/src/webpack/utils/helpers.js +3 -2
  33. package/src/webpack/utils/stats.d.ts +3 -2
  34. package/src/webpack/utils/stats.js +22 -5
@@ -35,6 +35,7 @@ const fs = __importStar(require("fs"));
35
35
  const path = __importStar(require("path"));
36
36
  const action_executor_1 = require("./action-executor");
37
37
  const copy_assets_1 = require("./copy-assets");
38
+ const error_1 = require("./error");
38
39
  const spinner_1 = require("./spinner");
39
40
  function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emittedPath, outputPath, es5, missingTranslation, context) {
40
41
  const options = [];
@@ -61,6 +62,7 @@ function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emitte
61
62
  originalFiles.push(originalMapPath);
62
63
  }
63
64
  catch (err) {
65
+ (0, error_1.assertIsError)(err);
64
66
  if (err.code !== 'ENOENT') {
65
67
  throw err;
66
68
  }
@@ -102,6 +104,7 @@ async function i18nInlineEmittedFiles(context, emittedFiles, i18n, baseOutputPat
102
104
  ], outputPaths, '');
103
105
  }
104
106
  catch (err) {
107
+ (0, error_1.assertIsError)(err);
105
108
  spinner.fail('Localized bundle generation failed: ' + err.message);
106
109
  return false;
107
110
  }
@@ -146,12 +146,12 @@ async function configureI18nBuild(context, options) {
146
146
  if (first) {
147
147
  localeDataPath = findLocaleDataPath(first.toLowerCase(), localeResolver);
148
148
  if (localeDataPath) {
149
- context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
149
+ context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
150
150
  }
151
151
  }
152
152
  }
153
153
  if (!localeDataPath) {
154
- context.logger.warn(`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`);
154
+ context.logger.warn(`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`);
155
155
  }
156
156
  else {
157
157
  desc.dataPath = localeDataPath;
@@ -175,13 +175,15 @@ async function configureI18nBuild(context, options) {
175
175
  }
176
176
  // If inlining store the output in a temporary location to facilitate post-processing
177
177
  if (i18n.shouldInline) {
178
+ // TODO: we should likely save these in the .angular directory in the next major version.
179
+ // We'd need to do a migration to add the temp directory to gitignore.
178
180
  const tempPath = fs_1.default.mkdtempSync(path_1.default.join(fs_1.default.realpathSync(os_1.default.tmpdir()), 'angular-cli-i18n-'));
179
181
  buildOptions.outputPath = tempPath;
180
- process.on('exit', () => deleteTempDirectory(tempPath));
181
- process.once('SIGINT', () => {
182
- deleteTempDirectory(tempPath);
183
- // Needed due to `ora` as otherwise process will not terminate.
184
- process.kill(process.pid, 'SIGINT');
182
+ process.on('exit', () => {
183
+ try {
184
+ fs_1.default.rmSync(tempPath, { force: true, recursive: true, maxRetries: 3 });
185
+ }
186
+ catch { }
185
187
  });
186
188
  }
187
189
  return { buildOptions, i18n };
@@ -194,19 +196,9 @@ function findLocaleDataPath(locale, resolver) {
194
196
  return resolver(scrubbedLocale);
195
197
  }
196
198
  catch {
197
- if (scrubbedLocale === 'en-US') {
198
- // fallback to known existing en-US locale data as of 9.0
199
- return findLocaleDataPath('en-US-POSIX', resolver);
200
- }
201
- return null;
202
- }
203
- }
204
- /** Remove temporary directory used for i18n processing. */
205
- function deleteTempDirectory(tempPath) {
206
- try {
207
- fs_1.default.rmSync(tempPath, { force: true, recursive: true, maxRetries: 3 });
199
+ // fallback to known existing en-US locale data as of 14.0
200
+ return scrubbedLocale === 'en-US' ? findLocaleDataPath('en', resolver) : null;
208
201
  }
209
- catch { }
210
202
  }
211
203
  function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedFormats, duplicateTranslation) {
212
204
  let translations = undefined;
@@ -41,6 +41,7 @@ const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const worker_threads_1 = require("worker_threads");
43
43
  const environment_options_1 = require("./environment-options");
44
+ const error_1 = require("./error");
44
45
  const load_esm_1 = require("./load-esm");
45
46
  // Lazy loaded webpack-sources object
46
47
  // Webpack is only imported if needed during the processing
@@ -124,14 +125,13 @@ async function inlineLocales(options) {
124
125
  });
125
126
  }
126
127
  catch (error) {
127
- if (error.message) {
128
- // Make the error more readable.
129
- // Same errors will contain the full content of the file as the error message
130
- // Which makes it hard to find the actual error message.
131
- const index = error.message.indexOf(')\n');
132
- const msg = index !== -1 ? error.message.slice(0, index + 1) : error.message;
133
- throw new Error(`${msg}\nAn error occurred inlining file "${options.filename}"`);
134
- }
128
+ (0, error_1.assertIsError)(error);
129
+ // Make the error more readable.
130
+ // Same errors will contain the full content of the file as the error message
131
+ // Which makes it hard to find the actual error message.
132
+ const index = error.message.indexOf(')\n');
133
+ const msg = index !== -1 ? error.message.slice(0, index + 1) : error.message;
134
+ throw new Error(`${msg}\nAn error occurred inlining file "${options.filename}"`);
135
135
  }
136
136
  if (!ast) {
137
137
  throw new Error(`Unknown error occurred inlining file "${options.filename}"`);
@@ -35,6 +35,7 @@ const crypto = __importStar(require("crypto"));
35
35
  const fs_1 = require("fs");
36
36
  const path = __importStar(require("path"));
37
37
  const stream_1 = require("stream");
38
+ const error_1 = require("./error");
38
39
  const load_esm_1 = require("./load-esm");
39
40
  class CliFilesystem {
40
41
  constructor(base) {
@@ -87,6 +88,7 @@ async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, b
87
88
  config = JSON.parse(configurationData);
88
89
  }
89
90
  catch (error) {
91
+ (0, error_1.assertIsError)(error);
90
92
  if (error.code === 'ENOENT') {
91
93
  throw new Error('Error: Expected to find an ngsw-config.json configuration file' +
92
94
  ` in the ${appRoot} folder. Either provide one or` +
@@ -117,6 +119,7 @@ async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, b
117
119
  await fs_1.promises.copyFile(safetyPath, path.join(outputPath, 'safety-worker.js'), fs_1.constants.COPYFILE_FICLONE);
118
120
  }
119
121
  catch (error) {
122
+ (0, error_1.assertIsError)(error);
120
123
  if (error.code !== 'ENOENT') {
121
124
  throw error;
122
125
  }
@@ -35,6 +35,7 @@ const core_1 = require("@angular-devkit/core");
35
35
  const fs_1 = require("fs");
36
36
  const path_1 = require("path");
37
37
  const url_1 = require("url");
38
+ const error_1 = require("../../utils/error");
38
39
  const load_esm_1 = require("../../utils/load-esm");
39
40
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
40
41
  const hmr_loader_1 = require("../plugins/hmr/hmr-loader");
@@ -85,6 +86,10 @@ async function getDevServerConfig(wco) {
85
86
  },
86
87
  ],
87
88
  },
89
+ // When setupExitSignals is enabled webpack-dev-server will shutdown gracefully which would
90
+ // require CTRL+C to be pressed multiple times to exit.
91
+ // See: https://github.com/webpack/webpack-dev-server/blob/c76b6d11a3821436c5e20207c8a38deb6ab7e33c/lib/Server.js#L1801-L1827
92
+ setupExitSignals: false,
88
93
  compress: false,
89
94
  static: false,
90
95
  server: getServerConfig(root, wco.buildOptions),
@@ -187,6 +192,7 @@ async function addProxyConfig(root, proxyConfig) {
187
192
  return require(proxyPath);
188
193
  }
189
194
  catch (e) {
195
+ (0, error_1.assertIsError)(e);
190
196
  if (e.code === 'ERR_REQUIRE_ESM') {
191
197
  // Load the ESM configuration file using the TypeScript dynamic import workaround.
192
198
  // Once TypeScript provides support for keeping the dynamic import this workaround can be
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.IndexHtmlWebpackPlugin = void 0;
11
11
  const path_1 = require("path");
12
12
  const webpack_1 = require("webpack");
13
+ const error_1 = require("../../utils/error");
13
14
  const index_html_generator_1 = require("../../utils/index-file/index-html-generator");
14
15
  const webpack_diagnostics_1 = require("../../utils/webpack-diagnostics");
15
16
  const PLUGIN_NAME = 'index-html-webpack-plugin';
@@ -58,6 +59,7 @@ class IndexHtmlWebpackPlugin extends index_html_generator_1.IndexHtmlGenerator {
58
59
  errors.forEach((msg) => (0, webpack_diagnostics_1.addError)(this.compilation, msg));
59
60
  }
60
61
  catch (error) {
62
+ (0, error_1.assertIsError)(error);
61
63
  (0, webpack_diagnostics_1.addError)(this.compilation, error.message);
62
64
  }
63
65
  };
@@ -33,6 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
33
33
  exports.JsonStatsPlugin = void 0;
34
34
  const fs_1 = require("fs");
35
35
  const path_1 = require("path");
36
+ const error_1 = require("../../utils/error");
36
37
  const webpack_diagnostics_1 = require("../../utils/webpack-diagnostics");
37
38
  class JsonStatsPlugin {
38
39
  constructor(statsOutputPath) {
@@ -50,6 +51,7 @@ class JsonStatsPlugin {
50
51
  .on('error', reject));
51
52
  }
52
53
  catch (error) {
54
+ (0, error_1.assertIsError)(error);
53
55
  (0, webpack_diagnostics_1.addError)(stats.compilation, `Unable to write stats file: ${error.message || 'unknown error'}`);
54
56
  }
55
57
  });
@@ -34,6 +34,7 @@ exports.postcss = void 0;
34
34
  const loader_utils_1 = require("loader-utils");
35
35
  const path = __importStar(require("path"));
36
36
  const url = __importStar(require("url"));
37
+ const error_1 = require("../../utils/error");
37
38
  function wrapUrl(url) {
38
39
  let wrappedUrl;
39
40
  const hasSingleQuotes = url.indexOf("'") >= 0;
@@ -146,6 +147,7 @@ function default_1(options) {
146
147
  processedUrl = await process(originalUrl, context, resourceCache);
147
148
  }
148
149
  catch (err) {
150
+ (0, error_1.assertIsError)(err);
149
151
  loader.emitError(decl.error(err.message, { word: originalUrl }));
150
152
  continue;
151
153
  }
@@ -20,7 +20,6 @@ function ensureIvy(wco) {
20
20
  '\nFor additional information or if the build fails, please see https://angular.io/guide/ivy');
21
21
  wco.tsConfig.options.enableIvy = true;
22
22
  }
23
- let es5TargetWarningsShown = false;
24
23
  function createIvyPlugin(wco, aot, tsconfig) {
25
24
  if (aot) {
26
25
  ensureIvy(wco);
@@ -40,10 +39,7 @@ function createIvyPlugin(wco, aot, tsconfig) {
40
39
  // as for third-party libraries. This greatly reduces the complexity of static analysis.
41
40
  if (wco.scriptTarget < typescript_1.ScriptTarget.ES2015) {
42
41
  compilerOptions.target = typescript_1.ScriptTarget.ES2015;
43
- if (!es5TargetWarningsShown) {
44
- wco.logger.warn('DEPRECATED: ES5 output is deprecated. Please update TypeScript `target` compiler option to ES2015 or later.');
45
- es5TargetWarningsShown = true;
46
- }
42
+ wco.logger.warn('DEPRECATED: ES5 output is deprecated. Please update TypeScript `target` compiler option to ES2015 or later.');
47
43
  }
48
44
  const fileReplacements = {};
49
45
  if (buildOptions.fileReplacements) {
@@ -16,6 +16,7 @@ export interface HashFormat {
16
16
  file: string;
17
17
  script: string;
18
18
  }
19
+ export declare type WebpackStatsOptions = Exclude<Configuration['stats'], string | boolean | undefined>;
19
20
  export declare function getOutputHashFormat(outputHashing?: OutputHashing, length?: number): HashFormat;
20
21
  export declare type NormalizedEntryPoint = Required<Exclude<ScriptElement | StyleElement, string>>;
21
22
  export declare function normalizeExtraEntryPoints(extraEntryPoints: (ScriptElement | StyleElement)[], defaultBundleName: string): NormalizedEntryPoint[];
@@ -29,7 +30,5 @@ export declare function globalScriptsByBundleName(root: string, scripts: ScriptE
29
30
  }[];
30
31
  export declare function assetPatterns(root: string, assets: AssetPatternClass[]): ObjectPattern[];
31
32
  export declare function externalizePackages(context: string, request: string | undefined, callback: (error?: Error, result?: string) => void): void;
32
- declare type WebpackStatsOptions = Exclude<Configuration['stats'], string | boolean>;
33
33
  export declare function getStatsOptions(verbose?: boolean): WebpackStatsOptions;
34
34
  export declare function getMainFieldsAndConditionNames(target: ScriptTarget, platformServer: boolean): Pick<WebpackOptionsNormalized['resolve'], 'mainFields' | 'conditionNames'>;
35
- export {};
@@ -125,8 +125,8 @@ function getInstrumentationExcludedPaths(sourceRoot, excludedPaths) {
125
125
  const excluded = new Set();
126
126
  for (const excludeGlob of excludedPaths) {
127
127
  glob_1.default
128
- .sync(path.join(sourceRoot, excludeGlob), { nodir: true })
129
- .forEach((p) => excluded.add(path.normalize(p)));
128
+ .sync(excludeGlob, { nodir: true, cwd: sourceRoot })
129
+ .forEach((p) => excluded.add(path.join(sourceRoot, p)));
130
130
  }
131
131
  return excluded;
132
132
  }
@@ -278,6 +278,7 @@ function getStatsOptions(verbose = false) {
278
278
  version: true,
279
279
  chunkModules: true,
280
280
  errorDetails: true,
281
+ errorStack: true,
281
282
  moduleTrace: true,
282
283
  logging: 'verbose',
283
284
  modulesSpace: Infinity,
@@ -10,6 +10,7 @@ import { logging } from '@angular-devkit/core';
10
10
  import { Configuration, StatsCompilation } from 'webpack';
11
11
  import { Schema as BrowserBuilderOptions } from '../../builders/browser/schema';
12
12
  import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
13
+ import { WebpackStatsOptions } from './helpers';
13
14
  export declare function formatSize(size: number): string;
14
15
  export declare type BundleStatsData = [
15
16
  files: string,
@@ -29,8 +30,8 @@ export declare function generateBundleStats(info: {
29
30
  initial?: boolean;
30
31
  rendered?: boolean;
31
32
  }): BundleStats;
32
- export declare function statsWarningsToString(json: StatsCompilation, statsConfig: any): string;
33
- export declare function statsErrorsToString(json: StatsCompilation, statsConfig: any): string;
33
+ export declare function statsWarningsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
34
+ export declare function statsErrorsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
34
35
  export declare function statsHasErrors(json: StatsCompilation): boolean;
35
36
  export declare function statsHasWarnings(json: StatsCompilation): boolean;
36
37
  export declare function createWebpackLoggingCallback(options: BrowserBuilderOptions, logger: logging.LoggerApi): WebpackLoggingCallback;
@@ -261,7 +261,6 @@ statsConfig, budgetFailures) {
261
261
  `));
262
262
  }
263
263
  }
264
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
264
  function statsWarningsToString(json, statsConfig) {
266
265
  const colors = statsConfig.colors;
267
266
  const c = (x) => (colors ? color_1.colors.reset.cyan(x) : x);
@@ -294,8 +293,8 @@ function statsWarningsToString(json, statsConfig) {
294
293
  return output ? '\n' + output : output;
295
294
  }
296
295
  exports.statsWarningsToString = statsWarningsToString;
297
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
296
  function statsErrorsToString(json, statsConfig) {
297
+ var _a, _b;
299
298
  const colors = statsConfig.colors;
300
299
  const c = (x) => (colors ? color_1.colors.reset.cyan(x) : x);
301
300
  const yb = (x) => (colors ? color_1.colors.reset.yellowBright(x) : x);
@@ -310,7 +309,16 @@ function statsErrorsToString(json, statsConfig) {
310
309
  output += r(`Error: ${error}\n\n`);
311
310
  }
312
311
  else {
313
- const file = error.file || error.moduleName;
312
+ let file = error.file || error.moduleName;
313
+ // Clean up error paths
314
+ // Ex: ./src/app/styles.scss.webpack[javascript/auto]!=!./node_modules/css-loader/dist/cjs.js....
315
+ // to ./src/app/styles.scss.webpack
316
+ if (file && !statsConfig.errorDetails) {
317
+ const webpackPathIndex = file.indexOf('.webpack[');
318
+ if (webpackPathIndex !== -1) {
319
+ file = file.substring(0, webpackPathIndex);
320
+ }
321
+ }
314
322
  if (file) {
315
323
  output += c(file);
316
324
  if (error.loc) {
@@ -318,10 +326,16 @@ function statsErrorsToString(json, statsConfig) {
318
326
  }
319
327
  output += ' - ';
320
328
  }
321
- if (!/^error/i.test(error.message)) {
329
+ // In most cases webpack will add stack traces to error messages.
330
+ // This below cleans up the error from stacks.
331
+ // See: https://github.com/webpack/webpack/issues/15980
332
+ const message = statsConfig.errorStack
333
+ ? error.message
334
+ : (_b = (_a = /[\s\S]+?(?=[\n\s]+at)/.exec(error.message)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : error.message;
335
+ if (!/^error/i.test(message)) {
322
336
  output += r('Error: ');
323
337
  }
324
- output += `${error.message}\n\n`;
338
+ output += `${message}\n\n`;
325
339
  }
326
340
  }
327
341
  return output ? '\n' + output : output;
@@ -358,6 +372,9 @@ function createWebpackLoggingCallback(options, logger) {
358
372
  exports.createWebpackLoggingCallback = createWebpackLoggingCallback;
359
373
  function webpackStatsLogger(logger, json, config, budgetFailures) {
360
374
  logger.info(statsToString(json, config.stats, budgetFailures));
375
+ if (typeof config.stats !== 'object') {
376
+ throw new Error('Invalid Webpack stats configuration.');
377
+ }
361
378
  if (statsHasWarnings(json)) {
362
379
  logger.warn(statsWarningsToString(json, config.stats));
363
380
  }