@angular-devkit/build-angular 0.900.3 → 0.900.7

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.
package/package.json CHANGED
@@ -1,31 +1,31 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "0.900.3",
3
+ "version": "0.900.7",
4
4
  "description": "Angular Webpack Build Facade",
5
5
  "experimental": true,
6
6
  "main": "src/index.js",
7
7
  "typings": "src/index.d.ts",
8
8
  "builders": "builders.json",
9
9
  "dependencies": {
10
- "@angular-devkit/architect": "0.900.3",
11
- "@angular-devkit/build-optimizer": "0.900.3",
12
- "@angular-devkit/build-webpack": "0.900.3",
13
- "@angular-devkit/core": "9.0.3",
10
+ "@angular-devkit/architect": "0.900.7",
11
+ "@angular-devkit/build-optimizer": "0.900.7",
12
+ "@angular-devkit/build-webpack": "0.900.7",
13
+ "@angular-devkit/core": "9.0.7",
14
14
  "@babel/core": "7.7.7",
15
15
  "@babel/generator": "7.7.7",
16
16
  "@babel/preset-env": "7.7.7",
17
- "@ngtools/webpack": "9.0.3",
17
+ "@ngtools/webpack": "9.0.7",
18
18
  "ajv": "6.10.2",
19
19
  "autoprefixer": "9.7.1",
20
20
  "babel-loader": "8.0.6",
21
- "browserslist": "4.8.3",
21
+ "browserslist": "^4.9.1",
22
22
  "cacache": "13.0.1",
23
- "caniuse-lite": "1.0.30001020",
23
+ "caniuse-lite": "^1.0.30001032",
24
24
  "cssnano": "4.1.10",
25
25
  "circular-dependency-plugin": "5.2.0",
26
26
  "coverage-istanbul-loader": "2.0.3",
27
27
  "copy-webpack-plugin": "5.1.1",
28
- "core-js": "3.6.0",
28
+ "core-js": "3.6.4",
29
29
  "file-loader": "4.2.0",
30
30
  "find-cache-dir": "3.0.0",
31
31
  "glob": "7.1.5",
@@ -11,7 +11,6 @@ const build_optimizer_1 = require("@angular-devkit/build-optimizer");
11
11
  const core_1 = require("@angular-devkit/core");
12
12
  const CopyWebpackPlugin = require("copy-webpack-plugin");
13
13
  const fs_1 = require("fs");
14
- const os_1 = require("os");
15
14
  const path = require("path");
16
15
  const typescript_1 = require("typescript");
17
16
  const webpack_1 = require("webpack");
@@ -103,10 +102,11 @@ function getCommonConfig(wco) {
103
102
  // The webpack.Compilation assetPath hook is a noop in 4.x so the template must be used
104
103
  // tslint:disable-next-line: no-any
105
104
  compilation.mainTemplate.hooks.assetPath.tap('build-angular', (filename, data) => {
106
- const isMap = filename && filename.endsWith('.map');
105
+ const assetName = typeof filename === 'function' ? filename(data) : filename;
106
+ const isMap = assetName && assetName.endsWith('.map');
107
107
  return data.chunk && data.chunk.name === 'polyfills-es5'
108
108
  ? `polyfills-es5${hashFormat.chunk}.js${isMap ? '.map' : ''}`
109
- : filename;
109
+ : assetName;
110
110
  });
111
111
  });
112
112
  },
@@ -331,14 +331,9 @@ function getCommonConfig(wco) {
331
331
  // Name mangling is handled within the browser builder
332
332
  mangle: environment_options_1.allowMangle && buildOptions.platform !== 'server' && !differentialLoadingMode,
333
333
  };
334
- // Use up to 7 CPUs for Terser workers, but no more.
335
- // Some environments, like CircleCI, report a large number of CPUs but trying to use them
336
- // Will cause `Error: Call retries were exceeded` errors.
337
- // https://github.com/webpack-contrib/terser-webpack-plugin/issues/143
338
- const maxCpus = Math.min(os_1.cpus().length, 7);
339
334
  extraMinimizers.push(new TerserPlugin({
340
335
  sourceMap: scriptsSourceMap,
341
- parallel: maxCpus,
336
+ parallel: utils_1.maxWorkers,
342
337
  cache: !environment_options_1.cachingDisabled && cache_path_1.findCachePath('terser-webpack'),
343
338
  extractComments: false,
344
339
  chunkFilter: (chunk) => !globalScriptsByBundleName.some(s => s.bundleName === chunk.name),
@@ -348,7 +343,7 @@ function getCommonConfig(wco) {
348
343
  // They are shared between ES2015 & ES5 outputs so must support ES5.
349
344
  new TerserPlugin({
350
345
  sourceMap: scriptsSourceMap,
351
- parallel: maxCpus,
346
+ parallel: utils_1.maxWorkers,
352
347
  cache: !environment_options_1.cachingDisabled && cache_path_1.findCachePath('terser-webpack'),
353
348
  extractComments: false,
354
349
  chunkFilter: (chunk) => globalScriptsByBundleName.some(s => s.bundleName === chunk.name),
@@ -423,14 +418,6 @@ function getCommonConfig(wco) {
423
418
  test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
424
419
  parser: { system: true },
425
420
  },
426
- {
427
- test: /[\/\\]hot[\/\\]emitter\.js$/,
428
- parser: { node: { events: true } },
429
- },
430
- {
431
- test: /[\/\\]webpack-dev-server[\/\\]client[\/\\]utils[\/\\]createSocketUrl\.js$/,
432
- parser: { node: { querystring: true } },
433
- },
434
421
  {
435
422
  test: /\.js$/,
436
423
  // Factory files are processed by BO in the rules added in typescript.ts.
@@ -111,6 +111,11 @@ function getStylesConfig(wco) {
111
111
  // bootstrap-sass requires a minimum precision of 8
112
112
  precision: 8,
113
113
  includePaths,
114
+ // Use expanded as otherwise sass will remove comments that are needed for autoprefixer
115
+ // Ex: /* autoprefixer grid: autoplace */
116
+ // tslint:disable-next-line: max-line-length
117
+ // See: https://github.com/webpack-contrib/sass-loader/blob/45ad0be17264ceada5f0b4fb87e9357abe85c4ff/src/getSassOptions.js#L68-L70
118
+ outputStyle: 'expanded',
114
119
  },
115
120
  },
116
121
  },
@@ -7,6 +7,7 @@
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ const path = require("path");
10
11
  const schema_1 = require("../../../src/browser/schema");
11
12
  const bundle_calculator_1 = require("../utilities/bundle-calculator");
12
13
  const PLUGIN_NAME = 'AnyComponentStyleBudgetChecker';
@@ -27,8 +28,15 @@ class AnyComponentStyleBudgetChecker {
27
28
  if (!parentCompilation) {
28
29
  return;
29
30
  }
31
+ const cssExtensions = [
32
+ '.css',
33
+ '.scss',
34
+ '.less',
35
+ '.styl',
36
+ '.sass',
37
+ ];
30
38
  const componentStyles = Object.keys(compilation.assets)
31
- .filter((name) => name.endsWith('.css'))
39
+ .filter((name) => cssExtensions.includes(path.extname(name)))
32
40
  .map((name) => ({
33
41
  size: compilation.assets[name].size(),
34
42
  label: name,
@@ -120,16 +120,15 @@ class Calculator {
120
120
  else {
121
121
  // No differential builds, get the chunk size by summing its assets.
122
122
  return chunk.files
123
- .filter((file) => !file.endsWith('.map'))
124
- .map((file) => {
123
+ .filter(file => !file.endsWith('.map'))
124
+ .map(file => {
125
125
  const asset = this.assets.find((asset) => asset.name === file);
126
126
  if (!asset) {
127
127
  throw new Error(`Could not find asset for file: ${file}`);
128
128
  }
129
- return asset;
129
+ return asset.size;
130
130
  })
131
- .map((asset) => asset.size)
132
- .reduce((l, r) => l + r);
131
+ .reduce((l, r) => l + r, 0);
133
132
  }
134
133
  }
135
134
  }
@@ -147,8 +146,8 @@ class BundleCalculator extends Calculator {
147
146
  const buildSizes = Object.values(DifferentialBuildType).map((buildType) => {
148
147
  const size = this.chunks
149
148
  .filter(chunk => chunk.names.indexOf(budgetName) !== -1)
150
- .map((chunk) => this.calculateChunkSize(chunk, buildType))
151
- .reduce((l, r) => l + r);
149
+ .map(chunk => this.calculateChunkSize(chunk, buildType))
150
+ .reduce((l, r) => l + r, 0);
152
151
  return { size, label: `${this.budget.name}-${buildType}` };
153
152
  });
154
153
  // If this bundle was not actually generated by a differential build, then
@@ -171,8 +170,8 @@ class InitialCalculator extends Calculator {
171
170
  label: `initial-${buildType}`,
172
171
  size: this.chunks
173
172
  .filter(chunk => chunk.initial)
174
- .map((chunk) => this.calculateChunkSize(chunk, buildType))
175
- .reduce((l, r) => l + r),
173
+ .map(chunk => this.calculateChunkSize(chunk, buildType))
174
+ .reduce((l, r) => l + r, 0),
176
175
  };
177
176
  });
178
177
  // If this bundle was not actually generated by a differential build, then
@@ -191,7 +190,7 @@ class InitialCalculator extends Calculator {
191
190
  class AllScriptCalculator extends Calculator {
192
191
  calculate() {
193
192
  const size = this.assets
194
- .filter((asset) => asset.name.endsWith('.js'))
193
+ .filter(asset => asset.name.endsWith('.js'))
195
194
  .map(asset => asset.size)
196
195
  .reduce((total, size) => total + size, 0);
197
196
  return [{ size, label: 'total scripts' }];
@@ -136,6 +136,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
136
136
  }).pipe(
137
137
  // tslint:disable-next-line: no-big-function
138
138
  operators_1.concatMap(async (buildEvent) => {
139
+ var _a, _b;
139
140
  const { webpackStats: webpackRawStats, success, emittedFiles = [] } = buildEvent;
140
141
  if (!webpackRawStats) {
141
142
  throw new Error('Webpack stats build result is required.');
@@ -245,7 +246,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
245
246
  fs.unlinkSync(filename + '.map');
246
247
  }
247
248
  }
248
- catch (_a) { }
249
+ catch (_c) { }
249
250
  }
250
251
  if (es5Polyfills) {
251
252
  fs.unlinkSync(filename);
@@ -467,9 +468,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
467
468
  for (const [locale, outputPath] of outputPaths.entries()) {
468
469
  let localeBaseHref;
469
470
  if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
470
- localeBaseHref = path.posix.join(options.baseHref || '', i18n.locales[locale].baseHref === undefined
471
- ? `/${locale}/`
472
- : i18n.locales[locale].baseHref);
471
+ localeBaseHref = utils_1.urlJoin(options.baseHref || '', (_a = i18n.locales[locale].baseHref, (_a !== null && _a !== void 0 ? _a : `/${locale}/`)));
473
472
  }
474
473
  try {
475
474
  await generateIndex(outputPath, options, root, files, noModuleFiles, moduleFiles, transforms.indexHtml,
@@ -485,9 +484,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
485
484
  for (const [locale, outputPath] of outputPaths.entries()) {
486
485
  let localeBaseHref;
487
486
  if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
488
- localeBaseHref = path.posix.join(options.baseHref || '', i18n.locales[locale].baseHref === undefined
489
- ? `/${locale}/`
490
- : i18n.locales[locale].baseHref);
487
+ localeBaseHref = utils_1.urlJoin(options.baseHref || '', (_b = i18n.locales[locale].baseHref, (_b !== null && _b !== void 0 ? _b : `/${locale}/`)));
491
488
  }
492
489
  try {
493
490
  await service_worker_1.augmentAppWithServiceWorker(host, root, core_1.normalize(projectRoot), core_1.normalize(outputPath), localeBaseHref || options.baseHref || '/', options.ngswConfigPath);
@@ -211,7 +211,7 @@
211
211
  "minItems": 1,
212
212
  "items": {
213
213
  "type": "string",
214
- "pattern": "^[a-z]{2}(-[a-zA-Z]{2,})?$"
214
+ "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$"
215
215
  }
216
216
  }
217
217
  ]
@@ -412,19 +412,31 @@ function _addLiveReload(options, browserOptions, webpackConfig, clientAddress, l
412
412
  if (webpackConfig.plugins === undefined) {
413
413
  webpackConfig.plugins = [];
414
414
  }
415
- // Enable the internal node plugins but no individual shims
416
- // This is needed to allow module specific rules to include node shims
415
+ // Workaround node shim hoisting issues with live reload client
417
416
  // Only needed in dev server mode to support live reload capabilities in all package managers
418
- if (webpackConfig.node === false) {
419
- webpackConfig.node = {
420
- global: false,
421
- process: false,
422
- __filename: false,
423
- __dirname: false,
424
- Buffer: false,
425
- setImmediate: false,
426
- };
427
- }
417
+ const webpackPath = path.dirname(require.resolve('webpack/package.json'));
418
+ const nodeLibsBrowserPath = require.resolve('node-libs-browser', { paths: [webpackPath] });
419
+ const nodeLibsBrowser = require(nodeLibsBrowserPath);
420
+ webpackConfig.plugins.push(new webpack.NormalModuleReplacementPlugin(/^events|url|querystring$/, (resource) => {
421
+ if (!resource.issuer) {
422
+ return;
423
+ }
424
+ if (/[\/\\]hot[\/\\]emitter\.js$/.test(resource.issuer)) {
425
+ if (resource.request === 'events') {
426
+ resource.request = nodeLibsBrowser.events;
427
+ }
428
+ }
429
+ else if (/[\/\\]webpack-dev-server[\/\\]client[\/\\]utils[\/\\]createSocketUrl\.js$/.test(resource.issuer)) {
430
+ switch (resource.request) {
431
+ case 'url':
432
+ resource.request = nodeLibsBrowser.url;
433
+ break;
434
+ case 'querystring':
435
+ resource.request = nodeLibsBrowser.querystring;
436
+ break;
437
+ }
438
+ }
439
+ }));
428
440
  // This allows for live reload of page when changes are made to repo.
429
441
  // https://webpack.js.org/configuration/dev-server/#devserver-inline
430
442
  let webpackDevServerPath;
@@ -175,7 +175,7 @@
175
175
  "minItems": 1,
176
176
  "items": {
177
177
  "type": "string",
178
- "pattern": "^[a-z]{2}(-[a-zA-Z]{2,})?$"
178
+ "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-[a-zA-Z]{5,8})?(-x(-[a-zA-Z0-9]{1,8})+)?$"
179
179
  }
180
180
  }
181
181
  ]
@@ -12,6 +12,7 @@ const os = require("os");
12
12
  const path = require("path");
13
13
  const v8 = require("v8");
14
14
  const action_cache_1 = require("./action-cache");
15
+ const workers_1 = require("./workers");
15
16
  const hasThreadSupport = (() => {
16
17
  try {
17
18
  require('worker_threads');
@@ -49,6 +50,7 @@ class BundleActionExecutor {
49
50
  return (this.largeWorker = new jest_worker_1.default(workerFile, {
50
51
  exposedMethods: ['process', 'inlineLocales'],
51
52
  setupArgs: [[...serialize(this.workerOptions)]],
53
+ numWorkers: workers_1.maxWorkers,
52
54
  }));
53
55
  }
54
56
  ensureSmall() {
@@ -140,7 +140,16 @@ async function configureI18nBuild(context, options) {
140
140
  if (!i18n.inlineLocales.has(locale)) {
141
141
  continue;
142
142
  }
143
- const localeDataPath = findLocaleDataPath(locale, localeDataBasePath);
143
+ let localeDataPath = findLocaleDataPath(locale, localeDataBasePath);
144
+ if (!localeDataPath) {
145
+ const [first] = locale.split('-');
146
+ if (first) {
147
+ localeDataPath = findLocaleDataPath(first.toLowerCase(), localeDataBasePath);
148
+ if (localeDataPath) {
149
+ context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
150
+ }
151
+ }
152
+ }
144
153
  if (!localeDataPath) {
145
154
  context.logger.warn(`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`);
146
155
  }
@@ -233,8 +242,14 @@ function findLocaleDataBasePath(projectRoot) {
233
242
  }
234
243
  }
235
244
  function findLocaleDataPath(locale, basePath) {
236
- const localeDataPath = path.join(basePath, locale + '.js');
245
+ // Remove private use subtags
246
+ const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
247
+ const localeDataPath = path.join(basePath, scrubbedLocale + '.js');
237
248
  if (!fs.existsSync(localeDataPath)) {
249
+ if (scrubbedLocale === 'en-US') {
250
+ // fallback to known existing en-US locale data as of 9.0
251
+ return findLocaleDataPath('en-US-POSIX', basePath);
252
+ }
238
253
  return null;
239
254
  }
240
255
  return localeDataPath;
@@ -14,3 +14,5 @@ export * from './normalize-asset-patterns';
14
14
  export * from './normalize-source-maps';
15
15
  export * from './normalize-optimization';
16
16
  export * from './normalize-builder-schema';
17
+ export * from './url';
18
+ export * from './workers';
@@ -19,3 +19,5 @@ __export(require("./normalize-asset-patterns"));
19
19
  __export(require("./normalize-source-maps"));
20
20
  __export(require("./normalize-optimization"));
21
21
  __export(require("./normalize-builder-schema"));
22
+ __export(require("./url"));
23
+ __export(require("./workers"));
@@ -59,6 +59,16 @@ async function process(options) {
59
59
  let downlevelCode;
60
60
  let downlevelMap;
61
61
  if (downlevel) {
62
+ const { supportedBrowsers: targets = [] } = options;
63
+ // todo: revisit this in version 10, when we update our defaults browserslist
64
+ // Without this workaround bundles will not be downlevelled because Babel doesn't know handle to 'op_mini all'
65
+ // See: https://github.com/babel/babel/issues/11155
66
+ if (Array.isArray(targets) && targets.includes('op_mini all')) {
67
+ targets.push('ie_mob 11');
68
+ }
69
+ else if ('op_mini' in targets) {
70
+ targets['ie_mob'] = '11';
71
+ }
62
72
  // Downlevel the bundle
63
73
  const transformResult = await core_1.transformAsync(sourceCode, {
64
74
  filename,
@@ -72,7 +82,7 @@ async function process(options) {
72
82
  require.resolve('@babel/preset-env'),
73
83
  {
74
84
  // browserslist-compatible query or object of minimum environment versions to support
75
- targets: options.supportedBrowsers,
85
+ targets,
76
86
  // modules aren't needed since the bundles use webpack's custom module loading
77
87
  modules: false,
78
88
  // 'transform-typeof-symbol' generates slower code
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google Inc. All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ export declare function urlJoin(...parts: string[]): string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google Inc. 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
+ function urlJoin(...parts) {
11
+ const [p, ...rest] = parts;
12
+ // Remove trailing slash from first part
13
+ // Join all parts with `/`
14
+ // Dedupe double slashes from path names
15
+ return p.replace(/\/$/, '') + ('/' + rest.join('/')).replace(/\/\/+/g, '/');
16
+ }
17
+ exports.urlJoin = urlJoin;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google Inc. All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ /**
9
+ * Use CPU count -1 with limit to 7 for workers not to clog the system.
10
+ * Some environments, like CircleCI which use Docker report a number of CPUs by the host and not the count of available.
11
+ * This cause `Error: Call retries were exceeded` errors when trying to use them.
12
+ *
13
+ * See:
14
+ *
15
+ * https://github.com/nodejs/node/issues/28762
16
+ *
17
+ * https://github.com/webpack-contrib/terser-webpack-plugin/issues/143
18
+ *
19
+ * https://github.com/angular/angular-cli/issues/16860#issuecomment-588828079
20
+ *
21
+ */
22
+ export declare const maxWorkers: number;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google Inc. 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
+ const os_1 = require("os");
11
+ /**
12
+ * Use CPU count -1 with limit to 7 for workers not to clog the system.
13
+ * Some environments, like CircleCI which use Docker report a number of CPUs by the host and not the count of available.
14
+ * This cause `Error: Call retries were exceeded` errors when trying to use them.
15
+ *
16
+ * See:
17
+ *
18
+ * https://github.com/nodejs/node/issues/28762
19
+ *
20
+ * https://github.com/webpack-contrib/terser-webpack-plugin/issues/143
21
+ *
22
+ * https://github.com/angular/angular-cli/issues/16860#issuecomment-588828079
23
+ *
24
+ */
25
+ exports.maxWorkers = Math.max(Math.min(os_1.cpus().length, 8) - 1, 1);