@angular-devkit/build-angular 0.800.0 → 0.800.4
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 +8 -7
- package/src/angular-cli-files/models/build-options.d.ts +3 -2
- package/src/angular-cli-files/models/safari-nomodule.js +3 -17
- package/src/angular-cli-files/models/webpack-configs/common.js +40 -34
- package/src/angular-cli-files/models/webpack-configs/typescript.d.ts +1 -1
- package/src/angular-cli-files/models/webpack-configs/typescript.js +5 -5
- package/src/angular-cli-files/models/webpack-configs/utils.d.ts +0 -1
- package/src/angular-cli-files/models/webpack-configs/utils.js +0 -4
- package/src/angular-cli-files/plugins/karma-context.html +1 -1
- package/src/angular-cli-files/plugins/karma-debug.html +1 -1
- package/src/angular-cli-files/plugins/karma.js +3 -3
- package/src/angular-cli-files/utilities/bundle-calculator.js +1 -0
- package/src/angular-cli-files/utilities/index-file/write-index-html.js +1 -1
- package/src/angular-cli-files/utilities/package-chunk-sort.js +1 -0
- package/src/angular-cli-files/utilities/read-tsconfig.d.ts +9 -2
- package/src/angular-cli-files/utilities/read-tsconfig.js +25 -8
- package/src/angular-cli-files/utilities/service-worker/index.js +1 -1
- package/src/browser/index.js +15 -7
- package/src/dev-server/schema.d.ts +3 -1
- package/src/dev-server/schema.json +1 -1
- package/src/extract-i18n/index.js +9 -0
- package/src/karma/index.js +1 -1
- package/src/utils/build-browser-features.d.ts +35 -0
- package/src/utils/build-browser-features.js +74 -0
- package/src/utils/index.d.ts +1 -1
- package/src/utils/index.js +5 -5
- package/src/utils/webpack-browser-config.js +16 -6
- package/src/utils/differential-loading.d.ts +0 -10
- package/src/utils/differential-loading.js +0 -24
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "0.800.
|
|
3
|
+
"version": "0.800.4",
|
|
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.
|
|
11
|
-
"@angular-devkit/build-optimizer": "0.800.
|
|
12
|
-
"@angular-devkit/build-webpack": "0.800.
|
|
13
|
-
"@angular-devkit/core": "8.0.
|
|
14
|
-
"@ngtools/webpack": "8.0.
|
|
10
|
+
"@angular-devkit/architect": "0.800.4",
|
|
11
|
+
"@angular-devkit/build-optimizer": "0.800.4",
|
|
12
|
+
"@angular-devkit/build-webpack": "0.800.4",
|
|
13
|
+
"@angular-devkit/core": "8.0.4",
|
|
14
|
+
"@ngtools/webpack": "8.0.4",
|
|
15
15
|
"ajv": "6.10.0",
|
|
16
16
|
"autoprefixer": "9.5.1",
|
|
17
17
|
"browserslist": "4.5.5",
|
|
18
|
-
"caniuse-
|
|
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 {
|
|
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:
|
|
82
|
+
tsConfig: ParsedConfiguration;
|
|
82
83
|
tsConfigPath: string;
|
|
83
84
|
supportES2015: boolean;
|
|
84
85
|
}
|
|
@@ -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
|
|
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);
|
|
@@ -45,41 +45,47 @@ function getCommonConfig(wco) {
|
|
|
45
45
|
if (buildOptions.main) {
|
|
46
46
|
entryPoints['main'] = [path.resolve(root, buildOptions.main)];
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
if (wco.buildOptions.platform !== 'server') {
|
|
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];
|
|
65
|
+
}
|
|
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')];
|
|
72
|
+
if (!buildOptions.aot) {
|
|
73
|
+
entryPoints[polyfillsChunkName].push(path.join(__dirname, '..', 'es5-jit-polyfills.js'));
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if (buildOptions.polyfills) {
|
|
78
|
+
entryPoints['polyfills'] = [
|
|
79
|
+
...(entryPoints['polyfills'] || []),
|
|
80
|
+
path.resolve(root, buildOptions.polyfills),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
if (!buildOptions.aot) {
|
|
84
|
+
entryPoints['polyfills'] = [
|
|
85
|
+
...(entryPoints['polyfills'] || []),
|
|
86
|
+
path.join(__dirname, '..', 'jit-polyfills.js'),
|
|
87
|
+
];
|
|
70
88
|
}
|
|
71
|
-
}
|
|
72
|
-
if (buildOptions.polyfills) {
|
|
73
|
-
entryPoints['polyfills'] = [
|
|
74
|
-
...(entryPoints['polyfills'] || []),
|
|
75
|
-
path.resolve(root, buildOptions.polyfills),
|
|
76
|
-
];
|
|
77
|
-
}
|
|
78
|
-
if (!buildOptions.aot) {
|
|
79
|
-
entryPoints['polyfills'] = [
|
|
80
|
-
...(entryPoints['polyfills'] || []),
|
|
81
|
-
path.join(__dirname, '..', 'jit-polyfills.js'),
|
|
82
|
-
];
|
|
83
89
|
}
|
|
84
90
|
if (buildOptions.profile || process.env['NG_BUILD_PROFILING']) {
|
|
85
91
|
extraPlugins.push(new webpack_1.debug.ProfilingPlugin({
|
|
@@ -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,
|
|
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,
|
|
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 =
|
|
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:
|
|
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,
|
|
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 },
|
|
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 = {
|
|
@@ -28,8 +28,8 @@ Reloaded before every execution run.
|
|
|
28
28
|
%MAPPINGS%
|
|
29
29
|
</script>
|
|
30
30
|
<script src="_karma_webpack_/runtime.js" crossorigin="anonymous"></script>
|
|
31
|
-
<script src="_karma_webpack_/polyfills.js" crossorigin="anonymous"></script>
|
|
32
31
|
<script src="_karma_webpack_/polyfills-es5.js" crossorigin="anonymous" nomodule></script>
|
|
32
|
+
<script src="_karma_webpack_/polyfills.js" crossorigin="anonymous"></script>
|
|
33
33
|
<!-- Dynamically replaced with <script> tags -->
|
|
34
34
|
%SCRIPTS%
|
|
35
35
|
<script src="_karma_webpack_/styles.js" crossorigin="anonymous"></script>
|
|
@@ -29,8 +29,8 @@ just for immediate execution, without reporting to Karma server.
|
|
|
29
29
|
%MAPPINGS%
|
|
30
30
|
</script>
|
|
31
31
|
<script src="_karma_webpack_/runtime.js" crossorigin="anonymous"></script>
|
|
32
|
-
<script src="_karma_webpack_/polyfills.js" crossorigin="anonymous"></script>
|
|
33
32
|
<script src="_karma_webpack_/polyfills-es5.js" crossorigin="anonymous" nomodule></script>
|
|
33
|
+
<script src="_karma_webpack_/polyfills.js" crossorigin="anonymous"></script>
|
|
34
34
|
<!-- Dynamically replaced with <script> tags -->
|
|
35
35
|
%SCRIPTS%
|
|
36
36
|
<script src="_karma_webpack_/styles.js" crossorigin="anonymous"></script>
|
|
@@ -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.
|
|
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.
|
|
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 = {
|
|
@@ -29,6 +29,7 @@ class BundleCalculator extends Calculator {
|
|
|
29
29
|
const size = this.compilation.chunks
|
|
30
30
|
.filter(chunk => chunk.name === this.budget.name)
|
|
31
31
|
.reduce((files, chunk) => [...files, ...chunk.files], [])
|
|
32
|
+
.filter((file) => !file.endsWith('.map'))
|
|
32
33
|
.map((file) => this.compilation.assets[file].size())
|
|
33
34
|
.reduce((total, size) => total + size, 0);
|
|
34
35
|
return [{ size, label: this.budget.name }];
|
|
@@ -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(
|
|
24
|
+
files: filterAndMapBuildFiles(ES2015BuildFiles, '.css'),
|
|
25
25
|
noModuleFiles: filterAndMapBuildFiles(ES5BuildFiles, '.js'),
|
|
26
26
|
moduleFiles: filterAndMapBuildFiles(ES2015BuildFiles, '.js'),
|
|
27
27
|
loadOutputFile: async (filePath) => {
|
|
@@ -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
|
|
9
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
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
|
}
|
package/src/browser/index.js
CHANGED
|
@@ -106,11 +106,10 @@ function buildWebpackBrowser(options, context, transforms = {}) {
|
|
|
106
106
|
throw new Error('Must either have a target from the context or a default project.');
|
|
107
107
|
}
|
|
108
108
|
const projectRoot = core_1.resolve(workspace.root, core_1.normalize(workspace.getProject(projectName).root));
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
tsConfig.options.target !== typescript_1.ScriptTarget.ES2015) {
|
|
109
|
+
const tsConfig = read_tsconfig_1.readTsconfig(options.tsConfig, context.workspaceRoot);
|
|
110
|
+
const target = tsConfig.options.target || typescript_1.ScriptTarget.ES5;
|
|
111
|
+
const buildBrowserFeatures = new utils_1.BuildBrowserFeatures(core_1.getSystemPath(projectRoot), target);
|
|
112
|
+
if (target > typescript_1.ScriptTarget.ES2015 && buildBrowserFeatures.isDifferentialLoadingNeeded()) {
|
|
114
113
|
context.logger.warn(core_1.tags.stripIndent `
|
|
115
114
|
WARNING: Using differential loading with targets ES5 and ES2016 or higher may
|
|
116
115
|
cause problems. Browsers with support for ES2015 will load the ES2016+ scripts
|
|
@@ -145,14 +144,14 @@ function buildWebpackBrowser(options, context, transforms = {}) {
|
|
|
145
144
|
scripts: options.scripts,
|
|
146
145
|
styles: options.styles,
|
|
147
146
|
})
|
|
148
|
-
.pipe(operators_1.map(() => ({ success: true })), operators_1.catchError(
|
|
147
|
+
.pipe(operators_1.map(() => ({ success: true })), operators_1.catchError(error => rxjs_1.of({ success: false, error: mapErrorToMessage(error) })));
|
|
149
148
|
}
|
|
150
149
|
else {
|
|
151
150
|
return rxjs_1.of({ success });
|
|
152
151
|
}
|
|
153
152
|
}), operators_1.concatMap(buildEvent => {
|
|
154
153
|
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 }),
|
|
154
|
+
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
155
|
}
|
|
157
156
|
else {
|
|
158
157
|
return rxjs_1.of(buildEvent);
|
|
@@ -165,4 +164,13 @@ function buildWebpackBrowser(options, context, transforms = {}) {
|
|
|
165
164
|
}));
|
|
166
165
|
}
|
|
167
166
|
exports.buildWebpackBrowser = buildWebpackBrowser;
|
|
167
|
+
function mapErrorToMessage(error) {
|
|
168
|
+
if (error instanceof Error) {
|
|
169
|
+
return error.message;
|
|
170
|
+
}
|
|
171
|
+
if (typeof error === 'string') {
|
|
172
|
+
return error;
|
|
173
|
+
}
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
168
176
|
exports.default = architect_1.createBuilder(buildWebpackBrowser);
|
|
@@ -72,7 +72,9 @@ export interface Schema {
|
|
|
72
72
|
*/
|
|
73
73
|
proxyConfig?: string;
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* The URL that the browser client (or live-reload client, if enabled) should use to connect
|
|
76
|
+
* to the development server. Use for a complex dev server setup, such as one with reverse
|
|
77
|
+
* proxies.
|
|
76
78
|
*/
|
|
77
79
|
publicHost?: string;
|
|
78
80
|
/**
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"publicHost": {
|
|
56
56
|
"type": "string",
|
|
57
|
-
"description": "
|
|
57
|
+
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
|
|
58
58
|
},
|
|
59
59
|
"servePath": {
|
|
60
60
|
"type": "string",
|
|
@@ -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,
|
package/src/karma/index.js
CHANGED
|
@@ -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;
|
package/src/utils/index.d.ts
CHANGED
|
@@ -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';
|
package/src/utils/index.js
CHANGED
|
@@ -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
|
|
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
|
-
&&
|
|
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;
|