diff --git a/package.json b/package.json index ff6a545cca43..c3d7aebd3e7c 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,8 @@ "@bazel/karma": "~0.26.0", "@bazel/typescript": "~0.26.0", "@ngtools/json-schema": "^1.1.0", + "@types/browserslist": "^4.4.0", + "@types/caniuse-api": "^3.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 52ae8c537d72..af301fb2375a 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -14,6 +14,8 @@ "@ngtools/webpack": "0.0.0", "ajv": "6.10.0", "autoprefixer": "9.5.0", + "browserslist": "4.5.2", + "caniuse-api": "3.0.0", "circular-dependency-plugin": "5.0.2", "clean-css": "4.2.1", "copy-webpack-plugin": "5.0.2", @@ -83,5 +85,8 @@ "popper.js": "^1.14.1", "protractor": "~5.4.0", "zone.js": "^0.9.0" + }, + "peerDependencies": { + "typescript": ">=2.7 < 3.4" } } diff --git a/packages/angular_devkit/build_angular/src/browser/utils.ts b/packages/angular_devkit/build_angular/src/browser/utils.ts new file mode 100644 index 000000000000..c4d202279fd1 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/browser/utils.ts @@ -0,0 +1,32 @@ +/** + * @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 { Path, getSystemPath } from '@angular-devkit/core'; +import * as browserslist from 'browserslist'; +import * as caniuse from 'caniuse-api'; +import * as ts from 'typescript'; + + +export function isDifferentialLoadingNeeded( + projectRoot: Path, + target: ts.ScriptTarget): boolean { + + const supportES2015 = target !== ts.ScriptTarget.ES3 && target !== ts.ScriptTarget.ES5; + + return supportES2015 && isEs5SupportNeeded(projectRoot); +} + +export function isEs5SupportNeeded(projectRoot: Path): boolean { + + const browsersList: string[] = browserslist( + undefined, { + path: getSystemPath(projectRoot), + }); + + return !caniuse.isSupported('es6-module', browsersList.join(', ')); +} diff --git a/packages/angular_devkit/build_angular/src/browser/utils_spec.ts b/packages/angular_devkit/build_angular/src/browser/utils_spec.ts new file mode 100644 index 000000000000..b35e114830e5 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/browser/utils_spec.ts @@ -0,0 +1,61 @@ +/** + * @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 { join, normalize } from '@angular-devkit/core'; +import { ScriptTarget } from 'typescript'; +import { + isDifferentialLoadingNeeded, +} from './utils'; + +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(normalize(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(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(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(host.root(), ScriptTarget.ES5); + + expect(needed).toBe(false); + }); +}); diff --git a/yarn.lock b/yarn.lock index c30322ecfbf7..02a72cc7cd88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -253,6 +253,16 @@ "@types/connect" "*" "@types/node" "*" +"@types/browserslist@^4.4.0": + version "4.4.0" + 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/caseless@*": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a" @@ -1562,6 +1572,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" +browserslist@4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.2.tgz#36ad281f040af684555a23c780f5c2081c752df0" + integrity sha512-zmJVLiKLrzko0iszd/V4SsjTaomFeoVzQGYYOYgRgsbh7WNh95RgDB0CmBdFWYs/3MyFSt69NypjL/h3iaddKQ== + dependencies: + caniuse-lite "^1.0.30000951" + electron-to-chromium "^1.3.116" + node-releases "^1.1.11" + browserslist@^4.0.0, browserslist@^4.3.3: version "4.3.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" @@ -1785,6 +1804,21 @@ camelcase@^4.0.0, camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +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, caniuse-lite@^1.0.30000951: + 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.30000898, caniuse-lite@^1.0.30000899: version "1.0.30000903" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000903.tgz#86d46227759279b3db345ddbe778335dbba9e858" @@ -3016,6 +3050,11 @@ electron-to-chromium@^1.3.113: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" integrity sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g== +electron-to-chromium@^1.3.116: + version "1.3.121" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.121.tgz#761aaec1ec947b8ed3e9538177598d8f6ca3b5bd" + integrity sha512-ALxUkgrnQ6zg2SN9zHnwDcDRy577haGT9dqsbq8lfeAgmEUPC+58SrrU8vIHpGRf7SEyyBYy4mlfonDnoKxONw== + electron-to-chromium@^1.3.82: version "1.3.82" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.82.tgz#7d13ae4437d2a783de3f4efba96b186c540b67b1" @@ -5598,6 +5637,11 @@ 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" @@ -5618,6 +5662,11 @@ 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" @@ -6293,6 +6342,13 @@ node-releases@^1.0.1: dependencies: semver "^5.3.0" +node-releases@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.12.tgz#1d6baf544316b5422fcd35efe18708370a4e7637" + integrity sha512-Y+AQ1xdjcgaEzpL65PBEF3fnl1FNKnDh9Zm+AUQLIlyyqtSc4u93jyMN4zrjMzdwKQ10RTr3tgY1x7qpsfF/xg== + dependencies: + semver "^5.3.0" + node-releases@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.8.tgz#32a63fff63c5e51b7e0f540ac95947d220fc6862"