@angular-devkit/build-angular 12.1.0-next.3 → 12.1.0
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 +40 -39
- package/src/app-shell/index.js +28 -8
- package/src/babel/plugins/adjust-static-class-members.d.ts +25 -0
- package/src/babel/plugins/adjust-static-class-members.js +251 -0
- package/src/babel/plugins/adjust-typescript-enums.d.ts +21 -0
- package/src/babel/plugins/adjust-typescript-enums.js +123 -0
- package/src/babel/plugins/elide-angular-metadata.d.ts +21 -0
- package/src/babel/plugins/elide-angular-metadata.js +68 -0
- package/src/babel/plugins/pure-toplevel-functions.d.ts +14 -0
- package/src/babel/plugins/pure-toplevel-functions.js +86 -0
- package/src/babel/presets/application.d.ts +1 -0
- package/src/babel/presets/application.js +23 -3
- package/src/babel/webpack-loader.js +39 -1
- package/src/browser/index.d.ts +1 -4
- package/src/browser/index.js +26 -36
- package/src/browser/schema.d.ts +1 -1
- package/src/browser/schema.json +1 -1
- package/src/dev-server/index.d.ts +1 -1
- package/src/dev-server/index.js +68 -47
- package/src/dev-server/tests/execute-fetch.js +4 -1
- package/src/extract-i18n/empty-loader.d.ts +8 -0
- package/src/extract-i18n/empty-loader.js +13 -0
- package/src/extract-i18n/index.d.ts +1 -1
- package/src/extract-i18n/index.js +46 -18
- package/src/extract-i18n/ivy-extract-loader.js +20 -1
- package/src/karma/find-tests.js +20 -1
- package/src/karma/index.js +21 -1
- package/src/karma/schema.d.ts +1 -1
- package/src/karma/schema.json +1 -1
- package/src/karma/tests/setup.d.ts +18 -0
- package/src/karma/tests/setup.js +29 -0
- package/src/ng-packagr/index.js +21 -2
- package/src/protractor/index.js +21 -2
- package/src/sass/sass-service.d.ts +0 -3
- package/src/sass/sass-service.js +8 -9
- package/src/sass/worker.js +4 -2
- package/src/server/index.d.ts +1 -1
- package/src/server/index.js +20 -1
- package/src/server/schema.d.ts +1 -1
- package/src/server/schema.json +1 -1
- package/src/tslint/index.js +22 -3
- package/src/typings.d.ts +6 -0
- package/src/utils/action-cache.js +21 -2
- package/src/utils/action-executor.js +21 -2
- package/src/utils/build-browser-features.js +25 -3
- package/src/utils/cache-path.js +5 -2
- package/src/utils/check-port.js +20 -1
- package/src/utils/color.js +20 -1
- package/src/utils/copy-assets.js +26 -4
- package/src/utils/copy-file.js +20 -1
- package/src/utils/delete-output-dir.js +2 -2
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +26 -2
- package/src/utils/find-up.js +20 -1
- package/src/utils/i18n-inlining.js +21 -2
- package/src/utils/i18n-options.js +23 -5
- package/src/utils/index-file/html-rewriting-stream.js +20 -1
- package/src/utils/index-file/index-html-generator.js +20 -1
- package/src/utils/index-file/inline-critical-css.js +20 -1
- package/src/utils/index-file/inline-fonts.js +27 -5
- package/src/utils/is-directory.js +20 -1
- package/src/utils/load-translations.js +26 -7
- package/src/utils/process-bundle.js +34 -12
- package/src/utils/read-tsconfig.js +20 -1
- package/src/utils/service-worker.js +21 -2
- package/src/utils/spinner.d.ts +2 -0
- package/src/utils/spinner.js +18 -2
- package/src/utils/webpack-browser-config.js +21 -2
- package/src/webpack/configs/analytics.d.ts +11 -0
- package/src/webpack/configs/analytics.js +29 -0
- package/src/webpack/configs/common.js +96 -45
- package/src/webpack/configs/dev-server.js +20 -1
- package/src/webpack/configs/index.d.ts +1 -0
- package/src/webpack/configs/index.js +1 -0
- package/src/webpack/configs/server.js +8 -0
- package/src/webpack/configs/stats.d.ts +6 -14
- package/src/webpack/configs/stats.js +5 -8
- package/src/webpack/configs/styles.js +28 -2
- package/src/webpack/configs/test.js +32 -3
- package/src/webpack/configs/typescript.d.ts +2 -9
- package/src/webpack/configs/typescript.js +16 -14
- package/src/webpack/plugins/any-component-style-budget-checker.js +20 -1
- package/src/webpack/plugins/builder-watch-plugin.d.ts +0 -2
- package/src/webpack/plugins/builder-watch-plugin.js +2 -7
- package/src/webpack/plugins/index.js +4 -1
- package/src/webpack/plugins/karma/karma-context.html +1 -1
- package/src/webpack/plugins/karma/karma-debug.html +1 -1
- package/src/webpack/plugins/karma/karma.js +27 -5
- package/src/webpack/plugins/postcss-cli-resources.js +21 -2
- package/src/webpack/plugins/scripts-webpack-plugin.js +20 -1
- package/src/webpack/utils/async-chunks.js +9 -5
- package/src/webpack/utils/helpers.js +20 -1
- package/src/webpack/utils/stats.d.ts +2 -3
- package/src/webpack/utils/stats.js +50 -15
- package/src/extract-i18n/empty-export-default.js +0 -1
package/package.json
CHANGED
|
@@ -1,89 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "12.1.0
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "Angular Webpack Build Facade",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
7
7
|
"builders": "builders.json",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@angular-devkit/architect": "0.1201.0
|
|
10
|
-
"@angular-devkit/build-optimizer": "0.1201.0
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1201.0
|
|
12
|
-
"@angular-devkit/core": "12.1.0
|
|
13
|
-
"@babel/core": "7.14.
|
|
14
|
-
"@babel/generator": "7.14.
|
|
15
|
-
"@babel/
|
|
16
|
-
"@babel/plugin-transform-
|
|
17
|
-
"@babel/
|
|
18
|
-
"@babel/
|
|
19
|
-
"@babel/
|
|
9
|
+
"@angular-devkit/architect": "0.1201.0",
|
|
10
|
+
"@angular-devkit/build-optimizer": "0.1201.0",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1201.0",
|
|
12
|
+
"@angular-devkit/core": "12.1.0",
|
|
13
|
+
"@babel/core": "7.14.6",
|
|
14
|
+
"@babel/generator": "7.14.5",
|
|
15
|
+
"@babel/helper-annotate-as-pure": "7.14.5",
|
|
16
|
+
"@babel/plugin-transform-async-to-generator": "7.14.5",
|
|
17
|
+
"@babel/plugin-transform-runtime": "7.14.5",
|
|
18
|
+
"@babel/preset-env": "7.14.7",
|
|
19
|
+
"@babel/runtime": "7.14.6",
|
|
20
|
+
"@babel/template": "7.14.5",
|
|
20
21
|
"@discoveryjs/json-ext": "0.5.3",
|
|
21
22
|
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
|
|
22
|
-
"@ngtools/webpack": "12.1.0
|
|
23
|
+
"@ngtools/webpack": "12.1.0",
|
|
23
24
|
"ansi-colors": "4.1.1",
|
|
24
25
|
"babel-loader": "8.2.2",
|
|
25
26
|
"browserslist": "^4.9.1",
|
|
26
|
-
"cacache": "15.0
|
|
27
|
+
"cacache": "15.2.0",
|
|
27
28
|
"caniuse-lite": "^1.0.30001032",
|
|
28
29
|
"circular-dependency-plugin": "5.2.2",
|
|
29
30
|
"copy-webpack-plugin": "9.0.0",
|
|
30
|
-
"core-js": "3.
|
|
31
|
+
"core-js": "3.15.1",
|
|
31
32
|
"critters": "0.0.10",
|
|
32
|
-
"css-loader": "5.2.
|
|
33
|
-
"css-minimizer-webpack-plugin": "3.0.
|
|
33
|
+
"css-loader": "5.2.6",
|
|
34
|
+
"css-minimizer-webpack-plugin": "3.0.1",
|
|
34
35
|
"find-cache-dir": "3.3.1",
|
|
35
36
|
"glob": "7.1.7",
|
|
36
37
|
"https-proxy-agent": "5.0.0",
|
|
37
|
-
"inquirer": "8.
|
|
38
|
-
"jest-worker": "27.0.
|
|
38
|
+
"inquirer": "8.1.1",
|
|
39
|
+
"jest-worker": "27.0.2",
|
|
39
40
|
"karma-source-map-support": "1.4.0",
|
|
40
41
|
"less": "4.1.1",
|
|
41
|
-
"less-loader": "
|
|
42
|
-
"license-webpack-plugin": "2.3.
|
|
42
|
+
"less-loader": "10.0.0",
|
|
43
|
+
"license-webpack-plugin": "2.3.19",
|
|
43
44
|
"loader-utils": "2.0.0",
|
|
44
45
|
"mini-css-extract-plugin": "1.6.0",
|
|
45
46
|
"minimatch": "3.0.4",
|
|
46
|
-
"open": "8.
|
|
47
|
-
"ora": "5.4.
|
|
47
|
+
"open": "8.2.1",
|
|
48
|
+
"ora": "5.4.1",
|
|
48
49
|
"parse5-html-rewriting-stream": "6.0.1",
|
|
49
|
-
"postcss": "8.
|
|
50
|
+
"postcss": "8.3.5",
|
|
50
51
|
"postcss-import": "14.0.2",
|
|
51
|
-
"postcss-loader": "
|
|
52
|
+
"postcss-loader": "6.1.0",
|
|
52
53
|
"postcss-preset-env": "6.7.0",
|
|
53
54
|
"raw-loader": "4.0.2",
|
|
54
55
|
"regenerator-runtime": "0.13.7",
|
|
55
56
|
"resolve-url-loader": "4.0.0",
|
|
56
|
-
"rimraf": "3.0.2",
|
|
57
57
|
"rxjs": "6.6.7",
|
|
58
|
-
"sass": "1.
|
|
59
|
-
"sass-loader": "
|
|
58
|
+
"sass": "1.35.1",
|
|
59
|
+
"sass-loader": "12.1.0",
|
|
60
60
|
"semver": "7.3.5",
|
|
61
61
|
"source-map": "0.7.3",
|
|
62
62
|
"source-map-loader": "3.0.0",
|
|
63
63
|
"source-map-support": "0.5.19",
|
|
64
64
|
"style-loader": "2.0.0",
|
|
65
65
|
"stylus": "0.54.8",
|
|
66
|
-
"stylus-loader": "6.
|
|
66
|
+
"stylus-loader": "6.1.0",
|
|
67
67
|
"terser": "5.7.0",
|
|
68
|
-
"terser-webpack-plugin": "5.1.
|
|
68
|
+
"terser-webpack-plugin": "5.1.3",
|
|
69
69
|
"text-table": "0.2.0",
|
|
70
70
|
"tree-kill": "1.2.2",
|
|
71
|
-
"
|
|
72
|
-
"webpack
|
|
71
|
+
"tslib": "2.3.0",
|
|
72
|
+
"webpack": "5.40.0",
|
|
73
|
+
"webpack-dev-middleware": "5.0.0",
|
|
73
74
|
"webpack-dev-server": "3.11.2",
|
|
74
|
-
"webpack-merge": "5.
|
|
75
|
+
"webpack-merge": "5.8.0",
|
|
75
76
|
"webpack-subresource-integrity": "1.5.2"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
|
-
"@angular/compiler-cli": "^12.0.0-next",
|
|
79
|
-
"@angular/localize": "^12.0.0-next",
|
|
80
|
-
"@angular/service-worker": "^12.0.0-next",
|
|
79
|
+
"@angular/compiler-cli": "^12.0.0 || ^12.1.0-next",
|
|
80
|
+
"@angular/localize": "^12.0.0 || ^12.1.0-next",
|
|
81
|
+
"@angular/service-worker": "^12.0.0 || ^12.1.0-next",
|
|
81
82
|
"karma": "^6.3.0",
|
|
82
|
-
"ng-packagr": "^12.0.0-next",
|
|
83
|
+
"ng-packagr": "^12.0.0 || ^12.1.0-next",
|
|
83
84
|
"protractor": "^7.0.0",
|
|
84
85
|
"tailwindcss": "^2.0.0",
|
|
85
86
|
"tslint": "^6.1.0",
|
|
86
|
-
"typescript": "~4.2.3"
|
|
87
|
+
"typescript": "~4.2.3 || ~4.3.2"
|
|
87
88
|
},
|
|
88
89
|
"peerDependenciesMeta": {
|
|
89
90
|
"@angular/localize": {
|
|
@@ -120,7 +121,7 @@
|
|
|
120
121
|
"url": "https://github.com/angular/angular-cli.git"
|
|
121
122
|
},
|
|
122
123
|
"engines": {
|
|
123
|
-
"node": "^12.14.1 ||
|
|
124
|
+
"node": "^12.14.1 || >=14.0.0",
|
|
124
125
|
"npm": "^6.11.0 || ^7.5.6",
|
|
125
126
|
"yarn": ">= 1.13.0"
|
|
126
127
|
},
|
package/src/app-shell/index.js
CHANGED
|
@@ -6,11 +6,30 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
9
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
29
|
const architect_1 = require("@angular-devkit/architect");
|
|
11
30
|
const core_1 = require("@angular-devkit/core");
|
|
12
|
-
const fs = require("fs");
|
|
13
|
-
const path = require("path");
|
|
31
|
+
const fs = __importStar(require("fs"));
|
|
32
|
+
const path = __importStar(require("path"));
|
|
14
33
|
const utils_1 = require("../utils");
|
|
15
34
|
const inline_critical_css_1 = require("../utils/index-file/inline-critical-css");
|
|
16
35
|
const service_worker_1 = require("../utils/service-worker");
|
|
@@ -24,7 +43,7 @@ async function _renderUniversal(options, context, browserResult, serverResult, s
|
|
|
24
43
|
// Initialize zone.js
|
|
25
44
|
const root = context.workspaceRoot;
|
|
26
45
|
const zonePackage = require.resolve('zone.js', { paths: [root] });
|
|
27
|
-
await Promise.resolve().then(() => require(zonePackage));
|
|
46
|
+
await Promise.resolve().then(() => __importStar(require(zonePackage)));
|
|
28
47
|
const projectName = context.target && context.target.project;
|
|
29
48
|
if (!projectName) {
|
|
30
49
|
throw new Error('The builder requires a target.');
|
|
@@ -43,7 +62,7 @@ async function _renderUniversal(options, context, browserResult, serverResult, s
|
|
|
43
62
|
const browserIndexOutputPath = path.join(outputPath, 'index.html');
|
|
44
63
|
const indexHtml = await fs.promises.readFile(browserIndexOutputPath, 'utf8');
|
|
45
64
|
const serverBundlePath = await _getServerModuleBundlePath(options, context, serverResult, localeDirectory);
|
|
46
|
-
const { AppServerModule, renderModule } = await Promise.resolve().then(() => require(serverBundlePath));
|
|
65
|
+
const { AppServerModule, renderModule } = await Promise.resolve().then(() => __importStar(require(serverBundlePath)));
|
|
47
66
|
const renderModuleFn = renderModule;
|
|
48
67
|
if (!(renderModuleFn && AppServerModule)) {
|
|
49
68
|
throw new Error(`renderModule method and/or AppServerModule were not exported from: ${serverBundlePath}.`);
|
|
@@ -111,9 +130,10 @@ async function _appShellBuilder(options, context) {
|
|
|
111
130
|
});
|
|
112
131
|
let spinner;
|
|
113
132
|
try {
|
|
133
|
+
// Using `.result` instead of `.output` causes Webpack FS cache not to be created.
|
|
114
134
|
const [browserResult, serverResult] = await Promise.all([
|
|
115
|
-
browserTargetRun.
|
|
116
|
-
serverTargetRun.
|
|
135
|
+
browserTargetRun.output.toPromise(),
|
|
136
|
+
serverTargetRun.output.toPromise(),
|
|
117
137
|
]);
|
|
118
138
|
if (browserResult.success === false || browserResult.baseOutputPath === undefined) {
|
|
119
139
|
return browserResult;
|
|
@@ -132,8 +152,8 @@ async function _appShellBuilder(options, context) {
|
|
|
132
152
|
return { success: false, error: err.message };
|
|
133
153
|
}
|
|
134
154
|
finally {
|
|
135
|
-
//
|
|
136
|
-
|
|
155
|
+
// workaround for [tsetse] All Promises in async functions must either be awaited or used in an expression.
|
|
156
|
+
const _ = Promise.all([browserTargetRun.stop(), serverTargetRun.stop()]);
|
|
137
157
|
}
|
|
138
158
|
}
|
|
139
159
|
exports.default = architect_1.createBuilder(_appShellBuilder);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC 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 { PluginObj } from '@babel/core';
|
|
9
|
+
/**
|
|
10
|
+
* Provides one or more keywords that if found within the content of a source file indicate
|
|
11
|
+
* that this plugin should be used with a source file.
|
|
12
|
+
*
|
|
13
|
+
* @returns An a string iterable containing one or more keywords.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getKeywords(): Iterable<string>;
|
|
16
|
+
/**
|
|
17
|
+
* A babel plugin factory function for adjusting classes; primarily with Angular metadata.
|
|
18
|
+
* The adjustments include wrapping classes with known safe or no side effects with pure
|
|
19
|
+
* annotations to support dead code removal of unused classes. Angular compiler generated
|
|
20
|
+
* metadata static fields not required in AOT mode are also elided to better support bundler-
|
|
21
|
+
* level treeshaking.
|
|
22
|
+
*
|
|
23
|
+
* @returns A babel plugin object instance.
|
|
24
|
+
*/
|
|
25
|
+
export default function (): PluginObj;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC 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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getKeywords = void 0;
|
|
14
|
+
const core_1 = require("@babel/core");
|
|
15
|
+
const helper_annotate_as_pure_1 = __importDefault(require("@babel/helper-annotate-as-pure"));
|
|
16
|
+
/**
|
|
17
|
+
* The name of the Typescript decorator helper function created by the TypeScript compiler.
|
|
18
|
+
*/
|
|
19
|
+
const TSLIB_DECORATE_HELPER_NAME = '__decorate';
|
|
20
|
+
/**
|
|
21
|
+
* The set of Angular static fields that should always be wrapped.
|
|
22
|
+
* These fields may appear to have side effects but are safe to remove if the associated class
|
|
23
|
+
* is otherwise unused within the output.
|
|
24
|
+
*/
|
|
25
|
+
const angularStaticsToWrap = new Set([
|
|
26
|
+
'ɵcmp',
|
|
27
|
+
'ɵdir',
|
|
28
|
+
'ɵfac',
|
|
29
|
+
'ɵinj',
|
|
30
|
+
'ɵmod',
|
|
31
|
+
'ɵpipe',
|
|
32
|
+
'ɵprov',
|
|
33
|
+
'INJECTOR_KEY',
|
|
34
|
+
]);
|
|
35
|
+
/**
|
|
36
|
+
* An object map of static fields and related value checks for discovery of Angular generated
|
|
37
|
+
* JIT related static fields.
|
|
38
|
+
*/
|
|
39
|
+
const angularStaticsToElide = {
|
|
40
|
+
'ctorParameters'(path) {
|
|
41
|
+
return path.isFunctionExpression() || path.isArrowFunctionExpression();
|
|
42
|
+
},
|
|
43
|
+
'decorators'(path) {
|
|
44
|
+
return path.isArrayExpression();
|
|
45
|
+
},
|
|
46
|
+
'propDecorators'(path) {
|
|
47
|
+
return path.isObjectExpression();
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Provides one or more keywords that if found within the content of a source file indicate
|
|
52
|
+
* that this plugin should be used with a source file.
|
|
53
|
+
*
|
|
54
|
+
* @returns An a string iterable containing one or more keywords.
|
|
55
|
+
*/
|
|
56
|
+
function getKeywords() {
|
|
57
|
+
return ['class'];
|
|
58
|
+
}
|
|
59
|
+
exports.getKeywords = getKeywords;
|
|
60
|
+
/**
|
|
61
|
+
* Analyze the sibling nodes of a class to determine if any downlevel elements should be
|
|
62
|
+
* wrapped in a pure annotated IIFE. Also determines if any elements have potential side
|
|
63
|
+
* effects.
|
|
64
|
+
*
|
|
65
|
+
* @param origin The starting NodePath location for analyzing siblings.
|
|
66
|
+
* @param classIdentifier The identifier node that represents the name of the class.
|
|
67
|
+
* @param allowWrappingDecorators Whether to allow decorators to be wrapped.
|
|
68
|
+
* @returns An object containing the results of the analysis.
|
|
69
|
+
*/
|
|
70
|
+
function analyzeClassSiblings(origin, classIdentifier, allowWrappingDecorators) {
|
|
71
|
+
var _a;
|
|
72
|
+
const wrapStatementPaths = [];
|
|
73
|
+
let hasPotentialSideEffects = false;
|
|
74
|
+
for (let i = 1;; ++i) {
|
|
75
|
+
const nextStatement = origin.getSibling(+origin.key + i);
|
|
76
|
+
if (!nextStatement.isExpressionStatement()) {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
// Valid sibling statements for class declarations are only assignment expressions
|
|
80
|
+
// and TypeScript decorator helper call expressions
|
|
81
|
+
const nextExpression = nextStatement.get('expression');
|
|
82
|
+
if (nextExpression.isCallExpression()) {
|
|
83
|
+
if (!core_1.types.isIdentifier(nextExpression.node.callee) ||
|
|
84
|
+
nextExpression.node.callee.name !== TSLIB_DECORATE_HELPER_NAME) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
if (allowWrappingDecorators) {
|
|
88
|
+
wrapStatementPaths.push(nextStatement);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Statement cannot be safely wrapped which makes wrapping the class unneeded.
|
|
92
|
+
// The statement will prevent even a wrapped class from being optimized away.
|
|
93
|
+
hasPotentialSideEffects = true;
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
else if (!nextExpression.isAssignmentExpression()) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
// Valid assignment expressions should be member access expressions using the class
|
|
101
|
+
// name as the object and an identifier as the property for static fields or only
|
|
102
|
+
// the class name for decorators.
|
|
103
|
+
const left = nextExpression.get('left');
|
|
104
|
+
if (left.isIdentifier()) {
|
|
105
|
+
if (!left.scope.bindingIdentifierEquals(left.node.name, classIdentifier) ||
|
|
106
|
+
!core_1.types.isCallExpression(nextExpression.node.right) ||
|
|
107
|
+
!core_1.types.isIdentifier(nextExpression.node.right.callee) ||
|
|
108
|
+
nextExpression.node.right.callee.name !== TSLIB_DECORATE_HELPER_NAME) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
if (allowWrappingDecorators) {
|
|
112
|
+
wrapStatementPaths.push(nextStatement);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Statement cannot be safely wrapped which makes wrapping the class unneeded.
|
|
116
|
+
// The statement will prevent even a wrapped class from being optimized away.
|
|
117
|
+
hasPotentialSideEffects = true;
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
else if (!left.isMemberExpression() ||
|
|
122
|
+
!core_1.types.isIdentifier(left.node.object) ||
|
|
123
|
+
!left.scope.bindingIdentifierEquals(left.node.object.name, classIdentifier) ||
|
|
124
|
+
!core_1.types.isIdentifier(left.node.property)) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
const propertyName = left.node.property.name;
|
|
128
|
+
const assignmentValue = nextExpression.get('right');
|
|
129
|
+
if ((_a = angularStaticsToElide[propertyName]) === null || _a === void 0 ? void 0 : _a.call(angularStaticsToElide, assignmentValue)) {
|
|
130
|
+
nextStatement.remove();
|
|
131
|
+
--i;
|
|
132
|
+
}
|
|
133
|
+
else if (angularStaticsToWrap.has(propertyName) || assignmentValue.isPure()) {
|
|
134
|
+
wrapStatementPaths.push(nextStatement);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// Statement cannot be safely wrapped which makes wrapping the class unneeded.
|
|
138
|
+
// The statement will prevent even a wrapped class from being optimized away.
|
|
139
|
+
hasPotentialSideEffects = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { hasPotentialSideEffects, wrapStatementPaths };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The set of classed already visited and analyzed during the plugin's execution.
|
|
146
|
+
* This is used to prevent adjusted classes from being repeatedly analyzed which can lead
|
|
147
|
+
* to an infinite loop.
|
|
148
|
+
*/
|
|
149
|
+
const visitedClasses = new WeakSet();
|
|
150
|
+
/**
|
|
151
|
+
* A babel plugin factory function for adjusting classes; primarily with Angular metadata.
|
|
152
|
+
* The adjustments include wrapping classes with known safe or no side effects with pure
|
|
153
|
+
* annotations to support dead code removal of unused classes. Angular compiler generated
|
|
154
|
+
* metadata static fields not required in AOT mode are also elided to better support bundler-
|
|
155
|
+
* level treeshaking.
|
|
156
|
+
*
|
|
157
|
+
* @returns A babel plugin object instance.
|
|
158
|
+
*/
|
|
159
|
+
function default_1() {
|
|
160
|
+
return {
|
|
161
|
+
visitor: {
|
|
162
|
+
ClassDeclaration(path, state) {
|
|
163
|
+
const { node: classNode, parentPath } = path;
|
|
164
|
+
const { wrapDecorators } = state.opts;
|
|
165
|
+
if (visitedClasses.has(classNode)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Analyze sibling statements for elements of the class that were downleveled
|
|
169
|
+
const hasExport = parentPath.isExportNamedDeclaration() || parentPath.isExportDefaultDeclaration();
|
|
170
|
+
const origin = hasExport ? parentPath : path;
|
|
171
|
+
const { wrapStatementPaths, hasPotentialSideEffects } = analyzeClassSiblings(origin, classNode.id, wrapDecorators);
|
|
172
|
+
visitedClasses.add(classNode);
|
|
173
|
+
if (hasPotentialSideEffects || wrapStatementPaths.length === 0) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const wrapStatementNodes = [];
|
|
177
|
+
for (const statementPath of wrapStatementPaths) {
|
|
178
|
+
wrapStatementNodes.push(statementPath.node);
|
|
179
|
+
statementPath.remove();
|
|
180
|
+
}
|
|
181
|
+
// Wrap class and safe static assignments in a pure annotated IIFE
|
|
182
|
+
const container = core_1.types.arrowFunctionExpression([], core_1.types.blockStatement([
|
|
183
|
+
classNode,
|
|
184
|
+
...wrapStatementNodes,
|
|
185
|
+
core_1.types.returnStatement(core_1.types.cloneNode(classNode.id)),
|
|
186
|
+
]));
|
|
187
|
+
const replacementInitializer = core_1.types.callExpression(core_1.types.parenthesizedExpression(container), []);
|
|
188
|
+
helper_annotate_as_pure_1.default(replacementInitializer);
|
|
189
|
+
// Replace class with IIFE wrapped class
|
|
190
|
+
const declaration = core_1.types.variableDeclaration('let', [
|
|
191
|
+
core_1.types.variableDeclarator(core_1.types.cloneNode(classNode.id), replacementInitializer),
|
|
192
|
+
]);
|
|
193
|
+
if (parentPath.isExportDefaultDeclaration()) {
|
|
194
|
+
// When converted to a variable declaration, the default export must be moved
|
|
195
|
+
// to a subsequent statement to prevent a JavaScript syntax error.
|
|
196
|
+
parentPath.replaceWithMultiple([
|
|
197
|
+
declaration,
|
|
198
|
+
core_1.types.exportNamedDeclaration(undefined, [
|
|
199
|
+
core_1.types.exportSpecifier(core_1.types.cloneNode(classNode.id), core_1.types.identifier('default')),
|
|
200
|
+
]),
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
path.replaceWith(declaration);
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
ClassExpression(path, state) {
|
|
208
|
+
const { node: classNode, parentPath } = path;
|
|
209
|
+
const { wrapDecorators } = state.opts;
|
|
210
|
+
// Class expressions are used by TypeScript to represent downlevel class/constructor decorators.
|
|
211
|
+
// If not wrapping decorators, they do not need to be processed.
|
|
212
|
+
if (!wrapDecorators || visitedClasses.has(classNode)) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (!classNode.id ||
|
|
216
|
+
!parentPath.isVariableDeclarator() ||
|
|
217
|
+
!core_1.types.isIdentifier(parentPath.node.id) ||
|
|
218
|
+
parentPath.node.id.name !== classNode.id.name) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const origin = parentPath.parentPath;
|
|
222
|
+
if (!origin.isVariableDeclaration() || origin.node.declarations.length !== 1) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const { wrapStatementPaths, hasPotentialSideEffects } = analyzeClassSiblings(origin, parentPath.node.id, wrapDecorators);
|
|
226
|
+
visitedClasses.add(classNode);
|
|
227
|
+
if (hasPotentialSideEffects || wrapStatementPaths.length === 0) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const wrapStatementNodes = [];
|
|
231
|
+
for (const statementPath of wrapStatementPaths) {
|
|
232
|
+
wrapStatementNodes.push(statementPath.node);
|
|
233
|
+
statementPath.remove();
|
|
234
|
+
}
|
|
235
|
+
// Wrap class and safe static assignments in a pure annotated IIFE
|
|
236
|
+
const container = core_1.types.arrowFunctionExpression([], core_1.types.blockStatement([
|
|
237
|
+
core_1.types.variableDeclaration('let', [
|
|
238
|
+
core_1.types.variableDeclarator(core_1.types.cloneNode(classNode.id), classNode),
|
|
239
|
+
]),
|
|
240
|
+
...wrapStatementNodes,
|
|
241
|
+
core_1.types.returnStatement(core_1.types.cloneNode(classNode.id)),
|
|
242
|
+
]));
|
|
243
|
+
const replacementInitializer = core_1.types.callExpression(core_1.types.parenthesizedExpression(container), []);
|
|
244
|
+
helper_annotate_as_pure_1.default(replacementInitializer);
|
|
245
|
+
// Add the wrapped class directly to the variable declaration
|
|
246
|
+
parentPath.get('init').replaceWith(replacementInitializer);
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
exports.default = default_1;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC 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 { PluginObj } from '@babel/core';
|
|
9
|
+
/**
|
|
10
|
+
* Provides one or more keywords that if found within the content of a source file indicate
|
|
11
|
+
* that this plugin should be used with a source file.
|
|
12
|
+
*
|
|
13
|
+
* @returns An a string iterable containing one or more keywords.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getKeywords(): Iterable<string>;
|
|
16
|
+
/**
|
|
17
|
+
* A babel plugin factory function for adjusting TypeScript emitted enums.
|
|
18
|
+
*
|
|
19
|
+
* @returns A babel plugin object instance.
|
|
20
|
+
*/
|
|
21
|
+
export default function (): PluginObj;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC 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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getKeywords = void 0;
|
|
14
|
+
const core_1 = require("@babel/core");
|
|
15
|
+
const helper_annotate_as_pure_1 = __importDefault(require("@babel/helper-annotate-as-pure"));
|
|
16
|
+
/**
|
|
17
|
+
* Provides one or more keywords that if found within the content of a source file indicate
|
|
18
|
+
* that this plugin should be used with a source file.
|
|
19
|
+
*
|
|
20
|
+
* @returns An a string iterable containing one or more keywords.
|
|
21
|
+
*/
|
|
22
|
+
function getKeywords() {
|
|
23
|
+
return ['var'];
|
|
24
|
+
}
|
|
25
|
+
exports.getKeywords = getKeywords;
|
|
26
|
+
/**
|
|
27
|
+
* A babel plugin factory function for adjusting TypeScript emitted enums.
|
|
28
|
+
*
|
|
29
|
+
* @returns A babel plugin object instance.
|
|
30
|
+
*/
|
|
31
|
+
function default_1() {
|
|
32
|
+
return {
|
|
33
|
+
visitor: {
|
|
34
|
+
VariableDeclaration(path, state) {
|
|
35
|
+
const { parentPath, node } = path;
|
|
36
|
+
const { loose } = state.opts;
|
|
37
|
+
if (node.kind !== 'var' || node.declarations.length !== 1) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const declaration = path.get('declarations')[0];
|
|
41
|
+
if (declaration.node.init) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const declarationId = declaration.node.id;
|
|
45
|
+
if (!core_1.types.isIdentifier(declarationId)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const hasExport = parentPath.isExportNamedDeclaration() || parentPath.isExportDefaultDeclaration();
|
|
49
|
+
const origin = hasExport ? parentPath : path;
|
|
50
|
+
const nextStatement = origin.getSibling(+origin.key + 1);
|
|
51
|
+
if (!nextStatement.isExpressionStatement()) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const nextExpression = nextStatement.get('expression');
|
|
55
|
+
if (!nextExpression.isCallExpression() || nextExpression.node.arguments.length !== 1) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const enumCallArgument = nextExpression.node.arguments[0];
|
|
59
|
+
if (!core_1.types.isLogicalExpression(enumCallArgument, { operator: '||' })) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Check if identifiers match var declaration
|
|
63
|
+
if (!core_1.types.isIdentifier(enumCallArgument.left) ||
|
|
64
|
+
!nextExpression.scope.bindingIdentifierEquals(enumCallArgument.left.name, declarationId)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const enumCallee = nextExpression.get('callee');
|
|
68
|
+
if (!enumCallee.isFunctionExpression() || enumCallee.node.params.length !== 1) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Loose mode rewrites the enum to a shorter but less TypeScript-like form
|
|
72
|
+
let enumAssignments;
|
|
73
|
+
if (loose) {
|
|
74
|
+
enumAssignments = [];
|
|
75
|
+
}
|
|
76
|
+
// Check if all enum member values are pure.
|
|
77
|
+
// If not, leave as-is due to potential side efects
|
|
78
|
+
let hasElements = false;
|
|
79
|
+
for (const enumStatement of enumCallee.get('body').get('body')) {
|
|
80
|
+
if (!enumStatement.isExpressionStatement()) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const enumValueAssignment = enumStatement.get('expression');
|
|
84
|
+
if (!enumValueAssignment.isAssignmentExpression() ||
|
|
85
|
+
!enumValueAssignment.get('right').isPure()) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
hasElements = true;
|
|
89
|
+
enumAssignments === null || enumAssignments === void 0 ? void 0 : enumAssignments.push(enumStatement.node);
|
|
90
|
+
}
|
|
91
|
+
// If there are no enum elements then there is nothing to wrap
|
|
92
|
+
if (!hasElements) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Remove existing enum initializer
|
|
96
|
+
const enumInitializer = nextExpression.node;
|
|
97
|
+
nextExpression.remove();
|
|
98
|
+
// Create IIFE block contents
|
|
99
|
+
let blockContents;
|
|
100
|
+
if (enumAssignments) {
|
|
101
|
+
// Loose mode
|
|
102
|
+
blockContents = [
|
|
103
|
+
core_1.types.expressionStatement(core_1.types.assignmentExpression('=', core_1.types.cloneNode(declarationId), core_1.types.logicalExpression('||', core_1.types.cloneNode(declarationId), core_1.types.objectExpression([])))),
|
|
104
|
+
...enumAssignments,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
blockContents = [core_1.types.expressionStatement(enumInitializer)];
|
|
109
|
+
}
|
|
110
|
+
// Wrap existing enum initializer in a pure annotated IIFE
|
|
111
|
+
const container = core_1.types.arrowFunctionExpression([], core_1.types.blockStatement([
|
|
112
|
+
...blockContents,
|
|
113
|
+
core_1.types.returnStatement(core_1.types.cloneNode(declarationId)),
|
|
114
|
+
]));
|
|
115
|
+
const replacementInitializer = core_1.types.callExpression(core_1.types.parenthesizedExpression(container), []);
|
|
116
|
+
helper_annotate_as_pure_1.default(replacementInitializer);
|
|
117
|
+
// Add the wrapped enum initializer directly to the variable declaration
|
|
118
|
+
declaration.get('init').replaceWith(replacementInitializer);
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
exports.default = default_1;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC 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 { PluginObj } from '@babel/core';
|
|
9
|
+
/**
|
|
10
|
+
* Provides one or more keywords that if found within the content of a source file indicate
|
|
11
|
+
* that this plugin should be used with a source file.
|
|
12
|
+
*
|
|
13
|
+
* @returns An a string iterable containing one or more keywords.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getKeywords(): Iterable<string>;
|
|
16
|
+
/**
|
|
17
|
+
* A babel plugin factory function for eliding the Angular class metadata function (`ɵsetClassMetadata`).
|
|
18
|
+
*
|
|
19
|
+
* @returns A babel plugin object instance.
|
|
20
|
+
*/
|
|
21
|
+
export default function (): PluginObj;
|