@angular-devkit/build-angular 0.800.2 → 0.800.6

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,21 +1,21 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "0.800.2",
3
+ "version": "0.800.6",
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.800.2",
11
- "@angular-devkit/build-optimizer": "0.800.2",
12
- "@angular-devkit/build-webpack": "0.800.2",
13
- "@angular-devkit/core": "8.0.2",
14
- "@ngtools/webpack": "8.0.2",
10
+ "@angular-devkit/architect": "0.800.6",
11
+ "@angular-devkit/build-optimizer": "0.800.6",
12
+ "@angular-devkit/build-webpack": "0.800.6",
13
+ "@angular-devkit/core": "8.0.6",
14
+ "@ngtools/webpack": "8.0.6",
15
15
  "ajv": "6.10.0",
16
16
  "autoprefixer": "9.5.1",
17
17
  "browserslist": "4.5.5",
18
- "caniuse-api": "3.0.0",
18
+ "caniuse-lite": "1.0.30000974",
19
19
  "circular-dependency-plugin": "5.0.2",
20
20
  "clean-css": "4.2.1",
21
21
  "copy-webpack-plugin": "5.0.2",
@@ -58,6 +58,7 @@
58
58
  "worker-plugin": "3.1.0"
59
59
  },
60
60
  "peerDependencies": {
61
+ "@angular/compiler-cli": ">=8.0.0-beta.0 < 9.0.0",
61
62
  "typescript": ">=3.1 < 3.5"
62
63
  },
63
64
  "keywords": [
@@ -6,7 +6,8 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { logging } from '@angular-devkit/core';
9
- import { ParsedCommandLine, ScriptTarget } from 'typescript';
9
+ import { ParsedConfiguration } from '@angular/compiler-cli';
10
+ import { ScriptTarget } from 'typescript';
10
11
  import { AssetPatternClass, Budget, ExtraEntryPoint, OptimizationClass, SourceMapClass } from '../../browser/schema';
11
12
  import { NormalizedFileReplacement } from '../../utils/normalize-file-replacements';
12
13
  export interface BuildOptions {
@@ -78,7 +79,7 @@ export interface WebpackConfigOptions<T = BuildOptions> {
78
79
  projectRoot: string;
79
80
  sourceRoot?: string;
80
81
  buildOptions: T;
81
- tsConfig: ParsedCommandLine;
82
+ tsConfig: ParsedConfiguration;
82
83
  tsConfigPath: string;
83
84
  supportES2015: boolean;
84
85
  }
@@ -8,6 +8,7 @@
8
8
 
9
9
  // ES2015 symbol capabilities
10
10
  import 'core-js/modules/es.symbol';
11
+ import 'core-js/modules/es.symbol.iterator';
11
12
 
12
13
  // ES2015 function capabilities
13
14
  import 'core-js/modules/es.function.bind';
@@ -1,22 +1,8 @@
1
- /**
2
- * Safari 10.1 supports modules, but does not support the `nomodule` attribute - it will
3
- * load <script nomodule> anyway. This snippet solve this problem, but only for script
4
- * tags that load external code, e.g.: <script nomodule src="nomodule.js"></script>
5
- *
6
- * Again: this will **not** prevent inline script, e.g.:
7
- * <script nomodule>alert('no modules');</script>.
8
- *
9
- * This workaround is possible because Safari supports the non-standard 'beforeload' event.
10
- * This allows us to trap the module and nomodule load.
11
- *
12
- * Note also that `nomodule` is supported in later versions of Safari - it's just 10.1 that
13
- * omits this attribute.
14
- */
15
- (function() {
1
+ (function () {
16
2
  var check = document.createElement('script');
17
3
  if (!('noModule' in check) && 'onbeforeload' in check) {
18
4
  var support = false;
19
- document.addEventListener('beforeload', function(e) {
5
+ document.addEventListener('beforeload', function (e) {
20
6
  if (e.target === check) {
21
7
  support = true;
22
8
  } else if (!e.target.hasAttribute('nomodule') || !support) {
@@ -30,4 +16,4 @@
30
16
  document.head.appendChild(check);
31
17
  check.remove();
32
18
  }
33
- }());
19
+ }());
@@ -12,7 +12,7 @@ const CopyWebpackPlugin = require("copy-webpack-plugin");
12
12
  const path = require("path");
13
13
  const typescript_1 = require("typescript");
14
14
  const webpack_1 = require("webpack");
15
- const differential_loading_1 = require("../../../utils/differential-loading");
15
+ const build_browser_features_1 = require("../../../utils/build-browser-features");
16
16
  const bundle_budget_1 = require("../../plugins/bundle-budget");
17
17
  const cleancss_webpack_plugin_1 = require("../../plugins/cleancss-webpack-plugin");
18
18
  const named_chunks_plugin_1 = require("../../plugins/named-chunks-plugin");
@@ -31,7 +31,7 @@ exports.buildOptimizerLoader = g['_DevKitIsLocal']
31
31
  : '@angular-devkit/build-optimizer/webpack-loader';
32
32
  // tslint:disable-next-line:no-big-function
33
33
  function getCommonConfig(wco) {
34
- const { root, projectRoot, buildOptions } = wco;
34
+ const { root, projectRoot, buildOptions, tsConfig } = wco;
35
35
  const { styles: stylesOptimization, scripts: scriptsOptimization } = buildOptions.optimization;
36
36
  const { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap, } = buildOptions.sourceMap;
37
37
  const nodeModules = find_up_1.findUp('node_modules', projectRoot);
@@ -46,27 +46,31 @@ function getCommonConfig(wco) {
46
46
  entryPoints['main'] = [path.resolve(root, buildOptions.main)];
47
47
  }
48
48
  if (wco.buildOptions.platform !== 'server') {
49
- const es5Polyfills = path.join(__dirname, '..', 'es5-polyfills.js');
50
- const es5JitPolyfills = path.join(__dirname, '..', 'es5-jit-polyfills.js');
51
- if (targetInFileName) {
52
- // For differential loading we don't need to have 2 polyfill bundles
53
- if (buildOptions.scriptTargetOverride === typescript_1.ScriptTarget.ES2015) {
54
- entryPoints['polyfills'] = [path.join(__dirname, '..', 'safari-nomodule.js')];
55
- }
56
- else {
57
- entryPoints['polyfills'] = [es5Polyfills];
58
- if (!buildOptions.aot) {
59
- entryPoints['polyfills'].push(es5JitPolyfills);
49
+ const buildBrowserFeatures = new build_browser_features_1.BuildBrowserFeatures(projectRoot, tsConfig.options.target || typescript_1.ScriptTarget.ES5);
50
+ if ((buildOptions.scriptTargetOverride || tsConfig.options.target) === typescript_1.ScriptTarget.ES5) {
51
+ if (buildOptions.es5BrowserSupport ||
52
+ (buildOptions.es5BrowserSupport === undefined &&
53
+ buildBrowserFeatures.isEs5SupportNeeded())) {
54
+ // The nomodule polyfill needs to be inject prior to any script and be
55
+ // outside of webpack compilation because otherwise webpack will cause the
56
+ // script to be wrapped in window["webpackJsonp"] which causes this to fail.
57
+ if (buildBrowserFeatures.isNoModulePolyfillNeeded()) {
58
+ const noModuleScript = {
59
+ bundleName: 'polyfills-nomodule-es5',
60
+ input: path.join(__dirname, '..', 'safari-nomodule.js'),
61
+ };
62
+ buildOptions.scripts = buildOptions.scripts
63
+ ? [...buildOptions.scripts, noModuleScript]
64
+ : [noModuleScript];
60
65
  }
61
- }
62
- }
63
- else {
64
- // For NON differential loading we want to have 2 polyfill bundles
65
- if (buildOptions.es5BrowserSupport
66
- || (buildOptions.es5BrowserSupport === undefined && differential_loading_1.isEs5SupportNeeded(projectRoot))) {
67
- entryPoints['polyfills-es5'] = [es5Polyfills];
66
+ // For differential loading we don't need to generate a seperate polyfill file
67
+ // because they will be loaded exclusivly based on module and nomodule
68
+ const polyfillsChunkName = buildBrowserFeatures.isDifferentialLoadingNeeded()
69
+ ? 'polyfills'
70
+ : 'polyfills-es5';
71
+ entryPoints[polyfillsChunkName] = [path.join(__dirname, '..', 'es5-polyfills.js')];
68
72
  if (!buildOptions.aot) {
69
- entryPoints['polyfills-es5'].push(es5JitPolyfills);
73
+ entryPoints[polyfillsChunkName].push(path.join(__dirname, '..', 'es5-jit-polyfills.js'));
70
74
  }
71
75
  }
72
76
  }
@@ -9,7 +9,7 @@ export declare function getNonAotConfig(wco: WebpackConfigOptions): {
9
9
  };
10
10
  plugins: AngularCompilerPlugin[];
11
11
  };
12
- export declare function getAotConfig(wco: WebpackConfigOptions, extract?: boolean): {
12
+ export declare function getAotConfig(wco: WebpackConfigOptions, i18nExtract?: boolean): {
13
13
  module: {
14
14
  rules: {
15
15
  test: RegExp;
@@ -34,12 +34,12 @@ function _pluginOptionsOverrides(buildOptions, pluginOptions) {
34
34
  compilerOptions
35
35
  };
36
36
  }
37
- function _createAotPlugin(wco, options, useMain = true, extract = false) {
37
+ function _createAotPlugin(wco, options, i18nExtract = false) {
38
38
  const { root, buildOptions } = wco;
39
39
  const i18nInFile = buildOptions.i18nFile
40
40
  ? path.resolve(root, buildOptions.i18nFile)
41
41
  : undefined;
42
- const i18nFileAndFormat = extract
42
+ const i18nFileAndFormat = i18nExtract
43
43
  ? {
44
44
  i18nOutFile: buildOptions.i18nFile,
45
45
  i18nOutFormat: buildOptions.i18nFormat,
@@ -54,7 +54,7 @@ function _createAotPlugin(wco, options, useMain = true, extract = false) {
54
54
  }
55
55
  }
56
56
  let pluginOptions = {
57
- mainPath: useMain ? path.join(root, buildOptions.main) : undefined,
57
+ mainPath: path.join(root, buildOptions.main),
58
58
  ...i18nFileAndFormat,
59
59
  locale: buildOptions.i18nLocale,
60
60
  platform: buildOptions.platform === 'server' ? webpack_1.PLATFORM.Server : webpack_1.PLATFORM.Browser,
@@ -79,7 +79,7 @@ function getNonAotConfig(wco) {
79
79
  };
80
80
  }
81
81
  exports.getNonAotConfig = getNonAotConfig;
82
- function getAotConfig(wco, extract = false) {
82
+ function getAotConfig(wco, i18nExtract = false) {
83
83
  const { tsConfigPath, buildOptions } = wco;
84
84
  const loaders = [webpack_1.NgToolsLoader];
85
85
  if (buildOptions.buildOptimizer) {
@@ -91,7 +91,7 @@ function getAotConfig(wco, extract = false) {
91
91
  const test = /(?:\.ngfactory\.js|\.ngstyle\.js|\.tsx?)$/;
92
92
  return {
93
93
  module: { rules: [{ test, use: loaders }] },
94
- plugins: [_createAotPlugin(wco, { tsConfigPath }, true, extract)]
94
+ plugins: [_createAotPlugin(wco, { tsConfigPath }, i18nExtract)]
95
95
  };
96
96
  }
97
97
  exports.getAotConfig = getAotConfig;
@@ -8,7 +8,6 @@
8
8
  import { ExtraEntryPoint, ExtraEntryPointClass } from '../../../browser/schema';
9
9
  import { SourceMapDevToolPlugin } from 'webpack';
10
10
  import { ScriptTarget } from 'typescript';
11
- export declare const ngAppResolve: (resolvePath: string) => string;
12
11
  export interface HashFormat {
13
12
  chunk: string;
14
13
  extract: string;
@@ -9,13 +9,9 @@
9
9
  // tslint:disable
10
10
  // TODO: cleanup this file, it's copied as is from Angular CLI.
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const path = require("path");
13
12
  const core_1 = require("@angular-devkit/core");
14
13
  const webpack_1 = require("webpack");
15
14
  const typescript_1 = require("typescript");
16
- exports.ngAppResolve = (resolvePath) => {
17
- return path.resolve(process.cwd(), resolvePath);
18
- };
19
15
  function getOutputHashFormat(option, length = 20) {
20
16
  /* tslint:disable:max-line-length */
21
17
  const hashFormats = {
@@ -60,15 +60,14 @@ const init = (config, emitter, customFileHandlers) => {
60
60
  const logger = config.buildWebpack.logger || node_1.createConsoleLogger();
61
61
  successCb = config.buildWebpack.successCb;
62
62
  failureCb = config.buildWebpack.failureCb;
63
- config.reporters.unshift('@angular-devkit/build-angular--event-reporter');
64
63
  // When using code-coverage, auto-add coverage-istanbul.
65
64
  config.reporters = config.reporters || [];
66
65
  if (options.codeCoverage && config.reporters.indexOf('coverage-istanbul') === -1) {
67
- config.reporters.unshift('coverage-istanbul');
66
+ config.reporters.push('coverage-istanbul');
68
67
  }
69
68
  // Add a reporter that fixes sourcemap urls.
70
69
  if (index_1.normalizeSourceMaps(options.sourceMap).scripts) {
71
- config.reporters.unshift('@angular-devkit/build-angular--sourcemap-reporter');
70
+ config.reporters.push('@angular-devkit/build-angular--sourcemap-reporter');
72
71
  // Code taken from https://github.com/tschaub/karma-source-map-support.
73
72
  // We can't use it directly because we need to add it conditionally in this file, and karma
74
73
  // frameworks cannot be added dynamically.
@@ -79,6 +78,7 @@ const init = (config, emitter, customFileHandlers) => {
79
78
  { pattern: path.join(ksmsPath, 'client.js'), watched: false }
80
79
  ], true);
81
80
  }
81
+ config.reporters.push('@angular-devkit/build-angular--event-reporter');
82
82
  // Add webpack config.
83
83
  const webpackConfig = config.buildWebpack.webpackConfig;
84
84
  const webpackMiddlewareConfig = {
@@ -21,7 +21,7 @@ function writeIndexHtml({ host, outputPath, indexPath, ES5BuildFiles, ES2015Buil
21
21
  deployUrl,
22
22
  sri,
23
23
  entrypoints: package_chunk_sort_1.generateEntryPoints({ scripts, styles }),
24
- files: filterAndMapBuildFiles(ES5BuildFiles, '.css'),
24
+ files: filterAndMapBuildFiles(ES2015BuildFiles, '.css'),
25
25
  noModuleFiles: filterAndMapBuildFiles(ES5BuildFiles, '.js'),
26
26
  moduleFiles: filterAndMapBuildFiles(ES2015BuildFiles, '.js'),
27
27
  loadOutputFile: async (filePath) => {
@@ -11,6 +11,7 @@ function generateEntryPoints(appConfig) {
11
11
  return [...new Set(entryPoints)];
12
12
  };
13
13
  const entryPoints = [
14
+ 'polyfills-nomodule-es5',
14
15
  'polyfills-es5',
15
16
  'polyfills',
16
17
  'sw-register',
@@ -5,5 +5,12 @@
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 * as ts from 'typescript';
9
- export declare function readTsconfig(tsconfigPath: string): ts.ParsedCommandLine;
8
+ import { ParsedConfiguration } from '@angular/compiler-cli';
9
+ /**
10
+ * Reads and parses a given TsConfig file.
11
+ *
12
+ * @param tsconfigPath - An absolute or relative path from 'workspaceRoot' of the tsconfig file.
13
+ * @param workspaceRoot - workspaceRoot root location when provided
14
+ * it will resolve 'tsconfigPath' from this path.
15
+ */
16
+ export declare function readTsconfig(tsconfigPath: string, workspaceRoot?: string): ParsedConfiguration;
@@ -1,14 +1,31 @@
1
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
+ */
2
9
  Object.defineProperty(exports, "__esModule", { value: true });
3
10
  const path = require("path");
4
- const require_project_module_1 = require("../utilities/require-project-module");
5
- function readTsconfig(tsconfigPath) {
6
- const projectTs = require_project_module_1.requireProjectModule(path.dirname(tsconfigPath), 'typescript');
7
- const configResult = projectTs.readConfigFile(tsconfigPath, projectTs.sys.readFile);
8
- const tsConfig = projectTs.parseJsonConfigFileContent(configResult.config, projectTs.sys, path.dirname(tsconfigPath), undefined, tsconfigPath);
9
- if (tsConfig.errors.length > 0) {
10
- throw new Error(`Errors found while reading ${tsconfigPath}:\n ${tsConfig.errors.map(e => e.messageText).join('\n ')}`);
11
+ /**
12
+ * Reads and parses a given TsConfig file.
13
+ *
14
+ * @param tsconfigPath - An absolute or relative path from 'workspaceRoot' of the tsconfig file.
15
+ * @param workspaceRoot - workspaceRoot root location when provided
16
+ * it will resolve 'tsconfigPath' from this path.
17
+ */
18
+ function readTsconfig(tsconfigPath, workspaceRoot) {
19
+ const tsConfigFullPath = workspaceRoot
20
+ ? path.resolve(workspaceRoot, tsconfigPath)
21
+ : tsconfigPath;
22
+ // We use 'ng' instead of 'ts' here because 'ts' is not aware of 'angularCompilerOptions'
23
+ // and will not merged them if they are at un upper level tsconfig file when using `extends`.
24
+ const ng = require('@angular/compiler-cli');
25
+ const configResult = ng.readConfiguration(tsConfigFullPath);
26
+ if (configResult.errors && configResult.errors.length) {
27
+ throw new Error(ng.formatDiagnostics(configResult.errors));
11
28
  }
12
- return tsConfig;
29
+ return configResult;
13
30
  }
14
31
  exports.readTsconfig = readTsconfig;
@@ -68,7 +68,7 @@ async function augmentAppWithServiceWorker(host, projectRoot, appRoot, outputPat
68
68
  if (!configExists) {
69
69
  throw new Error(core_1.tags.oneLine `
70
70
  Error: Expected to find an ngsw-config.json configuration
71
- file in the ${appRoot} folder. Either provide one or disable Service Worker
71
+ file in the ${core_1.getSystemPath(appRoot)} folder. Either provide one or disable Service Worker
72
72
  in your angular.json configuration file.
73
73
  `);
74
74
  }
@@ -61,7 +61,9 @@ function getAnalyticsConfig(wco, context) {
61
61
  let category = 'build';
62
62
  if (context.builder) {
63
63
  // We already vetted that this is a "safe" package, otherwise the analytics would be noop.
64
- category = context.builder.builderName.split(':')[1];
64
+ category = context.builder.builderName.split(':')[1]
65
+ || context.builder.builderName
66
+ || 'build';
65
67
  }
66
68
  // The category is the builder name if it's an angular builder.
67
69
  return {
@@ -106,11 +108,10 @@ function buildWebpackBrowser(options, context, transforms = {}) {
106
108
  throw new Error('Must either have a target from the context or a default project.');
107
109
  }
108
110
  const projectRoot = core_1.resolve(workspace.root, core_1.normalize(workspace.getProject(projectName).root));
109
- const tsConfigPath = path.resolve(core_1.getSystemPath(workspace.root), options.tsConfig);
110
- const tsConfig = read_tsconfig_1.readTsconfig(tsConfigPath);
111
- if (utils_1.isEs5SupportNeeded(projectRoot) &&
112
- tsConfig.options.target !== typescript_1.ScriptTarget.ES5 &&
113
- tsConfig.options.target !== typescript_1.ScriptTarget.ES2015) {
111
+ const tsConfig = read_tsconfig_1.readTsconfig(options.tsConfig, context.workspaceRoot);
112
+ const target = tsConfig.options.target || typescript_1.ScriptTarget.ES5;
113
+ const buildBrowserFeatures = new utils_1.BuildBrowserFeatures(core_1.getSystemPath(projectRoot), target);
114
+ if (target > typescript_1.ScriptTarget.ES2015 && buildBrowserFeatures.isDifferentialLoadingNeeded()) {
114
115
  context.logger.warn(core_1.tags.stripIndent `
115
116
  WARNING: Using differential loading with targets ES5 and ES2016 or higher may
116
117
  cause problems. Browsers with support for ES2015 will load the ES2016+ scripts
@@ -145,14 +146,14 @@ function buildWebpackBrowser(options, context, transforms = {}) {
145
146
  scripts: options.scripts,
146
147
  styles: options.styles,
147
148
  })
148
- .pipe(operators_1.map(() => ({ success: true })), operators_1.catchError(() => rxjs_1.of({ success: false })));
149
+ .pipe(operators_1.map(() => ({ success: true })), operators_1.catchError(error => rxjs_1.of({ success: false, error: mapErrorToMessage(error) })));
149
150
  }
150
151
  else {
151
152
  return rxjs_1.of({ success });
152
153
  }
153
154
  }), operators_1.concatMap(buildEvent => {
154
155
  if (buildEvent.success && !options.watch && options.serviceWorker) {
155
- return rxjs_1.from(service_worker_1.augmentAppWithServiceWorker(host, root, projectRoot, core_1.resolve(root, core_1.normalize(options.outputPath)), options.baseHref || '/', options.ngswConfigPath).then(() => ({ success: true }), () => ({ success: false })));
156
+ return rxjs_1.from(service_worker_1.augmentAppWithServiceWorker(host, root, projectRoot, core_1.resolve(root, core_1.normalize(options.outputPath)), options.baseHref || '/', options.ngswConfigPath).then(() => ({ success: true }), error => ({ success: false, error: mapErrorToMessage(error) })));
156
157
  }
157
158
  else {
158
159
  return rxjs_1.of(buildEvent);
@@ -165,4 +166,13 @@ function buildWebpackBrowser(options, context, transforms = {}) {
165
166
  }));
166
167
  }
167
168
  exports.buildWebpackBrowser = buildWebpackBrowser;
169
+ function mapErrorToMessage(error) {
170
+ if (error instanceof Error) {
171
+ return error.message;
172
+ }
173
+ if (typeof error === 'string') {
174
+ return error;
175
+ }
176
+ return undefined;
177
+ }
168
178
  exports.default = architect_1.createBuilder(buildWebpackBrowser);
@@ -12,6 +12,7 @@ const build_webpack_1 = require("@angular-devkit/build-webpack");
12
12
  const path = require("path");
13
13
  const webpack = require("webpack");
14
14
  const webpack_configs_1 = require("../angular-cli-files/models/webpack-configs");
15
+ const read_tsconfig_1 = require("../angular-cli-files/utilities/read-tsconfig");
15
16
  const stats_1 = require("../angular-cli-files/utilities/stats");
16
17
  const version_1 = require("../utils/version");
17
18
  const webpack_browser_config_1 = require("../utils/webpack-browser-config");
@@ -40,6 +41,13 @@ async function execute(options, context) {
40
41
  version_1.Version.assertCompatibleAngularVersion(context.workspaceRoot);
41
42
  const browserTarget = architect_1.targetFromTargetString(options.browserTarget);
42
43
  const browserOptions = await context.validateOptions(await context.getTargetOptions(browserTarget), await context.getBuilderNameForTarget(browserTarget));
44
+ // FIXME: i18n is not yet implemented in Ivy
45
+ // We should display a warning and exit gracefully.
46
+ const { options: compilerOptions } = read_tsconfig_1.readTsconfig(browserOptions.tsConfig, context.workspaceRoot);
47
+ if (compilerOptions.enableIvy) {
48
+ context.logger.warn('We are sorry but i18n is not yet implemented in Ivy.');
49
+ return { success: true };
50
+ }
43
51
  // We need to determine the outFile name so that AngularCompiler can retrieve it.
44
52
  let outFile = options.outFile || getI18nOutfile(options.i18nFormat);
45
53
  if (options.outputPath) {
@@ -52,6 +60,7 @@ async function execute(options, context) {
52
60
  scripts: false,
53
61
  styles: false,
54
62
  },
63
+ buildOptimizer: false,
55
64
  i18nLocale: options.i18nLocale,
56
65
  i18nFormat: options.i18nFormat,
57
66
  i18nFile: outFile,
@@ -81,7 +81,7 @@ function execute(options, context, transforms = {}) {
81
81
  return karmaStart.then(() => karmaServerWithStop.stop());
82
82
  }
83
83
  };
84
- })));
84
+ })), operators_1.defaultIfEmpty({ success: false }));
85
85
  }
86
86
  exports.execute = execute;
87
87
  exports.default = architect_1.createBuilder(execute);
@@ -0,0 +1,35 @@
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
+ import * as ts from 'typescript';
9
+ export declare class BuildBrowserFeatures {
10
+ private projectRoot;
11
+ private scriptTarget;
12
+ private readonly _supportedBrowsers;
13
+ private readonly _es6TargetOrLater;
14
+ constructor(projectRoot: string, scriptTarget: ts.ScriptTarget);
15
+ /**
16
+ * True, when one or more browsers requires ES5
17
+ * support and the scirpt target is ES2015 or greater.
18
+ */
19
+ isDifferentialLoadingNeeded(): boolean;
20
+ /**
21
+ * True, when one or more browsers requires ES5 support
22
+ */
23
+ isEs5SupportNeeded(): boolean;
24
+ /**
25
+ * Safari 10.1 and iOS Safari 10.3 supports modules,
26
+ * but does not support the `nomodule` attribute.
27
+ * While return `true`, when support for Safari 10.1 and iOS Safari 10.3
28
+ * is required and in differential loading is enabled.
29
+ */
30
+ isNoModulePolyfillNeeded(): boolean;
31
+ /**
32
+ * True, when a browser feature is supported partially or fully.
33
+ */
34
+ isFeatureSupported(featureId: string): boolean;
35
+ }
@@ -0,0 +1,74 @@
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 browserslist = require("browserslist");
11
+ const caniuse_lite_1 = require("caniuse-lite");
12
+ const ts = require("typescript");
13
+ class BuildBrowserFeatures {
14
+ constructor(projectRoot, scriptTarget) {
15
+ this.projectRoot = projectRoot;
16
+ this.scriptTarget = scriptTarget;
17
+ this._supportedBrowsers = browserslist(undefined, { path: this.projectRoot });
18
+ this._es6TargetOrLater = this.scriptTarget > ts.ScriptTarget.ES5;
19
+ }
20
+ /**
21
+ * True, when one or more browsers requires ES5
22
+ * support and the scirpt target is ES2015 or greater.
23
+ */
24
+ isDifferentialLoadingNeeded() {
25
+ return this._es6TargetOrLater && this.isEs5SupportNeeded();
26
+ }
27
+ /**
28
+ * True, when one or more browsers requires ES5 support
29
+ */
30
+ isEs5SupportNeeded() {
31
+ return !this.isFeatureSupported('es6-module');
32
+ }
33
+ /**
34
+ * Safari 10.1 and iOS Safari 10.3 supports modules,
35
+ * but does not support the `nomodule` attribute.
36
+ * While return `true`, when support for Safari 10.1 and iOS Safari 10.3
37
+ * is required and in differential loading is enabled.
38
+ */
39
+ isNoModulePolyfillNeeded() {
40
+ if (!this.isDifferentialLoadingNeeded()) {
41
+ return false;
42
+ }
43
+ const safariBrowsers = [
44
+ 'safari 10.1',
45
+ 'ios_saf 10.3',
46
+ ];
47
+ return this._supportedBrowsers.some(browser => safariBrowsers.includes(browser));
48
+ }
49
+ /**
50
+ * True, when a browser feature is supported partially or fully.
51
+ */
52
+ isFeatureSupported(featureId) {
53
+ // y: feature is fully available
54
+ // n: feature is unavailable
55
+ // a: feature is partially supported
56
+ // x: feature is prefixed
57
+ const criteria = [
58
+ 'y',
59
+ 'a',
60
+ ];
61
+ const data = caniuse_lite_1.feature(caniuse_lite_1.features[featureId]);
62
+ return !this._supportedBrowsers
63
+ .some(browser => {
64
+ const [agentId, version] = browser.split(' ');
65
+ const browserData = data.stats[agentId];
66
+ const featureStatus = (browserData && browserData[version]);
67
+ // We are only interested in the first character
68
+ // Ex: when 'a #4 #5', we only need to check for 'a'
69
+ // as for such cases we should polyfill these features as needed
70
+ return !featureStatus || !criteria.includes(featureStatus.charAt(0));
71
+ });
72
+ }
73
+ }
74
+ exports.BuildBrowserFeatures = BuildBrowserFeatures;
@@ -5,9 +5,9 @@
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
+ export * from './build-browser-features';
8
9
  export * from './default-progress';
9
10
  export * from './delete-output-dir';
10
- export * from './differential-loading';
11
11
  export * from './run-module-as-observable-fork';
12
12
  export * from './normalize-file-replacements';
13
13
  export * from './normalize-asset-patterns';
@@ -1,8 +1,4 @@
1
1
  "use strict";
2
- function __export(m) {
3
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4
- }
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
2
  /**
7
3
  * @license
8
4
  * Copyright Google Inc. All Rights Reserved.
@@ -10,9 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
6
  * Use of this source code is governed by an MIT-style license that can be
11
7
  * found in the LICENSE file at https://angular.io/license
12
8
  */
9
+ function __export(m) {
10
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
11
+ }
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __export(require("./build-browser-features"));
13
14
  __export(require("./default-progress"));
14
15
  __export(require("./delete-output-dir"));
15
- __export(require("./differential-loading"));
16
16
  __export(require("./run-module-as-observable-fork"));
17
17
  __export(require("./normalize-file-replacements"));
18
18
  __export(require("./normalize-asset-patterns"));
@@ -6,7 +6,7 @@ const path = require("path");
6
6
  const webpack_configs_1 = require("../angular-cli-files/models/webpack-configs");
7
7
  const read_tsconfig_1 = require("../angular-cli-files/utilities/read-tsconfig");
8
8
  const utils_1 = require("../utils");
9
- const differential_loading_1 = require("./differential-loading");
9
+ const build_browser_features_1 = require("./build-browser-features");
10
10
  const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
11
11
  const webpackMerge = require('webpack-merge');
12
12
  async function generateWebpackConfig(context, workspaceRoot, projectRoot, sourceRoot, options, webpackPartialGenerator, logger) {
@@ -20,9 +20,11 @@ async function generateWebpackConfig(context, workspaceRoot, projectRoot, source
20
20
  const ts = await Promise.resolve().then(() => require('typescript'));
21
21
  // At the moment, only the browser builder supports differential loading
22
22
  // However this config generation is used by multiple builders such as dev-server
23
- const scriptTarget = tsConfig.options.target;
23
+ const scriptTarget = tsConfig.options.target || ts.ScriptTarget.ES5;
24
+ const buildBrowserFeatures = new build_browser_features_1.BuildBrowserFeatures(projectRoot, scriptTarget);
24
25
  const differentialLoading = context.builder.builderName === 'browser'
25
- && differential_loading_1.isDifferentialLoadingNeeded(projectRoot, scriptTarget) && !options.watch;
26
+ && !options.watch
27
+ && buildBrowserFeatures.isDifferentialLoadingNeeded();
26
28
  const scriptTargets = [scriptTarget];
27
29
  if (differentialLoading) {
28
30
  scriptTargets.unshift(ts.ScriptTarget.ES5);
@@ -30,18 +32,26 @@ async function generateWebpackConfig(context, workspaceRoot, projectRoot, source
30
32
  // For differential loading, we can have several targets
31
33
  return scriptTargets.map(scriptTarget => {
32
34
  let buildOptions = { ...options };
35
+ const supportES2015 = scriptTarget !== ts.ScriptTarget.ES3 && scriptTarget !== ts.ScriptTarget.ES5;
33
36
  if (differentialLoading) {
34
- // For differential loading, the builder needs to created the index.html by itself
35
- // without using a webpack plugin.
36
37
  buildOptions = {
37
38
  ...options,
39
+ ...(
40
+ // FIXME: we do create better webpack config composition to achieve the below
41
+ // When DL is enabled and supportES2015 is true it means that we are on the second build
42
+ // This also means that we don't need to include styles and assets multiple times
43
+ supportES2015
44
+ ? {}
45
+ : {
46
+ styles: options.extractCss ? [] : options.styles,
47
+ assets: [],
48
+ }),
38
49
  es5BrowserSupport: undefined,
39
50
  index: '',
40
51
  esVersionInFileName: true,
41
52
  scriptTargetOverride: scriptTarget,
42
53
  };
43
54
  }
44
- const supportES2015 = scriptTarget !== ts.ScriptTarget.ES3 && scriptTarget !== ts.ScriptTarget.ES5;
45
55
  const wco = {
46
56
  root: workspaceRoot,
47
57
  logger: logger.createChild('webpackConfigOptions'),
@@ -1,10 +0,0 @@
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
- import { ScriptTarget } from 'typescript';
9
- export declare function isDifferentialLoadingNeeded(projectRoot: string, target?: ScriptTarget): boolean;
10
- export declare function isEs5SupportNeeded(projectRoot: string): boolean;
@@ -1,24 +0,0 @@
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 browserslist = require("browserslist");
11
- const caniuse = require("caniuse-api");
12
- const typescript_1 = require("typescript");
13
- function isDifferentialLoadingNeeded(projectRoot, target = typescript_1.ScriptTarget.ES5) {
14
- const supportES2015 = target !== typescript_1.ScriptTarget.ES3 && target !== typescript_1.ScriptTarget.ES5;
15
- return supportES2015 && isEs5SupportNeeded(projectRoot);
16
- }
17
- exports.isDifferentialLoadingNeeded = isDifferentialLoadingNeeded;
18
- function isEs5SupportNeeded(projectRoot) {
19
- const browsersList = browserslist(undefined, {
20
- path: projectRoot,
21
- });
22
- return !caniuse.isSupported('es6-module', browsersList.join(', '));
23
- }
24
- exports.isEs5SupportNeeded = isEs5SupportNeeded;