@angular-devkit/build-angular 0.801.0-beta.3 → 0.801.2
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 +12 -13
- package/plugins/webpack/analytics.d.ts +2 -0
- package/plugins/webpack/analytics.js +25 -3
- package/src/angular-cli-files/models/es5-polyfills.js +1 -0
- package/src/angular-cli-files/models/webpack-configs/common.js +24 -29
- package/src/angular-cli-files/models/webpack-configs/styles.js +22 -16
- package/src/angular-cli-files/models/webpack-configs/utils.d.ts +3 -3
- package/src/angular-cli-files/models/webpack-configs/utils.js +21 -7
- package/src/angular-cli-files/plugins/index-html-webpack-plugin.d.ts +3 -0
- package/src/angular-cli-files/plugins/index-html-webpack-plugin.js +9 -4
- package/src/angular-cli-files/plugins/karma.js +0 -1
- package/src/angular-cli-files/plugins/single-test-transform.d.ts +28 -0
- package/src/angular-cli-files/plugins/single-test-transform.js +40 -0
- package/src/angular-cli-files/utilities/find-tests.d.ts +1 -0
- package/src/angular-cli-files/utilities/find-tests.js +55 -0
- package/src/angular-cli-files/utilities/index-file/augment-index-html.d.ts +3 -0
- package/src/angular-cli-files/utilities/index-file/augment-index-html.js +13 -6
- package/src/angular-cli-files/utilities/index-file/write-index-html.d.ts +3 -1
- package/src/angular-cli-files/utilities/index-file/write-index-html.js +6 -5
- package/src/angular-cli-files/utilities/package-chunk-sort.js +4 -2
- package/src/browser/index.js +20 -14
- package/src/browser/schema.d.ts +16 -0
- package/src/browser/schema.js +9 -0
- package/src/browser/schema.json +17 -1
- package/src/dev-server/index.js +46 -22
- package/src/karma/index.js +30 -2
- package/src/karma/schema.d.ts +13 -0
- package/src/karma/schema.json +14 -1
- package/src/utils/webpack-browser-config.js +1 -1
- package/test/utils.d.ts +2 -1
- package/test/utils.js +7 -2
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "0.801.
|
|
3
|
+
"version": "0.801.2",
|
|
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.801.
|
|
11
|
-
"@angular-devkit/build-optimizer": "0.801.
|
|
12
|
-
"@angular-devkit/build-webpack": "0.801.
|
|
13
|
-
"@angular-devkit/core": "8.1.
|
|
14
|
-
"@ngtools/webpack": "8.1.
|
|
10
|
+
"@angular-devkit/architect": "0.801.2",
|
|
11
|
+
"@angular-devkit/build-optimizer": "0.801.2",
|
|
12
|
+
"@angular-devkit/build-webpack": "0.801.2",
|
|
13
|
+
"@angular-devkit/core": "8.1.2",
|
|
14
|
+
"@ngtools/webpack": "8.1.2",
|
|
15
15
|
"ajv": "6.10.0",
|
|
16
16
|
"autoprefixer": "9.6.0",
|
|
17
17
|
"browserslist": "4.6.3",
|
|
18
|
-
"caniuse-lite": "1.0.
|
|
18
|
+
"caniuse-lite": "1.0.30000979",
|
|
19
19
|
"circular-dependency-plugin": "5.0.2",
|
|
20
20
|
"clean-css": "4.2.1",
|
|
21
21
|
"copy-webpack-plugin": "5.0.3",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"mini-css-extract-plugin": "0.7.0",
|
|
32
32
|
"minimatch": "3.0.4",
|
|
33
33
|
"parse5": "4.0.0",
|
|
34
|
-
"open": "6.
|
|
34
|
+
"open": "6.4.0",
|
|
35
35
|
"postcss": "7.0.17",
|
|
36
36
|
"postcss-import": "12.0.1",
|
|
37
37
|
"postcss-loader": "3.0.0",
|
|
38
38
|
"raw-loader": "1.0.0",
|
|
39
39
|
"rxjs": "6.4.0",
|
|
40
|
-
"sass": "1.
|
|
40
|
+
"sass": "1.22.2",
|
|
41
41
|
"sass-loader": "7.1.0",
|
|
42
|
-
"semver": "6.
|
|
42
|
+
"semver": "6.2.0",
|
|
43
43
|
"source-map-support": "0.5.12",
|
|
44
44
|
"source-map-loader": "0.2.4",
|
|
45
45
|
"speed-measure-webpack-plugin": "1.3.1",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"stylus-loader": "3.0.2",
|
|
49
49
|
"tree-kill": "1.2.1",
|
|
50
50
|
"terser-webpack-plugin": "1.3.0",
|
|
51
|
-
"webpack": "4.35.
|
|
51
|
+
"webpack": "4.35.2",
|
|
52
52
|
"webpack-dev-middleware": "3.7.0",
|
|
53
53
|
"webpack-dev-server": "3.7.2",
|
|
54
54
|
"webpack-merge": "4.2.1",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"worker-plugin": "3.1.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@angular/compiler-cli": "
|
|
60
|
+
"@angular/compiler-cli": "^8.0.0-beta.0 || ^8.1.0-beta.0 || ^8.2.0-beta.0 || ^8.3.0-beta.0 || ^8.4.0-beta.0 || >=9.0.0-beta < 9",
|
|
61
61
|
"typescript": ">=3.1 < 3.5"
|
|
62
62
|
},
|
|
63
63
|
"keywords": [
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
"homepage": "https://github.com/angular/angular-cli",
|
|
84
84
|
"husky": {
|
|
85
85
|
"hooks": {
|
|
86
|
-
"pre-commit": "lint-staged",
|
|
87
86
|
"pre-push": "node ./bin/devkit-admin hooks/pre-push"
|
|
88
87
|
}
|
|
89
88
|
}
|
|
@@ -29,6 +29,7 @@ export declare function countOccurrences(source: string, match: string, wordBrea
|
|
|
29
29
|
declare class AnalyticsBuildStats {
|
|
30
30
|
errors: string[];
|
|
31
31
|
numberOfNgOnInit: number;
|
|
32
|
+
numberOfComponents: number;
|
|
32
33
|
initialChunkSize: number;
|
|
33
34
|
totalChunkCount: number;
|
|
34
35
|
totalChunkSize: number;
|
|
@@ -55,6 +56,7 @@ export declare class NgBuildAnalyticsPlugin {
|
|
|
55
56
|
protected _reportBuildMetrics(stats: Stats): void;
|
|
56
57
|
protected _reportRebuildMetrics(stats: Stats): void;
|
|
57
58
|
protected _checkTsNormalModule(module: NormalModule): void;
|
|
59
|
+
protected _checkNgFactoryNormalModule(module: NormalModule): void;
|
|
58
60
|
protected _collectErrors(stats: Stats): void;
|
|
59
61
|
protected _collectBundleStats(json: any): void;
|
|
60
62
|
/************************************************************************************************
|
|
@@ -56,6 +56,7 @@ class AnalyticsBuildStats {
|
|
|
56
56
|
constructor() {
|
|
57
57
|
this.errors = [];
|
|
58
58
|
this.numberOfNgOnInit = 0;
|
|
59
|
+
this.numberOfComponents = 0;
|
|
59
60
|
this.initialChunkSize = 0;
|
|
60
61
|
this.totalChunkCount = 0;
|
|
61
62
|
this.totalChunkSize = 0;
|
|
@@ -87,6 +88,7 @@ class NgBuildAnalyticsPlugin {
|
|
|
87
88
|
const metrics = [];
|
|
88
89
|
metrics[core_1.analytics.NgCliAnalyticsMetrics.BuildTime] = (endTime - startTime);
|
|
89
90
|
metrics[core_1.analytics.NgCliAnalyticsMetrics.NgOnInitCount] = this._stats.numberOfNgOnInit;
|
|
91
|
+
metrics[core_1.analytics.NgCliAnalyticsMetrics.NgComponentCount] = this._stats.numberOfComponents;
|
|
90
92
|
metrics[core_1.analytics.NgCliAnalyticsMetrics.InitialChunkSize] = this._stats.initialChunkSize;
|
|
91
93
|
metrics[core_1.analytics.NgCliAnalyticsMetrics.TotalChunkCount] = this._stats.totalChunkCount;
|
|
92
94
|
metrics[core_1.analytics.NgCliAnalyticsMetrics.TotalChunkSize] = this._stats.totalChunkSize;
|
|
@@ -100,8 +102,10 @@ class NgBuildAnalyticsPlugin {
|
|
|
100
102
|
}
|
|
101
103
|
_getDimensions(stats) {
|
|
102
104
|
const dimensions = [];
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
if (this._stats.errors.length) {
|
|
106
|
+
// Adding commas before and after so the regex are easier to define filters.
|
|
107
|
+
dimensions[core_1.analytics.NgCliAnalyticsDimensions.BuildErrors] = `,${this._stats.errors.join()},`;
|
|
108
|
+
}
|
|
105
109
|
return dimensions;
|
|
106
110
|
}
|
|
107
111
|
_reportBuildMetrics(stats) {
|
|
@@ -116,10 +120,25 @@ class NgBuildAnalyticsPlugin {
|
|
|
116
120
|
}
|
|
117
121
|
_checkTsNormalModule(module) {
|
|
118
122
|
if (module._source) {
|
|
123
|
+
// PLEASE REMEMBER:
|
|
119
124
|
// We're dealing with ES5 _or_ ES2015 JavaScript at this point (we don't know for sure).
|
|
120
125
|
// Just count the ngOnInit occurences. Comments/Strings/calls occurences should be sparse
|
|
121
126
|
// so we just consider them within the margin of error. We do break on word break though.
|
|
122
127
|
this._stats.numberOfNgOnInit += countOccurrences(module._source.source(), 'ngOnInit', true);
|
|
128
|
+
// Count the number of `Component({` strings (case sensitive), which happens in __decorate().
|
|
129
|
+
// This does not include View Engine AOT compilation, we use the ngfactory for it.
|
|
130
|
+
this._stats.numberOfComponents += countOccurrences(module._source.source(), ' Component({');
|
|
131
|
+
// For Ivy we just count ngComponentDef.
|
|
132
|
+
this._stats.numberOfComponents += countOccurrences(module._source.source(), 'ngComponentDef', true);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
_checkNgFactoryNormalModule(module) {
|
|
136
|
+
if (module._source) {
|
|
137
|
+
// PLEASE REMEMBER:
|
|
138
|
+
// We're dealing with ES5 _or_ ES2015 JavaScript at this point (we don't know for sure).
|
|
139
|
+
// Count the number of `.ɵccf(` strings (case sensitive). They're calls to components
|
|
140
|
+
// factories.
|
|
141
|
+
this._stats.numberOfComponents += countOccurrences(module._source.source(), '.ɵccf(');
|
|
123
142
|
}
|
|
124
143
|
}
|
|
125
144
|
_collectErrors(stats) {
|
|
@@ -198,9 +217,12 @@ class NgBuildAnalyticsPlugin {
|
|
|
198
217
|
return;
|
|
199
218
|
}
|
|
200
219
|
// Check that it's a source file from the project.
|
|
201
|
-
if (module.
|
|
220
|
+
if (module.resource.endsWith('.ts')) {
|
|
202
221
|
this._checkTsNormalModule(module);
|
|
203
222
|
}
|
|
223
|
+
else if (module.resource.endsWith('.ngfactory.js')) {
|
|
224
|
+
this._checkNgFactoryNormalModule(module);
|
|
225
|
+
}
|
|
204
226
|
}
|
|
205
227
|
_compilation(compiler, compilation) {
|
|
206
228
|
this._reset();
|
|
@@ -48,8 +48,7 @@ function getCommonConfig(wco) {
|
|
|
48
48
|
const buildBrowserFeatures = new build_browser_features_1.BuildBrowserFeatures(projectRoot, tsConfig.options.target || typescript_1.ScriptTarget.ES5);
|
|
49
49
|
if ((buildOptions.scriptTargetOverride || tsConfig.options.target) === typescript_1.ScriptTarget.ES5) {
|
|
50
50
|
if (buildOptions.es5BrowserSupport ||
|
|
51
|
-
(buildOptions.es5BrowserSupport === undefined &&
|
|
52
|
-
buildBrowserFeatures.isEs5SupportNeeded())) {
|
|
51
|
+
(buildOptions.es5BrowserSupport === undefined && buildBrowserFeatures.isEs5SupportNeeded())) {
|
|
53
52
|
// The nomodule polyfill needs to be inject prior to any script and be
|
|
54
53
|
// outside of webpack compilation because otherwise webpack will cause the
|
|
55
54
|
// script to be wrapped in window["webpackJsonp"] which causes this to fail.
|
|
@@ -95,15 +94,14 @@ function getCommonConfig(wco) {
|
|
|
95
94
|
const hashFormat = utils_1.getOutputHashFormat(buildOptions.outputHashing || 'none');
|
|
96
95
|
// process global scripts
|
|
97
96
|
if (buildOptions.scripts.length > 0) {
|
|
98
|
-
const globalScriptsByBundleName = utils_1.normalizeExtraEntryPoints(buildOptions.scripts, 'scripts')
|
|
99
|
-
.reduce((prev, curr) => {
|
|
97
|
+
const globalScriptsByBundleName = utils_1.normalizeExtraEntryPoints(buildOptions.scripts, 'scripts').reduce((prev, curr) => {
|
|
100
98
|
const bundleName = curr.bundleName;
|
|
101
99
|
const resolvedPath = path.resolve(root, curr.input);
|
|
102
|
-
const existingEntry = prev.find(
|
|
100
|
+
const existingEntry = prev.find(el => el.bundleName === bundleName);
|
|
103
101
|
if (existingEntry) {
|
|
104
|
-
if (existingEntry.
|
|
102
|
+
if (existingEntry.inject && !curr.inject) {
|
|
105
103
|
// All entries have to be lazy for the bundle to be lazy.
|
|
106
|
-
throw new Error(`The ${curr.bundleName} bundle is mixing
|
|
104
|
+
throw new Error(`The ${curr.bundleName} bundle is mixing injected and non-injected scripts.`);
|
|
107
105
|
}
|
|
108
106
|
existingEntry.paths.push(resolvedPath);
|
|
109
107
|
}
|
|
@@ -111,15 +109,15 @@ function getCommonConfig(wco) {
|
|
|
111
109
|
prev.push({
|
|
112
110
|
bundleName,
|
|
113
111
|
paths: [resolvedPath],
|
|
114
|
-
|
|
112
|
+
inject: curr.inject,
|
|
115
113
|
});
|
|
116
114
|
}
|
|
117
115
|
return prev;
|
|
118
116
|
}, []);
|
|
119
117
|
// Add a new asset for each entry.
|
|
120
|
-
globalScriptsByBundleName.forEach(
|
|
118
|
+
globalScriptsByBundleName.forEach(script => {
|
|
121
119
|
// Lazy scripts don't get a hash, otherwise they can't be loaded by name.
|
|
122
|
-
const hash = script.
|
|
120
|
+
const hash = script.inject ? hashFormat.script : '';
|
|
123
121
|
const bundleName = script.bundleName;
|
|
124
122
|
extraPlugins.push(new scripts_webpack_plugin_1.ScriptsWebpackPlugin({
|
|
125
123
|
name: bundleName,
|
|
@@ -165,14 +163,14 @@ function getCommonConfig(wco) {
|
|
|
165
163
|
}));
|
|
166
164
|
}
|
|
167
165
|
if (buildOptions.statsJson) {
|
|
168
|
-
extraPlugins.push(new class {
|
|
166
|
+
extraPlugins.push(new (class {
|
|
169
167
|
apply(compiler) {
|
|
170
168
|
compiler.hooks.emit.tap('angular-cli-stats', compilation => {
|
|
171
169
|
const data = JSON.stringify(compilation.getStats().toJson('verbose'));
|
|
172
170
|
compilation.assets[`stats${targetInFileName}.json`] = new webpack_sources_1.RawSource(data);
|
|
173
171
|
});
|
|
174
172
|
}
|
|
175
|
-
});
|
|
173
|
+
})());
|
|
176
174
|
}
|
|
177
175
|
if (buildOptions.namedChunks) {
|
|
178
176
|
extraPlugins.push(new named_chunks_plugin_1.NamedLazyChunksPlugin());
|
|
@@ -219,7 +217,7 @@ function getCommonConfig(wco) {
|
|
|
219
217
|
extraMinimizers.push(new cleancss_webpack_plugin_1.CleanCssWebpackPlugin({
|
|
220
218
|
sourceMap: stylesSourceMap,
|
|
221
219
|
// component styles retain their original file name
|
|
222
|
-
test:
|
|
220
|
+
test: file => /\.(?:css|scss|sass|less|styl)$/.test(file),
|
|
223
221
|
}));
|
|
224
222
|
}
|
|
225
223
|
if (scriptsOptimization) {
|
|
@@ -249,15 +247,17 @@ function getCommonConfig(wco) {
|
|
|
249
247
|
},
|
|
250
248
|
// On server, we don't want to compress anything. We still set the ngDevMode = false for it
|
|
251
249
|
// to remove dev code, and ngI18nClosureMode to remove Closure compiler i18n code
|
|
252
|
-
compress:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
250
|
+
compress: buildOptions.platform == 'server'
|
|
251
|
+
? {
|
|
252
|
+
global_defs: angularGlobalDefinitions,
|
|
253
|
+
}
|
|
254
|
+
: {
|
|
255
|
+
pure_getters: buildOptions.buildOptimizer,
|
|
256
|
+
// PURE comments work best with 3 passes.
|
|
257
|
+
// See https://github.com/webpack/webpack/issues/2899#issuecomment-317425926.
|
|
258
|
+
passes: buildOptions.buildOptimizer ? 3 : 1,
|
|
259
|
+
global_defs: angularGlobalDefinitions,
|
|
260
|
+
},
|
|
261
261
|
// We also want to avoid mangling on server.
|
|
262
262
|
...(buildOptions.platform == 'server' ? { mangle: false } : {}),
|
|
263
263
|
};
|
|
@@ -277,18 +277,13 @@ function getCommonConfig(wco) {
|
|
|
277
277
|
`);
|
|
278
278
|
}
|
|
279
279
|
return {
|
|
280
|
-
mode: scriptsOptimization || stylesOptimization
|
|
281
|
-
? 'production'
|
|
282
|
-
: 'development',
|
|
280
|
+
mode: scriptsOptimization || stylesOptimization ? 'production' : 'development',
|
|
283
281
|
devtool: false,
|
|
284
282
|
profile: buildOptions.statsJson,
|
|
285
283
|
resolve: {
|
|
286
284
|
extensions: ['.ts', '.tsx', '.mjs', '.js'],
|
|
287
285
|
symlinks: !buildOptions.preserveSymlinks,
|
|
288
|
-
modules: [
|
|
289
|
-
wco.tsConfig.options.baseUrl || projectRoot,
|
|
290
|
-
'node_modules',
|
|
291
|
-
],
|
|
286
|
+
modules: [wco.tsConfig.options.baseUrl || projectRoot, 'node_modules'],
|
|
292
287
|
alias,
|
|
293
288
|
},
|
|
294
289
|
resolveLoader: {
|
|
@@ -26,6 +26,7 @@ const postcssImports = require('postcss-import');
|
|
|
26
26
|
* require('node-sass')
|
|
27
27
|
* require('sass-loader')
|
|
28
28
|
*/
|
|
29
|
+
// tslint:disable-next-line:no-big-function
|
|
29
30
|
function getStylesConfig(wco) {
|
|
30
31
|
const { root, buildOptions } = wco;
|
|
31
32
|
const entryPoints = {};
|
|
@@ -37,7 +38,7 @@ function getStylesConfig(wco) {
|
|
|
37
38
|
const postcssPluginCreator = function (loader) {
|
|
38
39
|
return [
|
|
39
40
|
postcssImports({
|
|
40
|
-
resolve: (url) => url.startsWith('~') ? url.substr(1) : url,
|
|
41
|
+
resolve: (url) => (url.startsWith('~') ? url.substr(1) : url),
|
|
41
42
|
load: (filename) => {
|
|
42
43
|
return new Promise((resolve, reject) => {
|
|
43
44
|
loader.fs.readFile(filename, (err, data) => {
|
|
@@ -65,9 +66,9 @@ function getStylesConfig(wco) {
|
|
|
65
66
|
// use includePaths from appConfig
|
|
66
67
|
const includePaths = [];
|
|
67
68
|
let lessPathOptions = {};
|
|
68
|
-
if (buildOptions.stylePreprocessorOptions
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
if (buildOptions.stylePreprocessorOptions &&
|
|
70
|
+
buildOptions.stylePreprocessorOptions.includePaths &&
|
|
71
|
+
buildOptions.stylePreprocessorOptions.includePaths.length > 0) {
|
|
71
72
|
buildOptions.stylePreprocessorOptions.includePaths.forEach((includePath) => includePaths.push(path.resolve(root, includePath)));
|
|
72
73
|
lessPathOptions = {
|
|
73
74
|
paths: includePaths,
|
|
@@ -85,8 +86,8 @@ function getStylesConfig(wco) {
|
|
|
85
86
|
else {
|
|
86
87
|
entryPoints[style.bundleName] = [resolvedPath];
|
|
87
88
|
}
|
|
88
|
-
// Add
|
|
89
|
-
if (style.
|
|
89
|
+
// Add non injected styles to the list.
|
|
90
|
+
if (!style.inject) {
|
|
90
91
|
chunkNames.push(style.bundleName);
|
|
91
92
|
}
|
|
92
93
|
// Add global css paths.
|
|
@@ -116,7 +117,8 @@ function getStylesConfig(wco) {
|
|
|
116
117
|
{ test: /\.css$/, use: [] },
|
|
117
118
|
{
|
|
118
119
|
test: /\.scss$|\.sass$/,
|
|
119
|
-
use: [
|
|
120
|
+
use: [
|
|
121
|
+
{
|
|
120
122
|
loader: 'sass-loader',
|
|
121
123
|
options: {
|
|
122
124
|
implementation: sassImplementation,
|
|
@@ -126,28 +128,33 @@ function getStylesConfig(wco) {
|
|
|
126
128
|
precision: 8,
|
|
127
129
|
includePaths,
|
|
128
130
|
},
|
|
129
|
-
}
|
|
131
|
+
},
|
|
132
|
+
],
|
|
130
133
|
},
|
|
131
134
|
{
|
|
132
135
|
test: /\.less$/,
|
|
133
|
-
use: [
|
|
136
|
+
use: [
|
|
137
|
+
{
|
|
134
138
|
loader: 'less-loader',
|
|
135
139
|
options: {
|
|
136
140
|
sourceMap: cssSourceMap,
|
|
137
141
|
javascriptEnabled: true,
|
|
138
142
|
...lessPathOptions,
|
|
139
143
|
},
|
|
140
|
-
}
|
|
144
|
+
},
|
|
145
|
+
],
|
|
141
146
|
},
|
|
142
147
|
{
|
|
143
148
|
test: /\.styl$/,
|
|
144
|
-
use: [
|
|
149
|
+
use: [
|
|
150
|
+
{
|
|
145
151
|
loader: 'stylus-loader',
|
|
146
152
|
options: {
|
|
147
153
|
sourceMap: cssSourceMap,
|
|
148
154
|
paths: includePaths,
|
|
149
155
|
},
|
|
150
|
-
}
|
|
156
|
+
},
|
|
157
|
+
],
|
|
151
158
|
},
|
|
152
159
|
];
|
|
153
160
|
// load component css as raw strings
|
|
@@ -181,10 +188,9 @@ function getStylesConfig(wco) {
|
|
|
181
188
|
options: {
|
|
182
189
|
ident: buildOptions.extractCss ? 'extracted' : 'embedded',
|
|
183
190
|
plugins: postcssPluginCreator,
|
|
184
|
-
sourceMap: cssSourceMap
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
? 'inline' : cssSourceMap,
|
|
191
|
+
sourceMap: cssSourceMap && !buildOptions.extractCss && !buildOptions.sourceMap.hidden
|
|
192
|
+
? 'inline'
|
|
193
|
+
: cssSourceMap,
|
|
188
194
|
},
|
|
189
195
|
},
|
|
190
196
|
...use,
|
|
@@ -15,9 +15,8 @@ export interface HashFormat {
|
|
|
15
15
|
script: string;
|
|
16
16
|
}
|
|
17
17
|
export declare function getOutputHashFormat(option: string, length?: number): HashFormat;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
18
|
+
declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
|
19
|
+
export declare type NormalizedEntryPoint = Required<Omit<ExtraEntryPointClass, 'lazy'>>;
|
|
21
20
|
export declare function normalizeExtraEntryPoints(extraEntryPoints: ExtraEntryPoint[], defaultBundleName: string): NormalizedEntryPoint[];
|
|
22
21
|
export declare function getSourceMapDevTool(scriptsSourceMap: boolean, stylesSourceMap: boolean, hiddenSourceMap?: boolean, inlineSourceMap?: boolean): SourceMapDevToolPlugin;
|
|
23
22
|
/**
|
|
@@ -25,3 +24,4 @@ export declare function getSourceMapDevTool(scriptsSourceMap: boolean, stylesSou
|
|
|
25
24
|
*/
|
|
26
25
|
export declare function getEsVersionForFileName(scriptTargetOverride: ScriptTarget | undefined, esVersionInFileName?: boolean): string;
|
|
27
26
|
export declare function isPolyfillsEntry(name: string): boolean;
|
|
27
|
+
export {};
|
|
@@ -17,8 +17,18 @@ function getOutputHashFormat(option, length = 20) {
|
|
|
17
17
|
const hashFormats = {
|
|
18
18
|
none: { chunk: '', extract: '', file: '', script: '' },
|
|
19
19
|
media: { chunk: '', extract: '', file: `.[hash:${length}]`, script: '' },
|
|
20
|
-
bundles: {
|
|
21
|
-
|
|
20
|
+
bundles: {
|
|
21
|
+
chunk: `.[chunkhash:${length}]`,
|
|
22
|
+
extract: `.[contenthash:${length}]`,
|
|
23
|
+
file: '',
|
|
24
|
+
script: `.[hash:${length}]`,
|
|
25
|
+
},
|
|
26
|
+
all: {
|
|
27
|
+
chunk: `.[chunkhash:${length}]`,
|
|
28
|
+
extract: `.[contenthash:${length}]`,
|
|
29
|
+
file: `.[hash:${length}]`,
|
|
30
|
+
script: `.[hash:${length}]`,
|
|
31
|
+
},
|
|
22
32
|
};
|
|
23
33
|
/* tslint:enable:max-line-length */
|
|
24
34
|
return hashFormats[option] || hashFormats['none'];
|
|
@@ -28,21 +38,23 @@ function normalizeExtraEntryPoints(extraEntryPoints, defaultBundleName) {
|
|
|
28
38
|
return extraEntryPoints.map(entry => {
|
|
29
39
|
let normalizedEntry;
|
|
30
40
|
if (typeof entry === 'string') {
|
|
31
|
-
normalizedEntry = { input: entry,
|
|
41
|
+
normalizedEntry = { input: entry, inject: true, bundleName: defaultBundleName };
|
|
32
42
|
}
|
|
33
43
|
else {
|
|
44
|
+
const { lazy, inject = true, ...newEntry } = entry;
|
|
45
|
+
const injectNormalized = entry.lazy !== undefined ? !entry.lazy : inject;
|
|
34
46
|
let bundleName;
|
|
35
47
|
if (entry.bundleName) {
|
|
36
48
|
bundleName = entry.bundleName;
|
|
37
49
|
}
|
|
38
|
-
else if (
|
|
50
|
+
else if (!injectNormalized) {
|
|
39
51
|
// Lazy entry points use the file name as bundle name.
|
|
40
52
|
bundleName = core_1.basename(core_1.normalize(entry.input.replace(/\.(js|css|scss|sass|less|styl)$/i, '')));
|
|
41
53
|
}
|
|
42
54
|
else {
|
|
43
55
|
bundleName = defaultBundleName;
|
|
44
56
|
}
|
|
45
|
-
normalizedEntry = { ...
|
|
57
|
+
normalizedEntry = { ...newEntry, inject: injectNormalized, bundleName };
|
|
46
58
|
}
|
|
47
59
|
return normalizedEntry;
|
|
48
60
|
});
|
|
@@ -59,6 +71,7 @@ function getSourceMapDevTool(scriptsSourceMap, stylesSourceMap, hiddenSourceMap
|
|
|
59
71
|
return new webpack_1.SourceMapDevToolPlugin({
|
|
60
72
|
filename: inlineSourceMap ? undefined : '[file].map',
|
|
61
73
|
include,
|
|
74
|
+
moduleFilenameTemplate: '[namespace]/[resource-path]',
|
|
62
75
|
append: hiddenSourceMap ? false : undefined,
|
|
63
76
|
});
|
|
64
77
|
}
|
|
@@ -67,8 +80,9 @@ exports.getSourceMapDevTool = getSourceMapDevTool;
|
|
|
67
80
|
* Returns an ES version file suffix to differentiate between various builds.
|
|
68
81
|
*/
|
|
69
82
|
function getEsVersionForFileName(scriptTargetOverride, esVersionInFileName = false) {
|
|
70
|
-
return scriptTargetOverride && esVersionInFileName
|
|
71
|
-
'-' + typescript_1.ScriptTarget[scriptTargetOverride].toLowerCase()
|
|
83
|
+
return scriptTargetOverride && esVersionInFileName
|
|
84
|
+
? '-' + typescript_1.ScriptTarget[scriptTargetOverride].toLowerCase()
|
|
85
|
+
: '';
|
|
72
86
|
}
|
|
73
87
|
exports.getEsVersionForFileName = getEsVersionForFileName;
|
|
74
88
|
function isPolyfillsEntry(name) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Compiler } from 'webpack';
|
|
2
|
+
import { CrossOriginValue } from '../utilities/index-file/augment-index-html';
|
|
2
3
|
import { IndexHtmlTransform } from '../utilities/index-file/write-index-html';
|
|
3
4
|
export interface IndexHtmlWebpackPluginOptions {
|
|
4
5
|
input: string;
|
|
@@ -8,7 +9,9 @@ export interface IndexHtmlWebpackPluginOptions {
|
|
|
8
9
|
deployUrl?: string;
|
|
9
10
|
sri: boolean;
|
|
10
11
|
noModuleEntrypoints: string[];
|
|
12
|
+
moduleEntrypoints: string[];
|
|
11
13
|
postTransform?: IndexHtmlTransform;
|
|
14
|
+
crossOrigin?: CrossOriginValue;
|
|
12
15
|
}
|
|
13
16
|
export declare class IndexHtmlWebpackPlugin {
|
|
14
17
|
private _options;
|
|
@@ -29,6 +29,7 @@ class IndexHtmlWebpackPlugin {
|
|
|
29
29
|
output: 'index.html',
|
|
30
30
|
entrypoints: ['polyfills', 'main'],
|
|
31
31
|
noModuleEntrypoints: [],
|
|
32
|
+
moduleEntrypoints: [],
|
|
32
33
|
sri: false,
|
|
33
34
|
...options,
|
|
34
35
|
};
|
|
@@ -37,14 +38,13 @@ class IndexHtmlWebpackPlugin {
|
|
|
37
38
|
compiler.hooks.emit.tapPromise('index-html-webpack-plugin', async (compilation) => {
|
|
38
39
|
// Get input html file
|
|
39
40
|
const inputContent = await readFile(this._options.input, compilation);
|
|
40
|
-
compilation
|
|
41
|
-
.fileDependencies.add(this._options.input);
|
|
41
|
+
compilation.fileDependencies.add(this._options.input);
|
|
42
42
|
// Get all files for selected entrypoints
|
|
43
43
|
const files = [];
|
|
44
44
|
const noModuleFiles = [];
|
|
45
|
+
const moduleFiles = [];
|
|
45
46
|
for (const [entryName, entrypoint] of compilation.entrypoints) {
|
|
46
|
-
const entryFiles = (entrypoint && entrypoint.getFiles() || [])
|
|
47
|
-
.map((f) => ({
|
|
47
|
+
const entryFiles = ((entrypoint && entrypoint.getFiles()) || []).map((f) => ({
|
|
48
48
|
name: entryName,
|
|
49
49
|
file: f,
|
|
50
50
|
extension: path.extname(f),
|
|
@@ -52,6 +52,9 @@ class IndexHtmlWebpackPlugin {
|
|
|
52
52
|
if (this._options.noModuleEntrypoints.includes(entryName)) {
|
|
53
53
|
noModuleFiles.push(...entryFiles);
|
|
54
54
|
}
|
|
55
|
+
else if (this._options.moduleEntrypoints.includes(entryName)) {
|
|
56
|
+
moduleFiles.push(...entryFiles);
|
|
57
|
+
}
|
|
55
58
|
else {
|
|
56
59
|
files.push(...entryFiles);
|
|
57
60
|
}
|
|
@@ -63,9 +66,11 @@ class IndexHtmlWebpackPlugin {
|
|
|
63
66
|
baseHref: this._options.baseHref,
|
|
64
67
|
deployUrl: this._options.deployUrl,
|
|
65
68
|
sri: this._options.sri,
|
|
69
|
+
crossOrigin: this._options.crossOrigin,
|
|
66
70
|
files,
|
|
67
71
|
noModuleFiles,
|
|
68
72
|
loadOutputFile,
|
|
73
|
+
moduleFiles,
|
|
69
74
|
entrypoints: this._options.entrypoints,
|
|
70
75
|
});
|
|
71
76
|
if (this._options.postTransform) {
|
|
@@ -125,7 +125,6 @@ const init = (config, emitter, customFileHandlers) => {
|
|
|
125
125
|
// Files need to be served from a custom path for Karma.
|
|
126
126
|
webpackConfig.output.path = '/_karma_webpack_/';
|
|
127
127
|
webpackConfig.output.publicPath = '/_karma_webpack_/';
|
|
128
|
-
webpackConfig.output.devtoolModuleFilenameTemplate = '[namespace]/[resource-path]?[loaders]';
|
|
129
128
|
let compiler;
|
|
130
129
|
try {
|
|
131
130
|
compiler = webpack(webpackConfig);
|
|
@@ -0,0 +1,28 @@
|
|
|
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 { logging } from '@angular-devkit/core';
|
|
9
|
+
import { loader } from 'webpack';
|
|
10
|
+
export interface SingleTestTransformLoaderOptions {
|
|
11
|
+
files: string[];
|
|
12
|
+
logger: logging.Logger;
|
|
13
|
+
}
|
|
14
|
+
export declare const SingleTestTransformLoader: string;
|
|
15
|
+
/**
|
|
16
|
+
* This loader transforms the default test file to only run tests
|
|
17
|
+
* for some specs instead of all specs.
|
|
18
|
+
* It works by replacing the known content of the auto-generated test file:
|
|
19
|
+
* const context = require.context('./', true, /\.spec\.ts$/);
|
|
20
|
+
* context.keys().map(context);
|
|
21
|
+
* with:
|
|
22
|
+
* const context = { keys: () => ({ map: (_a) => { } }) };
|
|
23
|
+
* context.keys().map(context);
|
|
24
|
+
* So that it does nothing.
|
|
25
|
+
* Then it adds import statements for each file in the files options
|
|
26
|
+
* array to import them directly, and thus run the tests there.
|
|
27
|
+
*/
|
|
28
|
+
export default function loader(this: loader.LoaderContext, source: string): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const loader_utils_1 = require("loader-utils");
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
exports.SingleTestTransformLoader = require.resolve(path_1.join(__dirname, 'single-test-transform'));
|
|
6
|
+
/**
|
|
7
|
+
* This loader transforms the default test file to only run tests
|
|
8
|
+
* for some specs instead of all specs.
|
|
9
|
+
* It works by replacing the known content of the auto-generated test file:
|
|
10
|
+
* const context = require.context('./', true, /\.spec\.ts$/);
|
|
11
|
+
* context.keys().map(context);
|
|
12
|
+
* with:
|
|
13
|
+
* const context = { keys: () => ({ map: (_a) => { } }) };
|
|
14
|
+
* context.keys().map(context);
|
|
15
|
+
* So that it does nothing.
|
|
16
|
+
* Then it adds import statements for each file in the files options
|
|
17
|
+
* array to import them directly, and thus run the tests there.
|
|
18
|
+
*/
|
|
19
|
+
function loader(source) {
|
|
20
|
+
const options = loader_utils_1.getOptions(this);
|
|
21
|
+
const lineSeparator = process.platform === 'win32' ? '\r\n' : '\n';
|
|
22
|
+
const targettedImports = options.files
|
|
23
|
+
.map(path => `require('./${path.replace('.' + path_1.extname(path), '')}');`)
|
|
24
|
+
.join(lineSeparator);
|
|
25
|
+
// TODO: maybe a documented 'marker/comment' inside test.ts would be nicer?
|
|
26
|
+
const regex = /require\.context\(.*/;
|
|
27
|
+
// signal the user that expected content is not present
|
|
28
|
+
if (!regex.test(source)) {
|
|
29
|
+
const message = [
|
|
30
|
+
`The 'include' option requires that the 'main' file for tests include the line below:`,
|
|
31
|
+
`const context = require.context('./', true, /\.spec\.ts$/);`,
|
|
32
|
+
`Arguments passed to require.context are not strict and can be changed`,
|
|
33
|
+
];
|
|
34
|
+
options.logger.error(message.join(lineSeparator));
|
|
35
|
+
}
|
|
36
|
+
const mockedRequireContext = '{ keys: () => ({ map: (_a) => { } }) };' + lineSeparator;
|
|
37
|
+
source = source.replace(regex, mockedRequireContext + targettedImports);
|
|
38
|
+
return source;
|
|
39
|
+
}
|
|
40
|
+
exports.default = loader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function findTests(patterns: string[], cwd: string, workspaceRoot: string): string[];
|