diff --git a/package.json b/package.json
index 751520b3b9f9..d75a1a20d005 100644
--- a/package.json
+++ b/package.json
@@ -88,7 +88,7 @@
"@bazel/typescript": "~0.26.0",
"@ngtools/json-schema": "^1.1.0",
"@types/browserslist": "^4.4.0",
- "@types/caniuse-api": "^3.0.0",
+ "@types/caniuse-lite": "^1.0.0",
"@types/copy-webpack-plugin": "^4.4.1",
"@types/express": "^4.16.0",
"@types/glob": "^7.0.0",
diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json
index 1803c7f40286..3b7cb6710da9 100644
--- a/packages/angular_devkit/build_angular/package.json
+++ b/packages/angular_devkit/build_angular/package.json
@@ -15,7 +15,7 @@
"ajv": "6.10.0",
"autoprefixer": "9.6.0",
"browserslist": "4.6.2",
- "caniuse-api": "3.0.0",
+ "caniuse-lite": "1.0.30000974",
"circular-dependency-plugin": "5.0.2",
"clean-css": "4.2.1",
"copy-webpack-plugin": "5.0.3",
diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/safari-nomodule.js b/packages/angular_devkit/build_angular/src/angular-cli-files/models/safari-nomodule.js
index 89db355822ae..1d2dbd1436ff 100644
--- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/safari-nomodule.js
+++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/safari-nomodule.js
@@ -1,22 +1,8 @@
-/**
- * Safari 10.1 supports modules, but does not support the `nomodule` attribute - it will
- * load
- *
- * Again: this will **not** prevent inline script, e.g.:
- * .
- *
- * This workaround is possible because Safari supports the non-standard 'beforeload' event.
- * This allows us to trap the module and nomodule load.
- *
- * Note also that `nomodule` is supported in later versions of Safari - it's just 10.1 that
- * omits this attribute.
- */
-(function() {
+(function () {
var check = document.createElement('script');
if (!('noModule' in check) && 'onbeforeload' in check) {
var support = false;
- document.addEventListener('beforeload', function(e) {
+ document.addEventListener('beforeload', function (e) {
if (e.target === check) {
support = true;
} else if (!e.target.hasAttribute('nomodule') || !support) {
@@ -30,4 +16,4 @@
document.head.appendChild(check);
check.remove();
}
-}());
\ No newline at end of file
+}());
diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
index 7e9402759b0c..ec8318348e78 100644
--- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
+++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts
@@ -18,8 +18,8 @@ import {
debug,
} from 'webpack';
import { RawSource } from 'webpack-sources';
-import { AssetPatternClass } from '../../../browser/schema';
-import { isEs5SupportNeeded } from '../../../utils/differential-loading';
+import { AssetPatternClass, ExtraEntryPoint } from '../../../browser/schema';
+import { BuildBrowserFeatures } from '../../../utils/build-browser-features';
import { BundleBudgetPlugin } from '../../plugins/bundle-budget';
import { CleanCssWebpackPlugin } from '../../plugins/cleancss-webpack-plugin';
import { NamedLazyChunksPlugin } from '../../plugins/named-chunks-plugin';
@@ -40,7 +40,7 @@ export const buildOptimizerLoader: string = g['_DevKitIsLocal']
// tslint:disable-next-line:no-big-function
export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
- const { root, projectRoot, buildOptions } = wco;
+ const { root, projectRoot, buildOptions, tsConfig } = wco;
const { styles: stylesOptimization, scripts: scriptsOptimization } = buildOptions.optimization;
const {
styles: stylesSourceMap,
@@ -67,25 +67,39 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
}
if (wco.buildOptions.platform !== 'server') {
- const es5Polyfills = path.join(__dirname, '..', 'es5-polyfills.js');
- const es5JitPolyfills = path.join(__dirname, '..', 'es5-jit-polyfills.js');
- if (targetInFileName) {
- // For differential loading we don't need to have 2 polyfill bundles
- if (buildOptions.scriptTargetOverride === ScriptTarget.ES2015) {
- entryPoints['polyfills'] = [path.join(__dirname, '..', 'safari-nomodule.js')];
- } else {
- entryPoints['polyfills'] = [es5Polyfills];
- if (!buildOptions.aot) {
- entryPoints['polyfills'].push(es5JitPolyfills);
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ projectRoot,
+ tsConfig.options.target || ScriptTarget.ES5,
+ );
+ if ((buildOptions.scriptTargetOverride || tsConfig.options.target) === ScriptTarget.ES5) {
+ if (buildOptions.es5BrowserSupport ||
+ (
+ buildOptions.es5BrowserSupport === undefined &&
+ buildBrowserFeatures.isEs5SupportNeeded()
+ )
+ ) {
+ // The nomodule polyfill needs to be inject prior to any script and be
+ // outside of webpack compilation because otherwise webpack will cause the
+ // script to be wrapped in window["webpackJsonp"] which causes this to fail.
+ if (buildBrowserFeatures.isNoModulePolyfillNeeded()) {
+ const noModuleScript: ExtraEntryPoint = {
+ bundleName: 'polyfills-nomodule-es5',
+ input: path.join(__dirname, '..', 'safari-nomodule.js'),
+ };
+ buildOptions.scripts = buildOptions.scripts
+ ? [...buildOptions.scripts, noModuleScript]
+ : [noModuleScript];
}
- }
- } else {
- // For NON differential loading we want to have 2 polyfill bundles
- if (buildOptions.es5BrowserSupport
- || (buildOptions.es5BrowserSupport === undefined && isEs5SupportNeeded(projectRoot))) {
- entryPoints['polyfills-es5'] = [es5Polyfills];
+
+ // For differential loading we don't need to generate a seperate polyfill file
+ // because they will be loaded exclusivly based on module and nomodule
+ const polyfillsChunkName = buildBrowserFeatures.isDifferentialLoadingNeeded()
+ ? 'polyfills'
+ : 'polyfills-es5';
+
+ entryPoints[polyfillsChunkName] = [path.join(__dirname, '..', 'es5-polyfills.js')];
if (!buildOptions.aot) {
- entryPoints['polyfills-es5'].push(es5JitPolyfills);
+ entryPoints[polyfillsChunkName].push(path.join(__dirname, '..', 'es5-jit-polyfills.js'));
}
}
}
diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/utils.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/utils.ts
index 2262bde39378..e0afd2ad53ef 100644
--- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/utils.ts
+++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/utils.ts
@@ -8,16 +8,11 @@
// tslint:disable
// TODO: cleanup this file, it's copied as is from Angular CLI.
-import * as path from 'path';
import { basename, normalize } from '@angular-devkit/core';
import { ExtraEntryPoint, ExtraEntryPointClass } from '../../../browser/schema';
import { SourceMapDevToolPlugin } from 'webpack';
import { ScriptTarget } from 'typescript';
-export const ngAppResolve = (resolvePath: string): string => {
- return path.resolve(process.cwd(), resolvePath);
-};
-
export interface HashFormat {
chunk: string;
extract: string;
diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/package-chunk-sort.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/package-chunk-sort.ts
index 5f45c58c7af5..3b2262575d70 100644
--- a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/package-chunk-sort.ts
+++ b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/package-chunk-sort.ts
@@ -26,6 +26,7 @@ export function generateEntryPoints(
};
const entryPoints = [
+ 'polyfills-nomodule-es5',
'polyfills-es5',
'polyfills',
'sw-register',
diff --git a/packages/angular_devkit/build_angular/src/browser/index.ts b/packages/angular_devkit/build_angular/src/browser/index.ts
index b5d75281ee68..76bb388e6295 100644
--- a/packages/angular_devkit/build_angular/src/browser/index.ts
+++ b/packages/angular_devkit/build_angular/src/browser/index.ts
@@ -57,7 +57,7 @@ import {
statsWarningsToString,
} from '../angular-cli-files/utilities/stats';
import { ExecutionTransformer } from '../transforms';
-import { deleteOutputDir, isEs5SupportNeeded } from '../utils';
+import { BuildBrowserFeatures, deleteOutputDir } from '../utils';
import { Version } from '../utils/version';
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
import { Schema as BrowserBuilderSchema } from './schema';
@@ -202,9 +202,13 @@ export function buildWebpackBrowser(
const tsConfigPath = path.resolve(getSystemPath(workspace.root), options.tsConfig);
const tsConfig = readTsconfig(tsConfigPath);
- if (isEs5SupportNeeded(projectRoot) &&
- tsConfig.options.target !== ScriptTarget.ES5 &&
- tsConfig.options.target !== ScriptTarget.ES2015) {
+ const target = tsConfig.options.target || ScriptTarget.ES5;
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ getSystemPath(projectRoot),
+ target,
+ );
+
+ if (target > ScriptTarget.ES2015 && buildBrowserFeatures.isDifferentialLoadingNeeded()) {
context.logger.warn(tags.stripIndent`
WARNING: Using differential loading with targets ES5 and ES2016 or higher may
cause problems. Browsers with support for ES2015 will load the ES2016+ scripts
diff --git a/packages/angular_devkit/build_angular/src/utils/build-browser-features.ts b/packages/angular_devkit/build_angular/src/utils/build-browser-features.ts
new file mode 100644
index 000000000000..cfd3e58dda4c
--- /dev/null
+++ b/packages/angular_devkit/build_angular/src/utils/build-browser-features.ts
@@ -0,0 +1,87 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import * as browserslist from 'browserslist';
+import { feature, features } from 'caniuse-lite';
+import * as ts from 'typescript';
+
+export class BuildBrowserFeatures {
+ private readonly _supportedBrowsers: string[];
+ private readonly _es6TargetOrLater: boolean;
+
+ constructor(
+ private projectRoot: string,
+ private scriptTarget: ts.ScriptTarget,
+ ) {
+ this._supportedBrowsers = browserslist(undefined, { path: this.projectRoot });
+ this._es6TargetOrLater = this.scriptTarget > ts.ScriptTarget.ES5;
+ }
+
+ /**
+ * True, when one or more browsers requires ES5
+ * support and the scirpt target is ES2015 or greater.
+ */
+ isDifferentialLoadingNeeded(): boolean {
+ return this._es6TargetOrLater && this.isEs5SupportNeeded();
+ }
+
+ /**
+ * True, when one or more browsers requires ES5 support
+ */
+ isEs5SupportNeeded(): boolean {
+ return !this.isFeatureSupported('es6-module');
+ }
+
+ /**
+ * Safari 10.1 and iOS Safari 10.3 supports modules,
+ * but does not support the `nomodule` attribute.
+ * While return `true`, when support for Safari 10.1 and iOS Safari 10.3
+ * is required and in differential loading is enabled.
+ */
+ isNoModulePolyfillNeeded(): boolean {
+ if (!this.isDifferentialLoadingNeeded()) {
+ return false;
+ }
+
+ const safariBrowsers = [
+ 'safari 10.1',
+ 'ios_saf 10.3',
+ ];
+
+ return this._supportedBrowsers.some(browser => safariBrowsers.includes(browser));
+ }
+
+ /**
+ * True, when a browser feature is supported partially or fully.
+ */
+ isFeatureSupported(featureId: string): boolean {
+ // y: feature is fully available
+ // n: feature is unavailable
+ // a: feature is partially supported
+ // x: feature is prefixed
+ const criteria = [
+ 'y',
+ 'a',
+ ];
+
+ const data = feature(features[featureId]);
+
+ return !this._supportedBrowsers
+ .some(browser => {
+ const [agentId, version] = browser.split(' ');
+
+ const browserData = data.stats[agentId];
+ const featureStatus = (browserData && browserData[version]) as string | undefined;
+
+ // We are only interested in the first character
+ // Ex: when 'a #4 #5', we only need to check for 'a'
+ // as for such cases we should polyfill these features as needed
+ return !featureStatus || !criteria.includes(featureStatus.charAt(0));
+ });
+ }
+}
diff --git a/packages/angular_devkit/build_angular/src/utils/build-browser-features_spec.ts b/packages/angular_devkit/build_angular/src/utils/build-browser-features_spec.ts
new file mode 100644
index 000000000000..0f111b563e1d
--- /dev/null
+++ b/packages/angular_devkit/build_angular/src/utils/build-browser-features_spec.ts
@@ -0,0 +1,195 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+
+import { TestProjectHost } from '@angular-devkit/architect/testing';
+import { getSystemPath, join } from '@angular-devkit/core';
+import { ScriptTarget } from 'typescript';
+import { BuildBrowserFeatures } from './build-browser-features';
+
+const devkitRoot = (global as any)._DevKitRoot; // tslint:disable-line:no-any
+const workspaceRoot = join(
+ devkitRoot,
+ 'tests/angular_devkit/build_angular/hello-world-app/');
+
+const host = new TestProjectHost(workspaceRoot);
+
+describe('BuildBrowserFeatures', () => {
+ let workspaceRootSysPath = '';
+ beforeEach(async () => {
+ await host.initialize().toPromise();
+ workspaceRootSysPath = getSystemPath(host.root());
+ });
+
+ afterEach(async () => host.restore().toPromise());
+
+ describe('isDifferentialLoadingNeeded', () => {
+ it('should be true for for IE 9-11 and ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'IE 9-11',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isDifferentialLoadingNeeded()).toBe(true);
+ });
+
+ it('should be false for Chrome and ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'last 1 chrome version',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isDifferentialLoadingNeeded()).toBe(false);
+ });
+
+ it('detects no need for differential loading for target is ES5', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'last 1 chrome version',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES5,
+ );
+ expect(buildBrowserFeatures.isDifferentialLoadingNeeded()).toBe(false);
+ });
+
+ it('should be false for Safari 10.1 when target is ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari 10.1',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isDifferentialLoadingNeeded()).toBe(false);
+ });
+ });
+
+ describe('isFeatureSupported', () => {
+ it('should be true for es6-module and Safari 10.1', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari 10.1',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isFeatureSupported('es6-module')).toBe(true);
+ });
+
+ it('should be false for es6-module and IE9', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'IE 9',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isFeatureSupported('es6-module')).toBe(false);
+ });
+
+ it('should be true for es6-module and last 1 chrome version', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'last 1 chrome version',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isFeatureSupported('es6-module')).toBe(true);
+ });
+
+ it('should be true for es6-module and Edge 18', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Edge 18',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isFeatureSupported('es6-module')).toBe(true);
+ });
+ });
+
+ describe('isNoModulePolyfillNeeded', () => {
+ it('should be false for Safari 10.1 when target is ES5', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari 10.1',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES5,
+ );
+ expect(buildBrowserFeatures.isNoModulePolyfillNeeded()).toBe(false);
+ });
+
+ it('should be false for Safari 10.1 when target is ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari 10.1',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isNoModulePolyfillNeeded()).toBe(false);
+ });
+
+ it('should be true for Safari 9+ when target is ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari >= 9',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isNoModulePolyfillNeeded()).toBe(true);
+ });
+
+ it('should be false for Safari 9+ when target is ES5', () => {
+ host.writeMultipleFiles({
+ 'browserslist': 'Safari >= 9',
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES5,
+ );
+ expect(buildBrowserFeatures.isNoModulePolyfillNeeded()).toBe(false);
+ });
+
+ it('should be false when not supporting Safari 10.1 target is ES2015', () => {
+ host.writeMultipleFiles({
+ 'browserslist': `
+ Edge 18
+ IE 9
+ `,
+ });
+
+ const buildBrowserFeatures = new BuildBrowserFeatures(
+ workspaceRootSysPath,
+ ScriptTarget.ES2015,
+ );
+ expect(buildBrowserFeatures.isNoModulePolyfillNeeded()).toBe(false);
+ });
+ });
+});
diff --git a/packages/angular_devkit/build_angular/src/utils/differential-loading.ts b/packages/angular_devkit/build_angular/src/utils/differential-loading.ts
deleted file mode 100644
index 456007ebff5b..000000000000
--- a/packages/angular_devkit/build_angular/src/utils/differential-loading.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
-
-import * as browserslist from 'browserslist';
-import * as caniuse from 'caniuse-api';
-import { ScriptTarget } from 'typescript';
-
-
-export function isDifferentialLoadingNeeded(
- projectRoot: string,
- target: ScriptTarget = ScriptTarget.ES5): boolean {
-
- const supportES2015 = target !== ScriptTarget.ES3 && target !== ScriptTarget.ES5;
-
- return supportES2015 && isEs5SupportNeeded(projectRoot);
-}
-
-export function isEs5SupportNeeded(projectRoot: string): boolean {
- const browsersList: string[] = browserslist(
- undefined, {
- path: projectRoot,
- });
-
- return !caniuse.isSupported('es6-module', browsersList.join(', '));
-}
diff --git a/packages/angular_devkit/build_angular/src/utils/differential-loading_spec.ts b/packages/angular_devkit/build_angular/src/utils/differential-loading_spec.ts
deleted file mode 100644
index 1307fd9f67cd..000000000000
--- a/packages/angular_devkit/build_angular/src/utils/differential-loading_spec.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
-
-
-import { TestProjectHost } from '@angular-devkit/architect/testing';
-import { getSystemPath, join } from '@angular-devkit/core';
-import { ScriptTarget } from 'typescript';
-import { isDifferentialLoadingNeeded } from './differential-loading';
-
-const devkitRoot = (global as any)._DevKitRoot; // tslint:disable-line:no-any
-const workspaceRoot = join(
- devkitRoot,
- 'tests/angular_devkit/build_angular/hello-world-app/');
-
-const host = new TestProjectHost(workspaceRoot);
-
-
-describe('differential loading', () => {
-
- beforeEach(async () => host.initialize().toPromise());
- afterEach(async () => host.restore().toPromise());
-
- it('detects the need for differential loading for IE 9-11 and ES2015', () => {
- host.writeMultipleFiles({
- 'browserslist': 'IE 9-11',
- });
-
- const needed = isDifferentialLoadingNeeded(getSystemPath(host.root()), ScriptTarget.ES2015);
- expect(needed).toBe(true);
- });
-
- it('detects no need for differential loading for Chrome and ES2015', () => {
- host.writeMultipleFiles({
- 'browserslist': 'last 1 chrome version',
- });
-
- const needed = isDifferentialLoadingNeeded(getSystemPath(host.root()), ScriptTarget.ES2015);
-
- expect(needed).toBe(false);
- });
-
- it('detects no need for differential loading for target is ES5', () => {
- host.writeMultipleFiles({
- 'browserslist': 'last 1 chrome version',
- });
-
- const needed = isDifferentialLoadingNeeded(getSystemPath(host.root()), ScriptTarget.ES5);
-
- expect(needed).toBe(false);
- });
-});
diff --git a/packages/angular_devkit/build_angular/src/utils/index.ts b/packages/angular_devkit/build_angular/src/utils/index.ts
index 0f297fff122b..8cd7670f0a9b 100644
--- a/packages/angular_devkit/build_angular/src/utils/index.ts
+++ b/packages/angular_devkit/build_angular/src/utils/index.ts
@@ -5,9 +5,10 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
+
+export * from './build-browser-features';
export * from './default-progress';
export * from './delete-output-dir';
-export * from './differential-loading';
export * from './run-module-as-observable-fork';
export * from './normalize-file-replacements';
export * from './normalize-asset-patterns';
diff --git a/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts b/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts
index 94966ee738bd..df478dbfde32 100644
--- a/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts
+++ b/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts
@@ -24,7 +24,7 @@ import { getEsVersionForFileName } from '../angular-cli-files/models/webpack-con
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
import { Schema as BrowserBuilderSchema } from '../browser/schema';
import { NormalizedBrowserBuilderSchema, defaultProgress, normalizeBrowserSchema } from '../utils';
-import { isDifferentialLoadingNeeded } from './differential-loading';
+import { BuildBrowserFeatures } from './build-browser-features';
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const webpackMerge = require('webpack-merge');
@@ -53,9 +53,11 @@ export async function generateWebpackConfig(
// At the moment, only the browser builder supports differential loading
// However this config generation is used by multiple builders such as dev-server
- const scriptTarget = tsConfig.options.target;
+ const scriptTarget = tsConfig.options.target || ts.ScriptTarget.ES5;
+ const buildBrowserFeatures = new BuildBrowserFeatures(projectRoot, scriptTarget);
const differentialLoading = context.builder.builderName === 'browser'
- && isDifferentialLoadingNeeded(projectRoot, scriptTarget) && !options.watch;
+ && !options.watch
+ && buildBrowserFeatures.isDifferentialLoadingNeeded();
const scriptTargets = [scriptTarget];
diff --git a/packages/angular_devkit/build_angular/test/browser/differential_loading_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/differential_loading_spec_large.ts
index 62c80dafa543..16530d00e934 100644
--- a/packages/angular_devkit/build_angular/test/browser/differential_loading_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/differential_loading_spec_large.ts
@@ -73,8 +73,6 @@ describe('Browser Builder with differential loading', () => {
'main.js',
'main.js.map',
- 'polyfills-es5.js',
- 'polyfills-es5.js.map',
'polyfills.js',
'polyfills.js.map',
diff --git a/tests/angular_devkit/build_angular/hello-world-app/package.json b/tests/angular_devkit/build_angular/hello-world-app/package.json
index 97164be01a98..5aecb7dd20b6 100644
--- a/tests/angular_devkit/build_angular/hello-world-app/package.json
+++ b/tests/angular_devkit/build_angular/hello-world-app/package.json
@@ -23,7 +23,6 @@
"@angular/platform-browser": "^6.0.0-rc.0",
"@angular/platform-browser-dynamic": "^6.0.0-rc.0",
"@angular/router": "^6.0.0-rc.0",
- "core-js": "^2.4.1",
"rxjs": "~6.2.0",
"zone.js": "^0.8.19"
},
diff --git a/tests/angular_devkit/build_angular/hello-world-app/src/polyfills.ts b/tests/angular_devkit/build_angular/hello-world-app/src/polyfills.ts
index d7fd9a7ba789..bd13d5722895 100644
--- a/tests/angular_devkit/build_angular/hello-world-app/src/polyfills.ts
+++ b/tests/angular_devkit/build_angular/hello-world-app/src/polyfills.ts
@@ -25,41 +25,39 @@
* BROWSER POLYFILLS
*/
-/** IE9, IE10 and IE11 requires all of the following polyfills. **/
-// import 'core-js/es6/symbol';
-// import 'core-js/es6/object';
-// import 'core-js/es6/function';
-// import 'core-js/es6/parse-int';
-// import 'core-js/es6/parse-float';
-// import 'core-js/es6/number';
-// import 'core-js/es6/math';
-// import 'core-js/es6/string';
-// import 'core-js/es6/date';
-// import 'core-js/es6/array';
-// import 'core-js/es6/regexp';
-// import 'core-js/es6/map';
-// import 'core-js/es6/weak-map';
-// import 'core-js/es6/set';
-
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
-/** IE10 and IE11 requires the following for the Reflect API. */
-// import 'core-js/es6/reflect';
-
-
-/** Evergreen browsers require these. **/
-// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
-import 'core-js/es7/reflect';
-
-
/**
- * Required to support Web Animations `@angular/platform-browser/animations`.
- * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
- **/
+ * Web Animations `@angular/platform-browser/animations`
+ * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
+ * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
+ */
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
-
+/**
+ * By default, zone.js will patch all possible macroTask and DomEvents
+ * user can disable parts of macroTask/DomEvents patch by setting following flags
+ * because those flags need to be set before `zone.js` being loaded, and webpack
+ * will put import in the top of bundle, so user need to create a separate file
+ * in this directory (for example: zone-flags.ts), and put the following flags
+ * into that file, and then add the following code before importing zone.js.
+ * import './zone-flags.ts';
+ *
+ * The flags allowed in zone-flags.ts are listed here.
+ *
+ * The following flags will work for all browsers.
+ *
+ * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
+ * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
+ * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
+ *
+ * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
+ * with the following flag, it will bypass `zone.js` patch for IE/Edge
+ *
+ * (window as any).__Zone_enable_cross_context_check = true;
+ *
+ */
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
@@ -67,7 +65,6 @@ import 'core-js/es7/reflect';
import 'zone.js/dist/zone'; // Included with Angular CLI.
-
/***************************************************************************************************
* APPLICATION IMPORTS
*/
diff --git a/tests/legacy-cli/e2e/tests/misc/support-safari-10.1.ts b/tests/legacy-cli/e2e/tests/misc/support-safari-10.1.ts
new file mode 100644
index 000000000000..f78cb217bdcb
--- /dev/null
+++ b/tests/legacy-cli/e2e/tests/misc/support-safari-10.1.ts
@@ -0,0 +1,42 @@
+import { oneLineTrim } from 'common-tags';
+import {
+ expectFileNotToExist,
+ expectFileToExist,
+ expectFileToMatch,
+ writeFile,
+} from '../../utils/fs';
+import { ng } from '../../utils/process';
+
+export default async function () {
+ await writeFile('browserslist', 'Safari 10.1');
+ await ng('build');
+ await expectFileNotToExist('dist/test-project/polyfills-es5.js');
+ await expectFileNotToExist('dist/test-project/polyfills-nomodule-es5.js');
+ await expectFileToMatch('dist/test-project/index.html', oneLineTrim`
+
+
+
+
+
+ `);
+
+ await writeFile('browserslist', `
+ IE 9
+ Safari 10.1
+ `);
+ await ng('build');
+ await expectFileToExist('dist/test-project/polyfills-nomodule-es5.js');
+ await expectFileToMatch('dist/test-project/index.html', oneLineTrim`
+
+
+
+
+
+
+
+
+
+
+
+ `);
+}
diff --git a/yarn.lock b/yarn.lock
index 72b867017af8..c98c5eef4ef0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -300,10 +300,10 @@
resolved "https://registry.yarnpkg.com/@types/browserslist/-/browserslist-4.4.0.tgz#e2a5f7f8c7e97afb39f50812a77e5230d3ca2353"
integrity sha512-hrIjWSu7Hh96/rKlpChe58qHEwIZ0+F5Zf4QNdvSVP5LUXbaJM04g9tBjo702VTNqPZr5znEJeqNR3nAV3vJPg==
-"@types/caniuse-api@^3.0.0":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@types/caniuse-api/-/caniuse-api-3.0.0.tgz#af31cc52062be0ab24583be072fd49b634dcc2fe"
- integrity sha512-wT1VfnScjAftZsvLYaefu/UuwYJdYBwD2JDL2OQd01plGmuAoir5V6HnVHgrfh7zEwcasoiyO2wQ+W58sNh2sw==
+"@types/caniuse-lite@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@types/caniuse-lite/-/caniuse-lite-1.0.0.tgz#6506ed4b3f8d19def130d19419062960e86cc3bc"
+ integrity sha512-g28510gzJpFL0xqvuGAlI+dfIr3qvUcZQVFc7f7u2VlWVqI1oBkWhGLYh3fXfoflR7HRnU4w0NRux0pPJQ7VVg==
"@types/caseless@*":
version "0.12.1"
@@ -1871,20 +1871,10 @@ camelcase@^5.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-caniuse-api@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
- integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
- dependencies:
- browserslist "^4.0.0"
- caniuse-lite "^1.0.0"
- lodash.memoize "^4.1.2"
- lodash.uniq "^4.5.0"
-
-caniuse-lite@^1.0.0:
- version "1.0.30000955"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000955.tgz#360fdb9a1e41d6dd996130411334e44a39e4446d"
- integrity sha512-6AwmIKgqCYfDWWadRkAuZSHMQP4Mmy96xAXEdRBlN/luQhlRYOKgwOlZ9plpCOsVbBuqbTmGqDK3JUM/nlr8CA==
+caniuse-lite@1.0.30000974:
+ version "1.0.30000974"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz#b7afe14ee004e97ce6dc73e3f878290a12928ad8"
+ integrity sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==
caniuse-lite@^1.0.30000898:
version "1.0.30000903"
@@ -5870,11 +5860,6 @@ lodash.get@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
-lodash.memoize@^4.1.2:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
- integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
-
lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@@ -5895,11 +5880,6 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "~3.0.0"
-lodash.uniq@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
- integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-
lodash@^4.16.6, lodash@^4.17.11, lodash@^4.17.5:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"