@angular-devkit/build-angular 12.2.5 → 12.2.9
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/esbuild-check.js +16 -0
- package/package.json +10 -7
- package/src/babel/plugins/adjust-typescript-enums.js +7 -1
- package/src/utils/color.js +25 -2
- package/src/webpack/configs/common.js +1 -1
- package/src/webpack/configs/styles.js +2 -1
- package/src/webpack/plugins/esbuild-executor.d.ts +46 -0
- package/src/webpack/plugins/esbuild-executor.js +126 -0
- package/src/webpack/plugins/javascript-optimizer-plugin.js +5 -0
- package/src/webpack/plugins/javascript-optimizer-worker.d.ts +42 -0
- package/src/webpack/plugins/javascript-optimizer-worker.js +70 -14
package/esbuild-check.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
|
|
9
|
+
// If the platform does not support the native variant of esbuild, this will crash.
|
|
10
|
+
// This script can then be spawned by the CLI to determine if native usage is supported.
|
|
11
|
+
require('esbuild')
|
|
12
|
+
.formatMessages([], { kind: 'error ' })
|
|
13
|
+
.then(
|
|
14
|
+
() => {},
|
|
15
|
+
() => {},
|
|
16
|
+
);
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "12.2.
|
|
3
|
+
"version": "12.2.9",
|
|
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
9
|
"@ampproject/remapping": "1.0.1",
|
|
10
|
-
"@angular-devkit/architect": "0.1202.
|
|
11
|
-
"@angular-devkit/build-optimizer": "0.1202.
|
|
12
|
-
"@angular-devkit/build-webpack": "0.1202.
|
|
13
|
-
"@angular-devkit/core": "12.2.
|
|
10
|
+
"@angular-devkit/architect": "0.1202.9",
|
|
11
|
+
"@angular-devkit/build-optimizer": "0.1202.9",
|
|
12
|
+
"@angular-devkit/build-webpack": "0.1202.9",
|
|
13
|
+
"@angular-devkit/core": "12.2.9",
|
|
14
14
|
"@babel/core": "7.14.8",
|
|
15
15
|
"@babel/generator": "7.14.8",
|
|
16
16
|
"@babel/helper-annotate-as-pure": "7.14.5",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@babel/template": "7.14.5",
|
|
23
23
|
"@discoveryjs/json-ext": "0.5.3",
|
|
24
24
|
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
|
|
25
|
-
"@ngtools/webpack": "12.2.
|
|
25
|
+
"@ngtools/webpack": "12.2.9",
|
|
26
26
|
"ansi-colors": "4.1.1",
|
|
27
27
|
"babel-loader": "8.2.2",
|
|
28
28
|
"browserslist": "^4.9.1",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"critters": "0.0.10",
|
|
35
35
|
"css-loader": "6.2.0",
|
|
36
36
|
"css-minimizer-webpack-plugin": "3.0.2",
|
|
37
|
-
"esbuild": "0.
|
|
37
|
+
"esbuild-wasm": "0.13.4",
|
|
38
38
|
"find-cache-dir": "3.3.1",
|
|
39
39
|
"glob": "7.1.7",
|
|
40
40
|
"https-proxy-agent": "5.0.0",
|
|
@@ -76,6 +76,9 @@
|
|
|
76
76
|
"webpack-merge": "5.8.0",
|
|
77
77
|
"webpack-subresource-integrity": "1.5.2"
|
|
78
78
|
},
|
|
79
|
+
"optionalDependencies": {
|
|
80
|
+
"esbuild": "0.13.4"
|
|
81
|
+
},
|
|
79
82
|
"peerDependencies": {
|
|
80
83
|
"@angular/compiler-cli": "^12.0.0",
|
|
81
84
|
"@angular/localize": "^12.0.0",
|
|
@@ -68,9 +68,15 @@ function default_1() {
|
|
|
68
68
|
if (!enumCallee.isFunctionExpression() || enumCallee.node.params.length !== 1) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
+
const enumCalleeParam = enumCallee.node.params[0];
|
|
72
|
+
const isEnumCalleeMatching = core_1.types.isIdentifier(enumCalleeParam) && enumCalleeParam.name === declarationId.name;
|
|
71
73
|
// Loose mode rewrites the enum to a shorter but less TypeScript-like form
|
|
74
|
+
// Note: We only can apply the `loose` mode transformation if the callee parameter matches
|
|
75
|
+
// with the declaration identifier name. This is necessary in case the the declaration id has
|
|
76
|
+
// been renamed to avoid collisions, as the loose transform would then break the enum assignments
|
|
77
|
+
// which rely on the differently-named callee identifier name.
|
|
72
78
|
let enumAssignments;
|
|
73
|
-
if (loose) {
|
|
79
|
+
if (loose && isEnumCalleeMatching) {
|
|
74
80
|
enumAssignments = [];
|
|
75
81
|
}
|
|
76
82
|
// Check if all enum member values are pure.
|
package/src/utils/color.js
CHANGED
|
@@ -29,7 +29,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.colors = exports.removeColor = void 0;
|
|
30
30
|
const ansiColors = __importStar(require("ansi-colors"));
|
|
31
31
|
const tty_1 = require("tty");
|
|
32
|
-
|
|
32
|
+
function supportColor() {
|
|
33
|
+
if (process.env.FORCE_COLOR !== undefined) {
|
|
34
|
+
// 2 colors: FORCE_COLOR = 0 (Disables colors), depth 1
|
|
35
|
+
// 16 colors: FORCE_COLOR = 1, depth 4
|
|
36
|
+
// 256 colors: FORCE_COLOR = 2, depth 8
|
|
37
|
+
// 16,777,216 colors: FORCE_COLOR = 3, depth 16
|
|
38
|
+
// See: https://nodejs.org/dist/latest-v12.x/docs/api/tty.html#tty_writestream_getcolordepth_env
|
|
39
|
+
// and https://github.com/nodejs/node/blob/b9f36062d7b5c5039498e98d2f2c180dca2a7065/lib/internal/tty.js#L106;
|
|
40
|
+
switch (process.env.FORCE_COLOR) {
|
|
41
|
+
case '':
|
|
42
|
+
case 'true':
|
|
43
|
+
case '1':
|
|
44
|
+
case '2':
|
|
45
|
+
case '3':
|
|
46
|
+
return true;
|
|
47
|
+
default:
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (process.stdout instanceof tty_1.WriteStream) {
|
|
52
|
+
return process.stdout.getColorDepth() > 1;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
33
56
|
function removeColor(text) {
|
|
34
57
|
// This has been created because when colors.enabled is false unstyle doesn't work
|
|
35
58
|
// see: https://github.com/doowb/ansi-colors/blob/a4794363369d7b4d1872d248fc43a12761640d8e/index.js#L38
|
|
@@ -40,4 +63,4 @@ exports.removeColor = removeColor;
|
|
|
40
63
|
// Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44
|
|
41
64
|
const colors = ansiColors.create();
|
|
42
65
|
exports.colors = colors;
|
|
43
|
-
colors.enabled =
|
|
66
|
+
colors.enabled = supportColor();
|
|
@@ -386,7 +386,7 @@ function getCommonConfig(wco) {
|
|
|
386
386
|
test: /\.[cm]?js$|\.tsx?$/,
|
|
387
387
|
// The below is needed due to a bug in `@babel/runtime`. See: https://github.com/babel/babel/issues/12824
|
|
388
388
|
resolve: { fullySpecified: false },
|
|
389
|
-
exclude: [/[
|
|
389
|
+
exclude: [/[/\\](?:core-js|@babel|tslib|web-animations-js|web-streams-polyfill)[/\\]/],
|
|
390
390
|
use: [
|
|
391
391
|
{
|
|
392
392
|
loader: require.resolve('../../babel/webpack-loader'),
|
|
@@ -33,6 +33,7 @@ const sass_service_1 = require("../../sass/sass-service");
|
|
|
33
33
|
const build_browser_features_1 = require("../../utils/build-browser-features");
|
|
34
34
|
const environment_options_1 = require("../../utils/environment-options");
|
|
35
35
|
const plugins_1 = require("../plugins");
|
|
36
|
+
const esbuild_executor_1 = require("../plugins/esbuild-executor");
|
|
36
37
|
const helpers_1 = require("../utils/helpers");
|
|
37
38
|
function resolveGlobalStyles(styleEntrypoints, root, preserveSymlinks) {
|
|
38
39
|
const entryPoints = {};
|
|
@@ -243,7 +244,7 @@ function getStylesConfig(wco) {
|
|
|
243
244
|
const extraMinimizers = [];
|
|
244
245
|
if (buildOptions.optimization.styles.minify) {
|
|
245
246
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
|
246
|
-
const esbuild =
|
|
247
|
+
const esbuild = new esbuild_executor_1.EsbuildExecutor();
|
|
247
248
|
const cssnanoOptions = {
|
|
248
249
|
preset: [
|
|
249
250
|
'default',
|
|
@@ -0,0 +1,46 @@
|
|
|
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 type { FormatMessagesOptions, PartialMessage, TransformOptions, TransformResult } from 'esbuild';
|
|
9
|
+
/**
|
|
10
|
+
* Provides the ability to execute esbuild regardless of the current platform's support
|
|
11
|
+
* for using the native variant of esbuild. The native variant will be preferred (assuming
|
|
12
|
+
* the `alwaysUseWasm` constructor option is `false) due to its inherent performance advantages.
|
|
13
|
+
* At first use of esbuild, a supportability test will be automatically performed and the
|
|
14
|
+
* WASM-variant will be used if needed by the platform.
|
|
15
|
+
*/
|
|
16
|
+
export declare class EsbuildExecutor implements Pick<typeof import('esbuild'), 'transform' | 'formatMessages'> {
|
|
17
|
+
private alwaysUseWasm;
|
|
18
|
+
private esbuildTransform;
|
|
19
|
+
private esbuildFormatMessages;
|
|
20
|
+
private initialized;
|
|
21
|
+
/**
|
|
22
|
+
* Constructs an instance of the `EsbuildExecutor` class.
|
|
23
|
+
*
|
|
24
|
+
* @param alwaysUseWasm If true, the WASM-variant will be preferred and no support test will be
|
|
25
|
+
* performed; if false (default), the native variant will be preferred.
|
|
26
|
+
*/
|
|
27
|
+
constructor(alwaysUseWasm?: boolean);
|
|
28
|
+
/**
|
|
29
|
+
* Determines whether the native variant of esbuild can be used on the current platform.
|
|
30
|
+
*
|
|
31
|
+
* @returns True, if the native variant of esbuild is support; False, if the WASM variant is required.
|
|
32
|
+
*/
|
|
33
|
+
static hasNativeSupport(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Initializes the esbuild transform and format messages functions.
|
|
36
|
+
*
|
|
37
|
+
* @returns A promise that fulfills when esbuild has been loaded and available for use.
|
|
38
|
+
*/
|
|
39
|
+
private ensureEsbuild;
|
|
40
|
+
/**
|
|
41
|
+
* Transitions an executor instance to use the WASM-variant of esbuild.
|
|
42
|
+
*/
|
|
43
|
+
private useWasm;
|
|
44
|
+
transform(input: string, options?: TransformOptions): Promise<TransformResult>;
|
|
45
|
+
formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise<string[]>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
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 __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
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.EsbuildExecutor = void 0;
|
|
30
|
+
const child_process_1 = require("child_process");
|
|
31
|
+
const path = __importStar(require("path"));
|
|
32
|
+
/**
|
|
33
|
+
* Provides the ability to execute esbuild regardless of the current platform's support
|
|
34
|
+
* for using the native variant of esbuild. The native variant will be preferred (assuming
|
|
35
|
+
* the `alwaysUseWasm` constructor option is `false) due to its inherent performance advantages.
|
|
36
|
+
* At first use of esbuild, a supportability test will be automatically performed and the
|
|
37
|
+
* WASM-variant will be used if needed by the platform.
|
|
38
|
+
*/
|
|
39
|
+
class EsbuildExecutor {
|
|
40
|
+
/**
|
|
41
|
+
* Constructs an instance of the `EsbuildExecutor` class.
|
|
42
|
+
*
|
|
43
|
+
* @param alwaysUseWasm If true, the WASM-variant will be preferred and no support test will be
|
|
44
|
+
* performed; if false (default), the native variant will be preferred.
|
|
45
|
+
*/
|
|
46
|
+
constructor(alwaysUseWasm = false) {
|
|
47
|
+
this.alwaysUseWasm = alwaysUseWasm;
|
|
48
|
+
this.initialized = false;
|
|
49
|
+
this.esbuildTransform = this.esbuildFormatMessages = () => {
|
|
50
|
+
throw new Error('esbuild implementation missing');
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Determines whether the native variant of esbuild can be used on the current platform.
|
|
55
|
+
*
|
|
56
|
+
* @returns True, if the native variant of esbuild is support; False, if the WASM variant is required.
|
|
57
|
+
*/
|
|
58
|
+
static hasNativeSupport() {
|
|
59
|
+
// Try to use native variant to ensure it is functional for the platform.
|
|
60
|
+
// Spawning a separate esbuild check process is used to determine if the native
|
|
61
|
+
// variant is viable. If check fails, the WASM variant is initialized instead.
|
|
62
|
+
// Attempting to call one of the native esbuild functions is not a viable test
|
|
63
|
+
// currently since esbuild spawn errors are currently not propagated through the
|
|
64
|
+
// call stack for the esbuild function. If this limitation is removed in the future
|
|
65
|
+
// then the separate process spawn check can be removed in favor of a direct function
|
|
66
|
+
// call check.
|
|
67
|
+
try {
|
|
68
|
+
const { status, error } = child_process_1.spawnSync(process.execPath, [
|
|
69
|
+
path.join(__dirname, '../../../esbuild-check.js'),
|
|
70
|
+
]);
|
|
71
|
+
return status === 0 && error === undefined;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Initializes the esbuild transform and format messages functions.
|
|
79
|
+
*
|
|
80
|
+
* @returns A promise that fulfills when esbuild has been loaded and available for use.
|
|
81
|
+
*/
|
|
82
|
+
async ensureEsbuild() {
|
|
83
|
+
if (this.initialized) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// If the WASM variant was preferred at class construction or native is not supported, use WASM
|
|
87
|
+
if (this.alwaysUseWasm || !EsbuildExecutor.hasNativeSupport()) {
|
|
88
|
+
await this.useWasm();
|
|
89
|
+
this.initialized = true;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
// Use the faster native variant if available.
|
|
94
|
+
const { transform, formatMessages } = await Promise.resolve().then(() => __importStar(require('esbuild')));
|
|
95
|
+
this.esbuildTransform = transform;
|
|
96
|
+
this.esbuildFormatMessages = formatMessages;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// If the native variant is not installed then use the WASM-based variant
|
|
100
|
+
await this.useWasm();
|
|
101
|
+
}
|
|
102
|
+
this.initialized = true;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Transitions an executor instance to use the WASM-variant of esbuild.
|
|
106
|
+
*/
|
|
107
|
+
async useWasm() {
|
|
108
|
+
const { transform, formatMessages } = await Promise.resolve().then(() => __importStar(require('esbuild-wasm')));
|
|
109
|
+
this.esbuildTransform = transform;
|
|
110
|
+
this.esbuildFormatMessages = formatMessages;
|
|
111
|
+
// The ESBUILD_BINARY_PATH environment variable cannot exist when attempting to use the
|
|
112
|
+
// WASM variant. If it is then the binary located at the specified path will be used instead
|
|
113
|
+
// of the WASM variant.
|
|
114
|
+
delete process.env.ESBUILD_BINARY_PATH;
|
|
115
|
+
this.alwaysUseWasm = true;
|
|
116
|
+
}
|
|
117
|
+
async transform(input, options) {
|
|
118
|
+
await this.ensureEsbuild();
|
|
119
|
+
return this.esbuildTransform(input, options);
|
|
120
|
+
}
|
|
121
|
+
async formatMessages(messages, options) {
|
|
122
|
+
await this.ensureEsbuild();
|
|
123
|
+
return this.esbuildFormatMessages(messages, options);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.EsbuildExecutor = EsbuildExecutor;
|
|
@@ -14,6 +14,7 @@ exports.JavaScriptOptimizerPlugin = void 0;
|
|
|
14
14
|
const piscina_1 = __importDefault(require("piscina"));
|
|
15
15
|
const typescript_1 = require("typescript");
|
|
16
16
|
const environment_options_1 = require("../../utils/environment-options");
|
|
17
|
+
const esbuild_executor_1 = require("./esbuild-executor");
|
|
17
18
|
/**
|
|
18
19
|
* The maximum number of Workers that will be created to execute optimize tasks.
|
|
19
20
|
*/
|
|
@@ -105,6 +106,10 @@ class JavaScriptOptimizerPlugin {
|
|
|
105
106
|
target,
|
|
106
107
|
removeLicenses: this.options.removeLicenses,
|
|
107
108
|
advanced: this.options.advanced,
|
|
109
|
+
// Perform a single native esbuild support check.
|
|
110
|
+
// This removes the need for each worker to perform the check which would
|
|
111
|
+
// otherwise require spawning a separate process per worker.
|
|
112
|
+
alwaysUseWasm: !esbuild_executor_1.EsbuildExecutor.hasNativeSupport(),
|
|
108
113
|
};
|
|
109
114
|
// Sort scripts so larger scripts start first - worker pool uses a FIFO queue
|
|
110
115
|
scriptsToOptimize.sort((a, b) => a.code.length - b.code.length);
|
|
@@ -13,22 +13,64 @@ interface OptimizeRequest {
|
|
|
13
13
|
* The options to use when optimizing.
|
|
14
14
|
*/
|
|
15
15
|
options: {
|
|
16
|
+
/**
|
|
17
|
+
* Controls advanced optimizations.
|
|
18
|
+
* Currently these are only terser related:
|
|
19
|
+
* * terser compress passes are set to 2
|
|
20
|
+
* * terser pure_getters option is enabled
|
|
21
|
+
*/
|
|
16
22
|
advanced: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Specifies the string tokens that should be replaced with a defined value.
|
|
25
|
+
*/
|
|
17
26
|
define?: Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* Controls whether class, function, and variable names should be left intact
|
|
29
|
+
* throughout the output code.
|
|
30
|
+
*/
|
|
18
31
|
keepNames: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Controls whether license text is removed from the output code.
|
|
34
|
+
* Within the CLI, this option is linked to the license extraction functionality.
|
|
35
|
+
*/
|
|
19
36
|
removeLicenses: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Controls whether source maps should be generated.
|
|
39
|
+
*/
|
|
20
40
|
sourcemap: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Specifies the target ECMAScript version for the output code.
|
|
43
|
+
*/
|
|
21
44
|
target: 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020;
|
|
45
|
+
/**
|
|
46
|
+
* Controls whether esbuild should only use the WASM-variant instead of trying to
|
|
47
|
+
* use the native variant. Some platforms may not support the native-variant and
|
|
48
|
+
* this option allows one support test to be conducted prior to all the workers starting.
|
|
49
|
+
*/
|
|
50
|
+
alwaysUseWasm: boolean;
|
|
22
51
|
};
|
|
23
52
|
/**
|
|
24
53
|
* The JavaScript asset to optimize.
|
|
25
54
|
*/
|
|
26
55
|
asset: {
|
|
56
|
+
/**
|
|
57
|
+
* The name of the JavaScript asset (typically the filename).
|
|
58
|
+
*/
|
|
27
59
|
name: string;
|
|
60
|
+
/**
|
|
61
|
+
* The source content of the JavaScript asset.
|
|
62
|
+
*/
|
|
28
63
|
code: string;
|
|
64
|
+
/**
|
|
65
|
+
* The source map of the JavaScript asset, if available.
|
|
66
|
+
* This map is merged with all intermediate source maps during optimization.
|
|
67
|
+
*/
|
|
29
68
|
map: object;
|
|
30
69
|
};
|
|
31
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Handles optimization requests sent from the main thread via the `JavaScriptOptimizerPlugin`.
|
|
73
|
+
*/
|
|
32
74
|
export default function ({ asset, options }: OptimizeRequest): Promise<{
|
|
33
75
|
name: string;
|
|
34
76
|
code: string;
|
|
@@ -11,23 +11,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
const remapping_1 = __importDefault(require("@ampproject/remapping"));
|
|
14
|
-
const esbuild_1 = require("esbuild");
|
|
15
14
|
const terser_1 = require("terser");
|
|
15
|
+
const esbuild_executor_1 = require("./esbuild-executor");
|
|
16
|
+
/**
|
|
17
|
+
* The cached esbuild executor.
|
|
18
|
+
* This will automatically use the native or WASM version based on platform and availability
|
|
19
|
+
* with the native version given priority due to its superior performance.
|
|
20
|
+
*/
|
|
21
|
+
let esbuild;
|
|
22
|
+
/**
|
|
23
|
+
* Handles optimization requests sent from the main thread via the `JavaScriptOptimizerPlugin`.
|
|
24
|
+
*/
|
|
16
25
|
async function default_1({ asset, options }) {
|
|
17
26
|
// esbuild is used as a first pass
|
|
18
|
-
const esbuildResult = await
|
|
19
|
-
minifyIdentifiers: !options.keepNames,
|
|
20
|
-
minifySyntax: true,
|
|
21
|
-
// NOTE: Disabling whitespace ensures unused pure annotations are kept
|
|
22
|
-
minifyWhitespace: false,
|
|
23
|
-
pure: ['forwardRef'],
|
|
24
|
-
legalComments: options.removeLicenses ? 'none' : 'inline',
|
|
25
|
-
sourcefile: asset.name,
|
|
26
|
-
sourcemap: options.sourcemap && 'external',
|
|
27
|
-
define: options.define,
|
|
28
|
-
keepNames: options.keepNames,
|
|
29
|
-
target: `es${options.target}`,
|
|
30
|
-
});
|
|
27
|
+
const esbuildResult = await optimizeWithEsbuild(asset.code, asset.name, options);
|
|
31
28
|
// terser is used as a second pass
|
|
32
29
|
const terserResult = await optimizeWithTerser(asset.name, esbuildResult.code, options.sourcemap, options.target, options.advanced);
|
|
33
30
|
// Merge intermediate sourcemaps with input sourcemap if enabled
|
|
@@ -48,6 +45,65 @@ async function default_1({ asset, options }) {
|
|
|
48
45
|
return { name: asset.name, code: terserResult.code, map: fullSourcemap };
|
|
49
46
|
}
|
|
50
47
|
exports.default = default_1;
|
|
48
|
+
/**
|
|
49
|
+
* Optimizes a JavaScript asset using esbuild.
|
|
50
|
+
*
|
|
51
|
+
* @param content The JavaScript asset source content to optimize.
|
|
52
|
+
* @param name The name of the JavaScript asset. Used to generate source maps.
|
|
53
|
+
* @param options The optimization request options to apply to the content.
|
|
54
|
+
* @returns A promise that resolves with the optimized code, source map, and any warnings.
|
|
55
|
+
*/
|
|
56
|
+
async function optimizeWithEsbuild(content, name, options) {
|
|
57
|
+
var _a;
|
|
58
|
+
if (!esbuild) {
|
|
59
|
+
esbuild = new esbuild_executor_1.EsbuildExecutor(options.alwaysUseWasm);
|
|
60
|
+
}
|
|
61
|
+
let result;
|
|
62
|
+
try {
|
|
63
|
+
result = await esbuild.transform(content, {
|
|
64
|
+
minifyIdentifiers: !options.keepNames,
|
|
65
|
+
minifySyntax: true,
|
|
66
|
+
// NOTE: Disabling whitespace ensures unused pure annotations are kept
|
|
67
|
+
minifyWhitespace: false,
|
|
68
|
+
pure: ['forwardRef'],
|
|
69
|
+
legalComments: options.removeLicenses ? 'none' : 'inline',
|
|
70
|
+
sourcefile: name,
|
|
71
|
+
sourcemap: options.sourcemap && 'external',
|
|
72
|
+
define: options.define,
|
|
73
|
+
keepNames: options.keepNames,
|
|
74
|
+
target: `es${options.target}`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const failure = error;
|
|
79
|
+
// If esbuild fails with only ES5 support errors, fallback to just terser.
|
|
80
|
+
// This will only happen if ES5 is the output target and a global script contains ES2015+ syntax.
|
|
81
|
+
// In that case, the global script is technically already invalid for the target environment but
|
|
82
|
+
// this is and has been considered a configuration issue. Global scripts must be compatible with
|
|
83
|
+
// the target environment.
|
|
84
|
+
if ((_a = failure.errors) === null || _a === void 0 ? void 0 : _a.every((error) => error.text.includes('to the configured target environment ("es5") is not supported yet'))) {
|
|
85
|
+
result = {
|
|
86
|
+
code: content,
|
|
87
|
+
map: '',
|
|
88
|
+
warnings: [],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Optimizes a JavaScript asset using terser.
|
|
99
|
+
*
|
|
100
|
+
* @param name The name of the JavaScript asset. Used to generate source maps.
|
|
101
|
+
* @param code The JavaScript asset source content to optimize.
|
|
102
|
+
* @param sourcemaps If true, generate an output source map for the optimized code.
|
|
103
|
+
* @param target Specifies the target ECMAScript version for the output code.
|
|
104
|
+
* @param advanced Controls advanced optimizations.
|
|
105
|
+
* @returns A promise that resolves with the optimized code and source map.
|
|
106
|
+
*/
|
|
51
107
|
async function optimizeWithTerser(name, code, sourcemaps, target, advanced) {
|
|
52
108
|
const result = await terser_1.minify({ [name]: code }, {
|
|
53
109
|
compress: {
|