@angular-devkit/build-angular 15.1.0-next.1 → 15.1.0-next.3
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 +14 -14
- package/src/babel/presets/application.d.ts +0 -1
- package/src/babel/presets/application.js +29 -1
- package/src/babel/webpack-loader.js +5 -11
- package/src/builders/browser-esbuild/compiler-plugin.d.ts +3 -1
- package/src/builders/browser-esbuild/compiler-plugin.js +11 -12
- package/src/builders/browser-esbuild/experimental-warnings.js +3 -7
- package/src/builders/browser-esbuild/index.js +57 -14
- package/src/builders/browser-esbuild/javascript-transformer-worker.js +1 -1
- package/src/builders/browser-esbuild/javascript-transformer.d.ts +0 -1
- package/src/builders/browser-esbuild/javascript-transformer.js +15 -8
- package/src/builders/browser-esbuild/options.d.ts +2 -1
- package/src/builders/browser-esbuild/options.js +4 -2
- package/src/builders/browser-esbuild/sass-plugin.d.ts +5 -3
- package/src/builders/browser-esbuild/sass-plugin.js +87 -74
- package/src/builders/browser-esbuild/stylesheets.d.ts +13 -25
- package/src/builders/browser-esbuild/stylesheets.js +57 -40
- package/src/builders/browser-esbuild/worker-angular-compilation.d.ts +0 -0
- package/src/builders/browser-esbuild/worker-angular-compilation.js +59 -0
- package/src/builders/karma/index.js +3 -1
- package/src/utils/esbuild-targets.js +17 -2
- package/src/utils/i18n-inlining.js +1 -1
- package/src/utils/index-file/augment-index-html.js +1 -1
- package/src/utils/index-file/html-rewriting-stream.d.ts +1 -1
- package/src/utils/index-file/html-rewriting-stream.js +24 -20
- package/src/utils/index-file/inline-fonts.js +6 -2
- package/src/utils/process-bundle.js +1 -1
- package/src/webpack/configs/styles.js +1 -0
- package/src/webpack/plugins/javascript-optimizer-worker.js +3 -2
- package/src/webpack/plugins/styles-webpack-plugin.js +26 -24
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "15.1.0-next.
|
|
3
|
+
"version": "15.1.0-next.3",
|
|
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": "2.2.0",
|
|
10
|
-
"@angular-devkit/architect": "0.1501.0-next.
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1501.0-next.
|
|
12
|
-
"@angular-devkit/core": "15.1.0-next.
|
|
10
|
+
"@angular-devkit/architect": "0.1501.0-next.3",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1501.0-next.3",
|
|
12
|
+
"@angular-devkit/core": "15.1.0-next.3",
|
|
13
13
|
"@babel/core": "7.20.5",
|
|
14
14
|
"@babel/generator": "7.20.5",
|
|
15
15
|
"@babel/helper-annotate-as-pure": "7.18.6",
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"@babel/runtime": "7.20.6",
|
|
21
21
|
"@babel/template": "7.18.10",
|
|
22
22
|
"@discoveryjs/json-ext": "0.5.7",
|
|
23
|
-
"@ngtools/webpack": "15.1.0-next.
|
|
23
|
+
"@ngtools/webpack": "15.1.0-next.3",
|
|
24
24
|
"ansi-colors": "4.1.3",
|
|
25
25
|
"autoprefixer": "10.4.13",
|
|
26
26
|
"babel-loader": "9.1.0",
|
|
27
27
|
"babel-plugin-istanbul": "6.1.1",
|
|
28
28
|
"browserslist": "4.21.4",
|
|
29
|
-
"cacache": "17.0.
|
|
29
|
+
"cacache": "17.0.3",
|
|
30
30
|
"chokidar": "3.5.3",
|
|
31
31
|
"copy-webpack-plugin": "11.0.0",
|
|
32
32
|
"critters": "0.0.16",
|
|
33
|
-
"css-loader": "6.7.
|
|
34
|
-
"esbuild-wasm": "0.
|
|
33
|
+
"css-loader": "6.7.3",
|
|
34
|
+
"esbuild-wasm": "0.16.6",
|
|
35
35
|
"glob": "8.0.3",
|
|
36
36
|
"https-proxy-agent": "5.0.1",
|
|
37
37
|
"inquirer": "8.2.4",
|
|
@@ -41,22 +41,22 @@
|
|
|
41
41
|
"less-loader": "11.1.0",
|
|
42
42
|
"license-webpack-plugin": "4.0.2",
|
|
43
43
|
"loader-utils": "3.2.1",
|
|
44
|
-
"magic-string": "0.
|
|
45
|
-
"mini-css-extract-plugin": "2.7.
|
|
44
|
+
"magic-string": "0.27.0",
|
|
45
|
+
"mini-css-extract-plugin": "2.7.2",
|
|
46
46
|
"open": "8.4.0",
|
|
47
47
|
"ora": "5.4.1",
|
|
48
48
|
"parse5-html-rewriting-stream": "6.0.1",
|
|
49
49
|
"piscina": "3.2.0",
|
|
50
|
-
"postcss": "8.4.
|
|
50
|
+
"postcss": "8.4.20",
|
|
51
51
|
"postcss-loader": "7.0.2",
|
|
52
52
|
"resolve-url-loader": "5.0.0",
|
|
53
53
|
"rxjs": "6.6.7",
|
|
54
|
-
"sass": "1.56.
|
|
54
|
+
"sass": "1.56.2",
|
|
55
55
|
"sass-loader": "13.2.0",
|
|
56
56
|
"semver": "7.3.8",
|
|
57
57
|
"source-map-loader": "4.0.1",
|
|
58
58
|
"source-map-support": "0.5.21",
|
|
59
|
-
"terser": "5.16.
|
|
59
|
+
"terser": "5.16.1",
|
|
60
60
|
"text-table": "0.2.0",
|
|
61
61
|
"tree-kill": "1.2.2",
|
|
62
62
|
"tslib": "2.4.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"webpack-subresource-integrity": "5.1.0"
|
|
68
68
|
},
|
|
69
69
|
"optionalDependencies": {
|
|
70
|
-
"esbuild": "0.
|
|
70
|
+
"esbuild": "0.16.6"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@angular/compiler-cli": "^15.0.0-next",
|
|
@@ -31,7 +31,6 @@ export interface ApplicationPresetOptions {
|
|
|
31
31
|
jitMode: boolean;
|
|
32
32
|
linkerPluginCreator: typeof import('@angular/compiler-cli/linker/babel').createEs2015LinkerPlugin;
|
|
33
33
|
};
|
|
34
|
-
forcePresetEnv?: boolean;
|
|
35
34
|
forceAsyncTransformation?: boolean;
|
|
36
35
|
instrumentCode?: {
|
|
37
36
|
includedBasePath: string;
|
|
@@ -29,10 +29,27 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
29
29
|
__setModuleDefault(result, mod);
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
32
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
36
|
const assert_1 = require("assert");
|
|
37
|
+
const browserslist_1 = __importDefault(require("browserslist"));
|
|
34
38
|
const fs = __importStar(require("fs"));
|
|
35
39
|
const path = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* List of browsers which are affected by a WebKit bug where class field
|
|
42
|
+
* initializers might have incorrect variable scopes.
|
|
43
|
+
*
|
|
44
|
+
* See: https://github.com/angular/angular-cli/issues/24355#issuecomment-1333477033
|
|
45
|
+
* See: https://github.com/WebKit/WebKit/commit/e8788a34b3d5f5b4edd7ff6450b80936bff396f2
|
|
46
|
+
*/
|
|
47
|
+
const safariClassFieldScopeBugBrowsers = new Set((0, browserslist_1.default)([
|
|
48
|
+
// Safari <15 is technically not supported via https://angular.io/guide/browser-support,
|
|
49
|
+
// but we apply the workaround if forcibly selected.
|
|
50
|
+
'Safari <=15',
|
|
51
|
+
'iOS <=15',
|
|
52
|
+
]));
|
|
36
53
|
function createI18nDiagnostics(reporter) {
|
|
37
54
|
const diagnostics = new (class {
|
|
38
55
|
constructor() {
|
|
@@ -113,13 +130,24 @@ function default_1(api, options) {
|
|
|
113
130
|
},
|
|
114
131
|
}));
|
|
115
132
|
}
|
|
116
|
-
|
|
133
|
+
// Applications code ES version can be controlled using TypeScript's `target` option.
|
|
134
|
+
// However, this doesn't effect libraries and hence we use preset-env to downlevel ES features
|
|
135
|
+
// based on the supported browsers in browserslist.
|
|
136
|
+
if (options.supportedBrowsers) {
|
|
137
|
+
const includePlugins = [];
|
|
138
|
+
// If a Safari browser affected by the class field scope bug is selected, we
|
|
139
|
+
// downlevel class properties by ensuring the class properties Babel plugin
|
|
140
|
+
// is always included- regardless of the preset-env targets.
|
|
141
|
+
if (options.supportedBrowsers.some((b) => safariClassFieldScopeBugBrowsers.has(b))) {
|
|
142
|
+
includePlugins.push('@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-private-methods');
|
|
143
|
+
}
|
|
117
144
|
presets.push([
|
|
118
145
|
require('@babel/preset-env').default,
|
|
119
146
|
{
|
|
120
147
|
bugfixes: true,
|
|
121
148
|
modules: false,
|
|
122
149
|
targets: options.supportedBrowsers,
|
|
150
|
+
include: includePlugins,
|
|
123
151
|
exclude: ['transform-typeof-symbol'],
|
|
124
152
|
},
|
|
125
153
|
]);
|
|
@@ -51,13 +51,12 @@ exports.default = (0, babel_loader_1.custom)(() => {
|
|
|
51
51
|
});
|
|
52
52
|
return {
|
|
53
53
|
async customOptions(options, { source, map }) {
|
|
54
|
-
var _a, _b
|
|
54
|
+
var _a, _b;
|
|
55
55
|
const { i18n, aot, optimize, instrumentCode, supportedBrowsers, ...rawOptions } = options;
|
|
56
56
|
// Must process file if plugins are added
|
|
57
57
|
let shouldProcess = Array.isArray(rawOptions.plugins) && rawOptions.plugins.length > 0;
|
|
58
58
|
const customOptions = {
|
|
59
59
|
forceAsyncTransformation: false,
|
|
60
|
-
forcePresetEnv: false,
|
|
61
60
|
angularLinker: undefined,
|
|
62
61
|
i18n: undefined,
|
|
63
62
|
instrumentCode: undefined,
|
|
@@ -76,20 +75,15 @@ exports.default = (0, babel_loader_1.custom)(() => {
|
|
|
76
75
|
};
|
|
77
76
|
shouldProcess = true;
|
|
78
77
|
}
|
|
79
|
-
// Analyze for ES target processing
|
|
80
|
-
if ((_a = customOptions.supportedBrowsers) === null || _a === void 0 ? void 0 : _a.length) {
|
|
81
|
-
// Applications code ES version can be controlled using TypeScript's `target` option.
|
|
82
|
-
// However, this doesn't effect libraries and hence we use preset-env to downlevel ES fetaures
|
|
83
|
-
// based on the supported browsers in browserlist.
|
|
84
|
-
customOptions.forcePresetEnv = true;
|
|
85
|
-
}
|
|
86
78
|
// Application code (TS files) will only contain native async if target is ES2017+.
|
|
87
79
|
// However, third-party libraries can regardless of the target option.
|
|
88
80
|
// APF packages with code in [f]esm2015 directories is downlevelled to ES2015 and
|
|
89
81
|
// will not have native async.
|
|
90
82
|
customOptions.forceAsyncTransformation =
|
|
91
83
|
!/[\\/][_f]?esm2015[\\/]/.test(this.resourcePath) && source.includes('async');
|
|
92
|
-
shouldProcess || (shouldProcess = customOptions.forceAsyncTransformation ||
|
|
84
|
+
shouldProcess || (shouldProcess = customOptions.forceAsyncTransformation ||
|
|
85
|
+
customOptions.supportedBrowsers !== undefined ||
|
|
86
|
+
false);
|
|
93
87
|
// Analyze for i18n inlining
|
|
94
88
|
if (i18n &&
|
|
95
89
|
!/[\\/]@angular[\\/](?:compiler|localize)/.test(this.resourcePath) &&
|
|
@@ -128,7 +122,7 @@ exports.default = (0, babel_loader_1.custom)(() => {
|
|
|
128
122
|
pureTopLevel: angularPackage,
|
|
129
123
|
// JavaScript modules that are marked as side effect free are considered to have
|
|
130
124
|
// no decorators that contain non-local effects.
|
|
131
|
-
wrapDecorators: !!((
|
|
125
|
+
wrapDecorators: !!((_b = (_a = this._module) === null || _a === void 0 ? void 0 : _a.factoryMeta) === null || _b === void 0 ? void 0 : _b.sideEffectFree),
|
|
132
126
|
};
|
|
133
127
|
shouldProcess = true;
|
|
134
128
|
}
|
|
@@ -22,4 +22,6 @@ export interface CompilerPluginOptions {
|
|
|
22
22
|
fileReplacements?: Record<string, string>;
|
|
23
23
|
sourceFileCache?: SourceFileCache;
|
|
24
24
|
}
|
|
25
|
-
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, styleOptions: BundleStylesheetOptions
|
|
25
|
+
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, styleOptions: BundleStylesheetOptions & {
|
|
26
|
+
inlineStyleLanguage: string;
|
|
27
|
+
}): Plugin;
|
|
@@ -44,6 +44,10 @@ const angular_compilation_1 = require("./angular-compilation");
|
|
|
44
44
|
const javascript_transformer_1 = require("./javascript-transformer");
|
|
45
45
|
const profiling_1 = require("./profiling");
|
|
46
46
|
const stylesheets_1 = require("./stylesheets");
|
|
47
|
+
/**
|
|
48
|
+
* A counter for component styles used to generate unique build-time identifiers for each stylesheet.
|
|
49
|
+
*/
|
|
50
|
+
let componentStyleCounter = 0;
|
|
47
51
|
/**
|
|
48
52
|
* Converts TypeScript Diagnostic related information into an esbuild compatible note object.
|
|
49
53
|
* Related information is a subset of a full TypeScript Diagnostic and also used for diagnostic
|
|
@@ -149,6 +153,10 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
149
153
|
// Skip keys that have been manually provided
|
|
150
154
|
continue;
|
|
151
155
|
}
|
|
156
|
+
if (key === 'ngDevMode') {
|
|
157
|
+
// ngDevMode is already set based on the builder's script optimization option
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
152
160
|
// esbuild requires values to be a string (actual strings need to be quoted).
|
|
153
161
|
// In this case, all provided values are booleans.
|
|
154
162
|
build.initialOptions.define[key] = value.toString();
|
|
@@ -213,18 +221,9 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
213
221
|
var _a, _b;
|
|
214
222
|
// Stylesheet file only exists for external stylesheets
|
|
215
223
|
const filename = stylesheetFile !== null && stylesheetFile !== void 0 ? stylesheetFile : containingFile;
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
if (filename.endsWith('.scss') || filename.endsWith('.sass')) {
|
|
220
|
-
stylesheetResult = await (0, stylesheets_1.bundleStylesheetFile)(filename, styleOptions);
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
stylesheetResult = await (0, stylesheets_1.bundleStylesheetText)(data, {
|
|
224
|
-
resolvePath: path.dirname(filename),
|
|
225
|
-
virtualName: filename,
|
|
226
|
-
}, styleOptions);
|
|
227
|
-
}
|
|
224
|
+
const stylesheetResult = await (0, stylesheets_1.bundleComponentStylesheet)(
|
|
225
|
+
// TODO: Evaluate usage of a fast hash instead
|
|
226
|
+
`${++componentStyleCounter}`, styleOptions.inlineStyleLanguage, data, filename, !stylesheetFile, styleOptions);
|
|
228
227
|
const { contents, resourceFiles, errors, warnings } = stylesheetResult;
|
|
229
228
|
((_a = result.errors) !== null && _a !== void 0 ? _a : (result.errors = [])).push(...errors);
|
|
230
229
|
((_b = result.warnings) !== null && _b !== void 0 ? _b : (result.warnings = [])).push(...warnings);
|
|
@@ -20,10 +20,6 @@ const UNSUPPORTED_OPTIONS = [
|
|
|
20
20
|
// The following two have no effect when localize is not enabled
|
|
21
21
|
// 'i18nDuplicateTranslation',
|
|
22
22
|
// 'i18nMissingTranslation',
|
|
23
|
-
// * Stylesheet preprocessor support
|
|
24
|
-
'inlineStyleLanguage',
|
|
25
|
-
// The following option has no effect until preprocessors are supported
|
|
26
|
-
// 'stylePreprocessorOptions',
|
|
27
23
|
// * Deprecated
|
|
28
24
|
'deployUrl',
|
|
29
25
|
// * Always enabled with esbuild
|
|
@@ -49,10 +45,10 @@ function logExperimentalWarnings(options, context) {
|
|
|
49
45
|
if (typeof value === 'object' && Object.keys(value).length === 0) {
|
|
50
46
|
continue;
|
|
51
47
|
}
|
|
52
|
-
if (unsupportedOption === 'inlineStyleLanguage' && value === 'css') {
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
48
|
context.logger.warn(`The '${unsupportedOption}' option is currently unsupported by this experimental builder and will be ignored.`);
|
|
56
49
|
}
|
|
50
|
+
if (options.inlineStyleLanguage === 'less') {
|
|
51
|
+
context.logger.warn('The less stylesheet preprocessor is not currently supported.');
|
|
52
|
+
}
|
|
57
53
|
}
|
|
58
54
|
exports.logExperimentalWarnings = logExperimentalWarnings;
|
|
@@ -180,7 +180,7 @@ function createOutputFileFromText(path, text) {
|
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
182
|
function createCodeBundleOptions(options, target, sourceFileCache) {
|
|
183
|
-
const { workspaceRoot, entryPoints, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, } = options;
|
|
183
|
+
const { workspaceRoot, entryPoints, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, } = options;
|
|
184
184
|
return {
|
|
185
185
|
absWorkingDir: workspaceRoot,
|
|
186
186
|
bundle: true,
|
|
@@ -190,19 +190,7 @@ function createCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
190
190
|
entryNames: outputNames.bundles,
|
|
191
191
|
assetNames: outputNames.media,
|
|
192
192
|
target,
|
|
193
|
-
supported:
|
|
194
|
-
// Native async/await is not supported with Zone.js. Disabling support here will cause
|
|
195
|
-
// esbuild to downlevel async/await and for await...of to a Zone.js supported form. However, esbuild
|
|
196
|
-
// does not currently support downleveling async generators. Instead babel is used within the JS/TS
|
|
197
|
-
// loader to perform the downlevel transformation.
|
|
198
|
-
// NOTE: If esbuild adds support in the future, the babel support for async generators can be disabled.
|
|
199
|
-
'async-await': false,
|
|
200
|
-
// V8 currently has a performance defect involving object spread operations that can cause signficant
|
|
201
|
-
// degradation in runtime performance. By not supporting the language feature here, a downlevel form
|
|
202
|
-
// will be used instead which provides a workaround for the performance issue.
|
|
203
|
-
// For more details: https://bugs.chromium.org/p/v8/issues/detail?id=11536
|
|
204
|
-
'object-rest-spread': false,
|
|
205
|
-
},
|
|
193
|
+
supported: getFeatureSupport(target),
|
|
206
194
|
mainFields: ['es2020', 'browser', 'module', 'main'],
|
|
207
195
|
conditions: ['es2020', 'es2015', 'module'],
|
|
208
196
|
resolveExtensions: ['.ts', '.tsx', '.mjs', '.js'],
|
|
@@ -241,14 +229,69 @@ function createCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
241
229
|
includePaths: stylePreprocessorOptions === null || stylePreprocessorOptions === void 0 ? void 0 : stylePreprocessorOptions.includePaths,
|
|
242
230
|
externalDependencies,
|
|
243
231
|
target,
|
|
232
|
+
inlineStyleLanguage,
|
|
244
233
|
}),
|
|
245
234
|
],
|
|
246
235
|
define: {
|
|
236
|
+
// Only set to false when script optimizations are enabled. It should not be set to true because
|
|
237
|
+
// Angular turns `ngDevMode` into an object for development debugging purposes when not defined
|
|
238
|
+
// which a constant true value would break.
|
|
247
239
|
...(optimizationOptions.scripts ? { 'ngDevMode': 'false' } : undefined),
|
|
240
|
+
// Only AOT mode is supported currently
|
|
248
241
|
'ngJitMode': 'false',
|
|
249
242
|
},
|
|
250
243
|
};
|
|
251
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Generates a syntax feature object map for Angular applications based on a list of targets.
|
|
247
|
+
* A full set of feature names can be found here: https://esbuild.github.io/api/#supported
|
|
248
|
+
* @param target An array of browser/engine targets in the format accepted by the esbuild `target` option.
|
|
249
|
+
* @returns An object that can be used with the esbuild build `supported` option.
|
|
250
|
+
*/
|
|
251
|
+
function getFeatureSupport(target) {
|
|
252
|
+
const supported = {
|
|
253
|
+
// Native async/await is not supported with Zone.js. Disabling support here will cause
|
|
254
|
+
// esbuild to downlevel async/await and for await...of to a Zone.js supported form. However, esbuild
|
|
255
|
+
// does not currently support downleveling async generators. Instead babel is used within the JS/TS
|
|
256
|
+
// loader to perform the downlevel transformation.
|
|
257
|
+
// NOTE: If esbuild adds support in the future, the babel support for async generators can be disabled.
|
|
258
|
+
'async-await': false,
|
|
259
|
+
// V8 currently has a performance defect involving object spread operations that can cause signficant
|
|
260
|
+
// degradation in runtime performance. By not supporting the language feature here, a downlevel form
|
|
261
|
+
// will be used instead which provides a workaround for the performance issue.
|
|
262
|
+
// For more details: https://bugs.chromium.org/p/v8/issues/detail?id=11536
|
|
263
|
+
'object-rest-spread': false,
|
|
264
|
+
};
|
|
265
|
+
// Detect Safari browser versions that have a class field behavior bug
|
|
266
|
+
// See: https://github.com/angular/angular-cli/issues/24355#issuecomment-1333477033
|
|
267
|
+
// See: https://github.com/WebKit/WebKit/commit/e8788a34b3d5f5b4edd7ff6450b80936bff396f2
|
|
268
|
+
let safariClassFieldScopeBug = false;
|
|
269
|
+
for (const browser of target) {
|
|
270
|
+
let majorVersion;
|
|
271
|
+
if (browser.startsWith('ios')) {
|
|
272
|
+
majorVersion = Number(browser.slice(3, 5));
|
|
273
|
+
}
|
|
274
|
+
else if (browser.startsWith('safari')) {
|
|
275
|
+
majorVersion = Number(browser.slice(6, 8));
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
// Technically, 14.0 is not broken but rather does not have support. However, the behavior
|
|
281
|
+
// is identical since it would be set to false by esbuild if present as a target.
|
|
282
|
+
if (majorVersion === 14 || majorVersion === 15) {
|
|
283
|
+
safariClassFieldScopeBug = true;
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// If class field support cannot be used set to false; otherwise leave undefined to allow
|
|
288
|
+
// esbuild to use `target` to determine support.
|
|
289
|
+
if (safariClassFieldScopeBug) {
|
|
290
|
+
supported['class-field'] = false;
|
|
291
|
+
supported['class-static-field'] = false;
|
|
292
|
+
}
|
|
293
|
+
return supported;
|
|
294
|
+
}
|
|
252
295
|
function createGlobalStylesBundleOptions(options, target) {
|
|
253
296
|
const { workspaceRoot, optimizationOptions, sourcemapOptions, outputNames, globalStyles, preserveSymlinks, externalDependencies, stylePreprocessorOptions, watch, } = options;
|
|
254
297
|
const buildOptions = (0, stylesheets_1.createStylesheetBundleOptions)({
|
|
@@ -25,7 +25,7 @@ exports.default = transformJavaScript;
|
|
|
25
25
|
let linkerPluginCreator;
|
|
26
26
|
async function transformWithBabel({ filename, data, ...options }) {
|
|
27
27
|
var _a, _b;
|
|
28
|
-
const forceAsyncTransformation = (_a = options.forceAsyncTransformation) !== null && _a !== void 0 ? _a : (!/[\\/][_f]?esm2015[\\/]/.test(filename) && /async
|
|
28
|
+
const forceAsyncTransformation = (_a = options.forceAsyncTransformation) !== null && _a !== void 0 ? _a : (!/[\\/][_f]?esm2015[\\/]/.test(filename) && /async(?:\s+function)?\s*\*/.test(data));
|
|
29
29
|
const shouldLink = !options.skipLinker && (await (0, webpack_loader_1.requiresLinking)(filename, data));
|
|
30
30
|
const useInputSourcemap = options.sourcemap &&
|
|
31
31
|
(!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename));
|
|
@@ -22,7 +22,6 @@ export interface JavaScriptTransformerOptions {
|
|
|
22
22
|
*/
|
|
23
23
|
export declare class JavaScriptTransformer {
|
|
24
24
|
#private;
|
|
25
|
-
private options;
|
|
26
25
|
constructor(options: JavaScriptTransformerOptions, maxThreads?: number);
|
|
27
26
|
/**
|
|
28
27
|
* Performs JavaScript transformations on a file from the filesystem.
|
|
@@ -20,7 +20,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
20
20
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
21
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
22
|
};
|
|
23
|
-
var _JavaScriptTransformer_workerPool;
|
|
23
|
+
var _JavaScriptTransformer_workerPool, _JavaScriptTransformer_commonOptions;
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.JavaScriptTransformer = void 0;
|
|
26
26
|
const piscina_1 = __importDefault(require("piscina"));
|
|
@@ -33,12 +33,19 @@ const piscina_1 = __importDefault(require("piscina"));
|
|
|
33
33
|
*/
|
|
34
34
|
class JavaScriptTransformer {
|
|
35
35
|
constructor(options, maxThreads) {
|
|
36
|
-
this.options = options;
|
|
37
36
|
_JavaScriptTransformer_workerPool.set(this, void 0);
|
|
37
|
+
_JavaScriptTransformer_commonOptions.set(this, void 0);
|
|
38
38
|
__classPrivateFieldSet(this, _JavaScriptTransformer_workerPool, new piscina_1.default({
|
|
39
39
|
filename: require.resolve('./javascript-transformer-worker'),
|
|
40
40
|
maxThreads,
|
|
41
41
|
}), "f");
|
|
42
|
+
// Extract options to ensure only the named options are serialized and sent to the worker
|
|
43
|
+
const { sourcemap, thirdPartySourcemaps = false, advancedOptimizations = false } = options;
|
|
44
|
+
__classPrivateFieldSet(this, _JavaScriptTransformer_commonOptions, {
|
|
45
|
+
sourcemap,
|
|
46
|
+
thirdPartySourcemaps,
|
|
47
|
+
advancedOptimizations,
|
|
48
|
+
}, "f");
|
|
42
49
|
}
|
|
43
50
|
/**
|
|
44
51
|
* Performs JavaScript transformations on a file from the filesystem.
|
|
@@ -51,7 +58,7 @@ class JavaScriptTransformer {
|
|
|
51
58
|
// they may need linking. The data is also not yet available to perform most transformation checks.
|
|
52
59
|
return __classPrivateFieldGet(this, _JavaScriptTransformer_workerPool, "f").run({
|
|
53
60
|
filename,
|
|
54
|
-
...this
|
|
61
|
+
...__classPrivateFieldGet(this, _JavaScriptTransformer_commonOptions, "f"),
|
|
55
62
|
});
|
|
56
63
|
}
|
|
57
64
|
/**
|
|
@@ -66,10 +73,10 @@ class JavaScriptTransformer {
|
|
|
66
73
|
// Perform a quick test to determine if the data needs any transformations.
|
|
67
74
|
// This allows directly returning the data without the worker communication overhead.
|
|
68
75
|
let forceAsyncTransformation;
|
|
69
|
-
if (skipLinker && !this.
|
|
76
|
+
if (skipLinker && !__classPrivateFieldGet(this, _JavaScriptTransformer_commonOptions, "f").advancedOptimizations) {
|
|
70
77
|
// If the linker is being skipped and no optimizations are needed, only async transformation is left.
|
|
71
|
-
// This checks for async generator functions. All other async transformation is handled by esbuild.
|
|
72
|
-
forceAsyncTransformation = data.includes('async') && /async
|
|
78
|
+
// This checks for async generator functions and class methods. All other async transformation is handled by esbuild.
|
|
79
|
+
forceAsyncTransformation = data.includes('async') && /async(?:\s+function)?\s*\*/.test(data);
|
|
73
80
|
if (!forceAsyncTransformation) {
|
|
74
81
|
return Buffer.from(data, 'utf-8');
|
|
75
82
|
}
|
|
@@ -80,7 +87,7 @@ class JavaScriptTransformer {
|
|
|
80
87
|
// Send the async check result if present to avoid rechecking in the worker
|
|
81
88
|
forceAsyncTransformation,
|
|
82
89
|
skipLinker,
|
|
83
|
-
...this
|
|
90
|
+
...__classPrivateFieldGet(this, _JavaScriptTransformer_commonOptions, "f"),
|
|
84
91
|
});
|
|
85
92
|
}
|
|
86
93
|
/**
|
|
@@ -92,4 +99,4 @@ class JavaScriptTransformer {
|
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
exports.JavaScriptTransformer = JavaScriptTransformer;
|
|
95
|
-
_JavaScriptTransformer_workerPool = new WeakMap();
|
|
102
|
+
_JavaScriptTransformer_workerPool = new WeakMap(), _JavaScriptTransformer_commonOptions = new WeakMap();
|
|
@@ -24,8 +24,9 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
24
24
|
cacheOptions: import("../../utils/normalize-cache").NormalizedCachedOptions;
|
|
25
25
|
crossOrigin: import("./schema").CrossOrigin | undefined;
|
|
26
26
|
externalDependencies: string[] | undefined;
|
|
27
|
+
inlineStyleLanguage: string;
|
|
27
28
|
poll: number | undefined;
|
|
28
|
-
preserveSymlinks: boolean
|
|
29
|
+
preserveSymlinks: boolean;
|
|
29
30
|
stylePreprocessorOptions: import("./schema").StylePreprocessorOptions | undefined;
|
|
30
31
|
subresourceIntegrity: boolean | undefined;
|
|
31
32
|
verbose: boolean | undefined;
|
|
@@ -122,7 +122,7 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
// Initial options to keep
|
|
125
|
-
const { baseHref, buildOptimizer, crossOrigin, externalDependencies, poll, preserveSymlinks, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, } = options;
|
|
125
|
+
const { baseHref, buildOptimizer, crossOrigin, externalDependencies, inlineStyleLanguage = 'css', poll, preserveSymlinks, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, } = options;
|
|
126
126
|
// Return all the normalized options
|
|
127
127
|
return {
|
|
128
128
|
advancedOptimizations: buildOptimizer,
|
|
@@ -130,8 +130,10 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
130
130
|
cacheOptions,
|
|
131
131
|
crossOrigin,
|
|
132
132
|
externalDependencies,
|
|
133
|
+
inlineStyleLanguage,
|
|
133
134
|
poll,
|
|
134
|
-
|
|
135
|
+
// If not explicitly set, default to the Node.js process argument
|
|
136
|
+
preserveSymlinks: preserveSymlinks !== null && preserveSymlinks !== void 0 ? preserveSymlinks : process.execArgv.includes('--preserve-symlinks'),
|
|
135
137
|
stylePreprocessorOptions,
|
|
136
138
|
subresourceIntegrity,
|
|
137
139
|
verbose,
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import type { Plugin } from 'esbuild';
|
|
9
|
-
export
|
|
10
|
-
export declare function createSassPlugin(options: {
|
|
9
|
+
export interface SassPluginOptions {
|
|
11
10
|
sourcemap: boolean;
|
|
12
11
|
loadPaths?: string[];
|
|
13
|
-
|
|
12
|
+
inlineComponentData?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export declare function shutdownSassWorkerPool(): void;
|
|
15
|
+
export declare function createSassPlugin(options: SassPluginOptions): Plugin;
|
|
@@ -6,8 +6,12 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
9
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
13
|
exports.createSassPlugin = exports.shutdownSassWorkerPool = void 0;
|
|
14
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
11
15
|
const promises_1 = require("node:fs/promises");
|
|
12
16
|
const node_path_1 = require("node:path");
|
|
13
17
|
const node_url_1 = require("node:url");
|
|
@@ -46,86 +50,95 @@ function createSassPlugin(options) {
|
|
|
46
50
|
}
|
|
47
51
|
return result;
|
|
48
52
|
};
|
|
53
|
+
build.onLoad({ filter: /^angular:styles\/component;s[ac]ss;/, namespace: 'angular:styles/component' }, async (args) => {
|
|
54
|
+
var _a;
|
|
55
|
+
const data = (_a = options.inlineComponentData) === null || _a === void 0 ? void 0 : _a[args.path];
|
|
56
|
+
(0, node_assert_1.default)(data, `component style name should always be found [${args.path}]`);
|
|
57
|
+
const [, language, , filePath] = args.path.split(';', 4);
|
|
58
|
+
const syntax = language === 'sass' ? 'indented' : 'scss';
|
|
59
|
+
return compileString(data, filePath, syntax, options, resolveUrl);
|
|
60
|
+
});
|
|
49
61
|
build.onLoad({ filter: /\.s[ac]ss$/ }, async (args) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
const data = await (0, promises_1.readFile)(args.path, 'utf-8');
|
|
55
|
-
const { css, sourceMap, loadedUrls } = await sassWorkerPool.compileStringAsync(data, {
|
|
56
|
-
url: (0, node_url_1.pathToFileURL)(args.path),
|
|
57
|
-
style: 'expanded',
|
|
58
|
-
loadPaths: options.loadPaths,
|
|
59
|
-
sourceMap: options.sourcemap,
|
|
60
|
-
sourceMapIncludeSources: options.sourcemap,
|
|
61
|
-
quietDeps: true,
|
|
62
|
-
importers: [
|
|
63
|
-
{
|
|
64
|
-
findFileUrl: async (url, { previousResolvedModules }) => {
|
|
65
|
-
const result = await resolveUrl(url, previousResolvedModules);
|
|
66
|
-
// Check for package deep imports
|
|
67
|
-
if (!result.path) {
|
|
68
|
-
const parts = url.split('/');
|
|
69
|
-
const hasScope = parts.length >= 2 && parts[0].startsWith('@');
|
|
70
|
-
const [nameOrScope, nameOrFirstPath, ...pathPart] = parts;
|
|
71
|
-
const packageName = hasScope
|
|
72
|
-
? `${nameOrScope}/${nameOrFirstPath}`
|
|
73
|
-
: nameOrScope;
|
|
74
|
-
const packageResult = await resolveUrl(packageName + '/package.json', previousResolvedModules);
|
|
75
|
-
if (packageResult.path) {
|
|
76
|
-
return (0, node_url_1.pathToFileURL)((0, node_path_1.join)((0, node_path_1.dirname)(packageResult.path), !hasScope ? nameOrFirstPath : '', ...pathPart));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return result.path ? (0, node_url_1.pathToFileURL)(result.path) : null;
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
logger: {
|
|
84
|
-
warn: (text, { deprecation, span }) => {
|
|
85
|
-
warnings.push({
|
|
86
|
-
text: deprecation ? 'Deprecation' : text,
|
|
87
|
-
location: span && {
|
|
88
|
-
file: span.url && (0, node_url_1.fileURLToPath)(span.url),
|
|
89
|
-
lineText: span.context,
|
|
90
|
-
// Sass line numbers are 0-based while esbuild's are 1-based
|
|
91
|
-
line: span.start.line + 1,
|
|
92
|
-
column: span.start.column,
|
|
93
|
-
},
|
|
94
|
-
notes: deprecation ? [{ text }] : undefined,
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
return {
|
|
100
|
-
loader: 'css',
|
|
101
|
-
contents: sourceMap
|
|
102
|
-
? `${css}\n${sourceMapToUrlComment(sourceMap, (0, node_path_1.dirname)(args.path))}`
|
|
103
|
-
: css,
|
|
104
|
-
watchFiles: loadedUrls.map((url) => (0, node_url_1.fileURLToPath)(url)),
|
|
105
|
-
warnings,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
if (isSassException(error)) {
|
|
110
|
-
const file = error.span.url ? (0, node_url_1.fileURLToPath)(error.span.url) : undefined;
|
|
111
|
-
return {
|
|
112
|
-
loader: 'css',
|
|
113
|
-
errors: [
|
|
114
|
-
{
|
|
115
|
-
text: error.message,
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
warnings,
|
|
119
|
-
watchFiles: file ? [file] : undefined,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
62
|
+
const data = await (0, promises_1.readFile)(args.path, 'utf-8');
|
|
63
|
+
const syntax = (0, node_path_1.extname)(args.path).toLowerCase() === '.sass' ? 'indented' : 'scss';
|
|
64
|
+
return compileString(data, args.path, syntax, options, resolveUrl);
|
|
124
65
|
});
|
|
125
66
|
},
|
|
126
67
|
};
|
|
127
68
|
}
|
|
128
69
|
exports.createSassPlugin = createSassPlugin;
|
|
70
|
+
async function compileString(data, filePath, syntax, options, resolveUrl) {
|
|
71
|
+
// Lazily load Sass when a Sass file is found
|
|
72
|
+
sassWorkerPool !== null && sassWorkerPool !== void 0 ? sassWorkerPool : (sassWorkerPool = new sass_service_1.SassWorkerImplementation(true));
|
|
73
|
+
const warnings = [];
|
|
74
|
+
try {
|
|
75
|
+
const { css, sourceMap, loadedUrls } = await sassWorkerPool.compileStringAsync(data, {
|
|
76
|
+
url: (0, node_url_1.pathToFileURL)(filePath),
|
|
77
|
+
style: 'expanded',
|
|
78
|
+
syntax,
|
|
79
|
+
loadPaths: options.loadPaths,
|
|
80
|
+
sourceMap: options.sourcemap,
|
|
81
|
+
sourceMapIncludeSources: options.sourcemap,
|
|
82
|
+
quietDeps: true,
|
|
83
|
+
importers: [
|
|
84
|
+
{
|
|
85
|
+
findFileUrl: async (url, { previousResolvedModules }) => {
|
|
86
|
+
const result = await resolveUrl(url, previousResolvedModules);
|
|
87
|
+
// Check for package deep imports
|
|
88
|
+
if (!result.path) {
|
|
89
|
+
const parts = url.split('/');
|
|
90
|
+
const hasScope = parts.length >= 2 && parts[0].startsWith('@');
|
|
91
|
+
const [nameOrScope, nameOrFirstPath, ...pathPart] = parts;
|
|
92
|
+
const packageName = hasScope ? `${nameOrScope}/${nameOrFirstPath}` : nameOrScope;
|
|
93
|
+
const packageResult = await resolveUrl(packageName + '/package.json', previousResolvedModules);
|
|
94
|
+
if (packageResult.path) {
|
|
95
|
+
return (0, node_url_1.pathToFileURL)((0, node_path_1.join)((0, node_path_1.dirname)(packageResult.path), !hasScope ? nameOrFirstPath : '', ...pathPart));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result.path ? (0, node_url_1.pathToFileURL)(result.path) : null;
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
logger: {
|
|
103
|
+
warn: (text, { deprecation, span }) => {
|
|
104
|
+
warnings.push({
|
|
105
|
+
text: deprecation ? 'Deprecation' : text,
|
|
106
|
+
location: span && {
|
|
107
|
+
file: span.url && (0, node_url_1.fileURLToPath)(span.url),
|
|
108
|
+
lineText: span.context,
|
|
109
|
+
// Sass line numbers are 0-based while esbuild's are 1-based
|
|
110
|
+
line: span.start.line + 1,
|
|
111
|
+
column: span.start.column,
|
|
112
|
+
},
|
|
113
|
+
notes: deprecation ? [{ text }] : undefined,
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
loader: 'css',
|
|
120
|
+
contents: sourceMap ? `${css}\n${sourceMapToUrlComment(sourceMap, (0, node_path_1.dirname)(filePath))}` : css,
|
|
121
|
+
watchFiles: loadedUrls.map((url) => (0, node_url_1.fileURLToPath)(url)),
|
|
122
|
+
warnings,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (isSassException(error)) {
|
|
127
|
+
const file = error.span.url ? (0, node_url_1.fileURLToPath)(error.span.url) : undefined;
|
|
128
|
+
return {
|
|
129
|
+
loader: 'css',
|
|
130
|
+
errors: [
|
|
131
|
+
{
|
|
132
|
+
text: error.message,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
warnings,
|
|
136
|
+
watchFiles: file ? [file] : undefined,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
129
142
|
function sourceMapToUrlComment(sourceMap, root) {
|
|
130
143
|
// Remove `file` protocol from all sourcemap sources and adjust to be relative to the input file.
|
|
131
144
|
// This allows esbuild to correctly process the paths.
|
|
@@ -19,36 +19,24 @@ export interface BundleStylesheetOptions {
|
|
|
19
19
|
externalDependencies?: string[];
|
|
20
20
|
target: string[];
|
|
21
21
|
}
|
|
22
|
-
export declare function createStylesheetBundleOptions(options: BundleStylesheetOptions): BuildOptions & {
|
|
22
|
+
export declare function createStylesheetBundleOptions(options: BundleStylesheetOptions, inlineComponentData?: Record<string, string>): BuildOptions & {
|
|
23
23
|
plugins: NonNullable<BuildOptions['plugins']>;
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Bundles a component stylesheet. The stylesheet can be either an inline stylesheet that
|
|
27
|
+
* is contained within the Component's metadata definition or an external file referenced
|
|
28
|
+
* from the Component's metadata definition.
|
|
27
29
|
*
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
30
|
-
* @
|
|
30
|
+
* @param identifier A unique string identifier for the component stylesheet.
|
|
31
|
+
* @param language The language of the stylesheet such as `css` or `scss`.
|
|
32
|
+
* @param data The string content of the stylesheet.
|
|
33
|
+
* @param filename The filename representing the source of the stylesheet content.
|
|
34
|
+
* @param inline If true, the stylesheet source is within the component metadata;
|
|
35
|
+
* if false, the source is a stylesheet file.
|
|
36
|
+
* @param options An object containing the stylesheet bundling options.
|
|
37
|
+
* @returns An object containing the output of the bundling operation.
|
|
31
38
|
*/
|
|
32
|
-
export declare function
|
|
33
|
-
errors: import("esbuild").Message[];
|
|
34
|
-
warnings: import("esbuild").Message[];
|
|
35
|
-
contents: string;
|
|
36
|
-
map: string | undefined;
|
|
37
|
-
path: string | undefined;
|
|
38
|
-
resourceFiles: OutputFile[];
|
|
39
|
-
}>;
|
|
40
|
-
/**
|
|
41
|
-
* Bundle stylesheet text data from a string.
|
|
42
|
-
*
|
|
43
|
-
* @param data The string content of a stylesheet to bundle.
|
|
44
|
-
* @param dataOptions The options to use to resolve references and name output of the stylesheet data.
|
|
45
|
-
* @param bundleOptions The stylesheet bundling options to use.
|
|
46
|
-
* @returns The bundle result object.
|
|
47
|
-
*/
|
|
48
|
-
export declare function bundleStylesheetText(data: string, dataOptions: {
|
|
49
|
-
resolvePath: string;
|
|
50
|
-
virtualName?: string;
|
|
51
|
-
}, bundleOptions: BundleStylesheetOptions): Promise<{
|
|
39
|
+
export declare function bundleComponentStylesheet(identifier: string, language: string, data: string, filename: string, inline: boolean, options: BundleStylesheetOptions): Promise<{
|
|
52
40
|
errors: import("esbuild").Message[];
|
|
53
41
|
warnings: import("esbuild").Message[];
|
|
54
42
|
contents: string;
|
|
@@ -30,12 +30,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.
|
|
34
|
-
const path = __importStar(require("path"));
|
|
33
|
+
exports.bundleComponentStylesheet = exports.createStylesheetBundleOptions = void 0;
|
|
34
|
+
const path = __importStar(require("node:path"));
|
|
35
35
|
const css_resource_plugin_1 = require("./css-resource-plugin");
|
|
36
36
|
const esbuild_1 = require("./esbuild");
|
|
37
37
|
const sass_plugin_1 = require("./sass-plugin");
|
|
38
|
-
function createStylesheetBundleOptions(options) {
|
|
38
|
+
function createStylesheetBundleOptions(options, inlineComponentData) {
|
|
39
39
|
var _a, _b;
|
|
40
40
|
return {
|
|
41
41
|
absWorkingDir: options.workspaceRoot,
|
|
@@ -54,18 +54,65 @@ function createStylesheetBundleOptions(options) {
|
|
|
54
54
|
conditions: ['style', 'sass'],
|
|
55
55
|
mainFields: ['style', 'sass'],
|
|
56
56
|
plugins: [
|
|
57
|
-
(0, sass_plugin_1.createSassPlugin)({
|
|
57
|
+
(0, sass_plugin_1.createSassPlugin)({
|
|
58
|
+
sourcemap: !!options.sourcemap,
|
|
59
|
+
loadPaths: options.includePaths,
|
|
60
|
+
inlineComponentData,
|
|
61
|
+
}),
|
|
58
62
|
(0, css_resource_plugin_1.createCssResourcePlugin)(),
|
|
59
63
|
],
|
|
60
64
|
};
|
|
61
65
|
}
|
|
62
66
|
exports.createStylesheetBundleOptions = createStylesheetBundleOptions;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Bundles a component stylesheet. The stylesheet can be either an inline stylesheet that
|
|
69
|
+
* is contained within the Component's metadata definition or an external file referenced
|
|
70
|
+
* from the Component's metadata definition.
|
|
71
|
+
*
|
|
72
|
+
* @param identifier A unique string identifier for the component stylesheet.
|
|
73
|
+
* @param language The language of the stylesheet such as `css` or `scss`.
|
|
74
|
+
* @param data The string content of the stylesheet.
|
|
75
|
+
* @param filename The filename representing the source of the stylesheet content.
|
|
76
|
+
* @param inline If true, the stylesheet source is within the component metadata;
|
|
77
|
+
* if false, the source is a stylesheet file.
|
|
78
|
+
* @param options An object containing the stylesheet bundling options.
|
|
79
|
+
* @returns An object containing the output of the bundling operation.
|
|
80
|
+
*/
|
|
81
|
+
async function bundleComponentStylesheet(identifier, language, data, filename, inline, options) {
|
|
82
|
+
const namespace = 'angular:styles/component';
|
|
83
|
+
const entry = [namespace, language, identifier, filename].join(';');
|
|
84
|
+
const buildOptions = createStylesheetBundleOptions(options, { [entry]: data });
|
|
85
|
+
buildOptions.entryPoints = [entry];
|
|
86
|
+
buildOptions.plugins.push({
|
|
87
|
+
name: 'angular-component-styles',
|
|
88
|
+
setup(build) {
|
|
89
|
+
build.onResolve({ filter: /^angular:styles\/component;/ }, (args) => {
|
|
90
|
+
if (args.kind !== 'entry-point') {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
if (inline) {
|
|
94
|
+
return {
|
|
95
|
+
path: args.path,
|
|
96
|
+
namespace,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return {
|
|
101
|
+
path: filename,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
build.onLoad({ filter: /^angular:styles\/component;css;/, namespace }, async () => {
|
|
106
|
+
return {
|
|
107
|
+
contents: data,
|
|
108
|
+
loader: 'css',
|
|
109
|
+
resolveDir: path.dirname(filename),
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
},
|
|
68
113
|
});
|
|
114
|
+
// Execute esbuild
|
|
115
|
+
const result = await (0, esbuild_1.bundle)(options.workspaceRoot, buildOptions);
|
|
69
116
|
// Extract the result of the bundling from the output files
|
|
70
117
|
let contents = '';
|
|
71
118
|
let map;
|
|
@@ -96,34 +143,4 @@ async function bundleStylesheet(entry, options) {
|
|
|
96
143
|
resourceFiles,
|
|
97
144
|
};
|
|
98
145
|
}
|
|
99
|
-
|
|
100
|
-
* Bundle a stylesheet that exists as a file on the filesystem.
|
|
101
|
-
*
|
|
102
|
-
* @param filename The path to the file to bundle.
|
|
103
|
-
* @param options The stylesheet bundling options to use.
|
|
104
|
-
* @returns The bundle result object.
|
|
105
|
-
*/
|
|
106
|
-
async function bundleStylesheetFile(filename, options) {
|
|
107
|
-
return bundleStylesheet({ entryPoints: [filename] }, options);
|
|
108
|
-
}
|
|
109
|
-
exports.bundleStylesheetFile = bundleStylesheetFile;
|
|
110
|
-
/**
|
|
111
|
-
* Bundle stylesheet text data from a string.
|
|
112
|
-
*
|
|
113
|
-
* @param data The string content of a stylesheet to bundle.
|
|
114
|
-
* @param dataOptions The options to use to resolve references and name output of the stylesheet data.
|
|
115
|
-
* @param bundleOptions The stylesheet bundling options to use.
|
|
116
|
-
* @returns The bundle result object.
|
|
117
|
-
*/
|
|
118
|
-
async function bundleStylesheetText(data, dataOptions, bundleOptions) {
|
|
119
|
-
const result = bundleStylesheet({
|
|
120
|
-
stdin: {
|
|
121
|
-
contents: data,
|
|
122
|
-
sourcefile: dataOptions.virtualName,
|
|
123
|
-
resolveDir: dataOptions.resolvePath,
|
|
124
|
-
loader: 'css',
|
|
125
|
-
},
|
|
126
|
-
}, bundleOptions);
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
exports.bundleStylesheetText = bundleStylesheetText;
|
|
146
|
+
exports.bundleComponentStylesheet = bundleComponentStylesheet;
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
// import type ng from '@angular/compiler-cli';
|
|
10
|
+
// import { Worker } from 'node:worker_threads';
|
|
11
|
+
// import { AngularHostOptions } from './angular-host';
|
|
12
|
+
// interface Message {
|
|
13
|
+
// id: number;
|
|
14
|
+
// }
|
|
15
|
+
// interface InitializeRequest extends Message {
|
|
16
|
+
// tsconfig: string;
|
|
17
|
+
// tsCallbackId: number;
|
|
18
|
+
// tcoCallbackId?: number;
|
|
19
|
+
// }
|
|
20
|
+
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
// type ResponseCallback = (...args: any[]) => void;
|
|
22
|
+
// let callbackIds = 0;
|
|
23
|
+
// export class WorkerAngularCompilation {
|
|
24
|
+
// #worker: Worker;
|
|
25
|
+
// #callbacks = new Map<number, ResponseCallback>();
|
|
26
|
+
// constructor() {
|
|
27
|
+
// this.#worker = new Worker(require.resolve('./compilation-worker'));
|
|
28
|
+
// }
|
|
29
|
+
// async initialize(
|
|
30
|
+
// tsconfig: string,
|
|
31
|
+
// hostOptions: AngularHostOptions,
|
|
32
|
+
// transformCompilerOptions?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions,
|
|
33
|
+
// ): Promise<{ compilerOptions: ng.CompilerOptions }> {
|
|
34
|
+
// const request: InitializeRequest = {
|
|
35
|
+
// id: ++callbackIds,
|
|
36
|
+
// tsconfig,
|
|
37
|
+
// tsCallbackId: ++callbackIds,
|
|
38
|
+
// };
|
|
39
|
+
// this.#callbacks.set(request.tsCallbackId, () => {
|
|
40
|
+
// hostOptions.transformStylesheet();
|
|
41
|
+
// });
|
|
42
|
+
// if (transformCompilerOptions) {
|
|
43
|
+
// request.tcoCallbackId = ++callbackIds;
|
|
44
|
+
// this.#callbacks.set(request.tcoCallbackId, (id: number, compilerOptions) => {
|
|
45
|
+
// try {
|
|
46
|
+
// transformCompilerOptions(compilerOptions);
|
|
47
|
+
// } catch (e) {
|
|
48
|
+
// }
|
|
49
|
+
// });
|
|
50
|
+
// }
|
|
51
|
+
// const result = new Promise<{ compilerOptions: ng.CompilerOptions }>((resolve, reject) => {
|
|
52
|
+
// this.#callbacks.set(request.id, () => {
|
|
53
|
+
// resolve({});
|
|
54
|
+
// });
|
|
55
|
+
// });
|
|
56
|
+
// this.#worker.postMessage(request);
|
|
57
|
+
// return result;
|
|
58
|
+
// }
|
|
59
|
+
// }
|
|
@@ -149,7 +149,9 @@ function execute(options, context, transforms = {}) {
|
|
|
149
149
|
});
|
|
150
150
|
const karmaStart = karmaServer.start();
|
|
151
151
|
// Cleanup, signal Karma to exit.
|
|
152
|
-
return () =>
|
|
152
|
+
return () => {
|
|
153
|
+
void karmaStart.then(() => karmaServer.stop());
|
|
154
|
+
};
|
|
153
155
|
})), (0, operators_1.defaultIfEmpty)({ success: false }));
|
|
154
156
|
}
|
|
155
157
|
exports.execute = execute;
|
|
@@ -15,9 +15,18 @@ exports.transformSupportedBrowsersToTargets = void 0;
|
|
|
15
15
|
function transformSupportedBrowsersToTargets(supportedBrowsers) {
|
|
16
16
|
const transformed = [];
|
|
17
17
|
// https://esbuild.github.io/api/#target
|
|
18
|
-
const esBuildSupportedBrowsers = new Set([
|
|
18
|
+
const esBuildSupportedBrowsers = new Set([
|
|
19
|
+
'chrome',
|
|
20
|
+
'edge',
|
|
21
|
+
'firefox',
|
|
22
|
+
'ie',
|
|
23
|
+
'ios',
|
|
24
|
+
'node',
|
|
25
|
+
'opera',
|
|
26
|
+
'safari',
|
|
27
|
+
]);
|
|
19
28
|
for (const browser of supportedBrowsers) {
|
|
20
|
-
let [browserName, version] = browser.split(' ');
|
|
29
|
+
let [browserName, version] = browser.toLowerCase().split(' ');
|
|
21
30
|
// browserslist uses the name `ios_saf` for iOS Safari whereas esbuild uses `ios`
|
|
22
31
|
if (browserName === 'ios_saf') {
|
|
23
32
|
browserName = 'ios';
|
|
@@ -31,6 +40,12 @@ function transformSupportedBrowsersToTargets(supportedBrowsers) {
|
|
|
31
40
|
// a Technology Preview (TP) of Safari is assumed to support all currently known features.
|
|
32
41
|
version = '999';
|
|
33
42
|
}
|
|
43
|
+
else if (!version.includes('.')) {
|
|
44
|
+
// A lone major version is considered by esbuild to include all minor versions. However,
|
|
45
|
+
// browserslist does not and is also inconsistent in its `.0` version naming. For example,
|
|
46
|
+
// Safari 15.0 is named `safari 15` but Safari 16.0 is named `safari 16.0`.
|
|
47
|
+
version += '.0';
|
|
48
|
+
}
|
|
34
49
|
transformed.push(browserName + version);
|
|
35
50
|
}
|
|
36
51
|
}
|
|
@@ -52,7 +52,7 @@ function emittedFilesToInlineOptions(emittedFiles, scriptsEntryPointName, emitte
|
|
|
52
52
|
code: fs.readFileSync(originalPath, 'utf8'),
|
|
53
53
|
outputPath,
|
|
54
54
|
missingTranslation,
|
|
55
|
-
setLocale: emittedFile.name === 'main'
|
|
55
|
+
setLocale: emittedFile.name === 'main',
|
|
56
56
|
};
|
|
57
57
|
originalFiles.push(originalPath);
|
|
58
58
|
try {
|
|
@@ -125,7 +125,7 @@ async function augmentIndexHtml(params) {
|
|
|
125
125
|
}
|
|
126
126
|
rewriter.emitEndTag(tag);
|
|
127
127
|
});
|
|
128
|
-
const content = await transformedContent;
|
|
128
|
+
const content = await transformedContent();
|
|
129
129
|
return {
|
|
130
130
|
content: linkTags.length || scriptTags.length
|
|
131
131
|
? // In case no body/head tags are not present (dotnet partial templates)
|
|
@@ -37,26 +37,30 @@ async function htmlRewritingStream(content) {
|
|
|
37
37
|
const rewriter = new (await Promise.resolve().then(() => __importStar(require('parse5-html-rewriting-stream')))).default();
|
|
38
38
|
return {
|
|
39
39
|
rewriter,
|
|
40
|
-
transformedContent:
|
|
41
|
-
new
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
40
|
+
transformedContent: () => {
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
new stream_1.Readable({
|
|
43
|
+
encoding: 'utf8',
|
|
44
|
+
read() {
|
|
45
|
+
this.push(Buffer.from(content));
|
|
46
|
+
this.push(null);
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
.pipe(rewriter)
|
|
50
|
+
.pipe(new stream_1.Writable({
|
|
51
|
+
write(chunk, encoding, callback) {
|
|
52
|
+
chunks.push(typeof chunk === 'string'
|
|
53
|
+
? Buffer.from(chunk, encoding)
|
|
54
|
+
: chunk);
|
|
55
|
+
callback();
|
|
56
|
+
},
|
|
57
|
+
final(callback) {
|
|
58
|
+
callback();
|
|
59
|
+
resolve(Buffer.concat(chunks).toString());
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
62
|
+
});
|
|
63
|
+
},
|
|
60
64
|
};
|
|
61
65
|
}
|
|
62
66
|
exports.htmlRewritingStream = htmlRewritingStream;
|
|
@@ -63,7 +63,7 @@ class InlineFontsProcessor {
|
|
|
63
63
|
const hrefList = [];
|
|
64
64
|
const existingPreconnect = new Set();
|
|
65
65
|
// Collector link tags with href
|
|
66
|
-
const { rewriter: collectorStream } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
|
|
66
|
+
const { rewriter: collectorStream, transformedContent: initCollectorStream } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
|
|
67
67
|
collectorStream.on('startTag', (tag) => {
|
|
68
68
|
const { tagName, attrs } = tag;
|
|
69
69
|
if (tagName !== 'link') {
|
|
@@ -95,6 +95,10 @@ class InlineFontsProcessor {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
});
|
|
98
|
+
initCollectorStream().catch(() => {
|
|
99
|
+
// We don't really care about any errors here because it just initializes
|
|
100
|
+
// the rewriting stream, as we are waiting for `finish` below.
|
|
101
|
+
});
|
|
98
102
|
await new Promise((resolve) => collectorStream.on('finish', resolve));
|
|
99
103
|
// Download stylesheets
|
|
100
104
|
const hrefsContent = new Map();
|
|
@@ -146,7 +150,7 @@ class InlineFontsProcessor {
|
|
|
146
150
|
break;
|
|
147
151
|
}
|
|
148
152
|
});
|
|
149
|
-
return transformedContent;
|
|
153
|
+
return transformedContent();
|
|
150
154
|
}
|
|
151
155
|
async getResponse(url) {
|
|
152
156
|
var _a;
|
|
@@ -211,7 +211,7 @@ async function inlineLocalesDirect(ast, options) {
|
|
|
211
211
|
}
|
|
212
212
|
let outputSource = content;
|
|
213
213
|
if (options.setLocale) {
|
|
214
|
-
const setLocaleText = `
|
|
214
|
+
const setLocaleText = `globalThis.$localize=Object.assign(globalThis.$localize || {},{locale:"${locale}"});\n`;
|
|
215
215
|
// If locale data is provided, load it and prepend to file
|
|
216
216
|
let localeDataSource;
|
|
217
217
|
const localeDataPath = i18n.locales[locale] && i18n.locales[locale].dataPath;
|
|
@@ -90,8 +90,9 @@ async function optimizeWithTerser(name, code, sourcemaps, advanced) {
|
|
|
90
90
|
passes: advanced ? 2 : 1,
|
|
91
91
|
pure_getters: advanced,
|
|
92
92
|
},
|
|
93
|
-
//
|
|
94
|
-
|
|
93
|
+
// Set to ES2015 to prevent higher level features from being introduced when browserslist
|
|
94
|
+
// contains older browsers. The build system requires browsers to support ES2015 at a minimum.
|
|
95
|
+
ecma: 2015,
|
|
95
96
|
// esbuild in the first pass is used to minify identifiers instead of mangle here
|
|
96
97
|
mangle: false,
|
|
97
98
|
// esbuild in the first pass is used to minify function names
|
|
@@ -24,8 +24,6 @@ class StylesWebpackPlugin {
|
|
|
24
24
|
}
|
|
25
25
|
apply(compiler) {
|
|
26
26
|
const { entryPoints, preserveSymlinks, root } = this.options;
|
|
27
|
-
const webpackOptions = compiler.options;
|
|
28
|
-
const entry = typeof webpackOptions.entry === 'function' ? webpackOptions.entry() : webpackOptions.entry;
|
|
29
27
|
const resolver = compiler.resolverFactory.get('global-styles', {
|
|
30
28
|
conditionNames: ['sass', 'less', 'style'],
|
|
31
29
|
mainFields: ['sass', 'less', 'style', 'main', '...'],
|
|
@@ -36,33 +34,37 @@ class StylesWebpackPlugin {
|
|
|
36
34
|
symlinks: !preserveSymlinks,
|
|
37
35
|
fileSystem: compiler.inputFileSystem,
|
|
38
36
|
});
|
|
39
|
-
webpackOptions
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
for (const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
37
|
+
const webpackOptions = compiler.options;
|
|
38
|
+
compiler.hooks.environment.tap(PLUGIN_NAME, () => {
|
|
39
|
+
const entry = typeof webpackOptions.entry === 'function' ? webpackOptions.entry() : webpackOptions.entry;
|
|
40
|
+
webpackOptions.entry = async () => {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
var _c;
|
|
43
|
+
const entrypoints = await entry;
|
|
44
|
+
for (const [bundleName, paths] of Object.entries(entryPoints)) {
|
|
45
|
+
(_a = entrypoints[bundleName]) !== null && _a !== void 0 ? _a : (entrypoints[bundleName] = {});
|
|
46
|
+
const entryImport = ((_b = (_c = entrypoints[bundleName]).import) !== null && _b !== void 0 ? _b : (_c.import = []));
|
|
47
|
+
for (const path of paths) {
|
|
48
|
+
try {
|
|
49
|
+
const resolvedPath = resolver.resolveSync({}, root, path);
|
|
50
|
+
if (resolvedPath) {
|
|
51
|
+
entryImport.push(`${resolvedPath}?ngGlobalStyle`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
(0, assert_1.default)(this.compilation, 'Compilation cannot be undefined.');
|
|
55
|
+
(0, webpack_diagnostics_1.addError)(this.compilation, `Cannot resolve '${path}'.`);
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
|
-
|
|
58
|
+
catch (error) {
|
|
53
59
|
(0, assert_1.default)(this.compilation, 'Compilation cannot be undefined.');
|
|
54
|
-
(0,
|
|
60
|
+
(0, error_1.assertIsError)(error);
|
|
61
|
+
(0, webpack_diagnostics_1.addError)(this.compilation, error.message);
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
(0, assert_1.default)(this.compilation, 'Compilation cannot be undefined.');
|
|
59
|
-
(0, error_1.assertIsError)(error);
|
|
60
|
-
(0, webpack_diagnostics_1.addError)(this.compilation, error.message);
|
|
61
|
-
}
|
|
62
64
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
};
|
|
65
|
+
return entrypoints;
|
|
66
|
+
};
|
|
67
|
+
});
|
|
66
68
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
67
69
|
this.compilation = compilation;
|
|
68
70
|
});
|