@angular-devkit/build-angular 15.0.0-next.3 → 15.0.0-next.5
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 +19 -18
- package/src/builders/app-shell/index.js +39 -40
- package/src/builders/app-shell/render-worker.d.ts +36 -0
- package/src/builders/app-shell/render-worker.js +82 -0
- package/src/builders/browser/index.d.ts +2 -0
- package/src/builders/browser/index.js +38 -19
- package/src/builders/browser/schema.json +2 -2
- package/src/builders/browser-esbuild/compiler-plugin.d.ts +10 -2
- package/src/builders/browser-esbuild/compiler-plugin.js +211 -115
- package/src/builders/browser-esbuild/esbuild.d.ts +4 -3
- package/src/builders/browser-esbuild/esbuild.js +12 -6
- package/src/builders/browser-esbuild/experimental-warnings.js +0 -3
- package/src/builders/browser-esbuild/index.d.ts +3 -3
- package/src/builders/browser-esbuild/index.js +145 -87
- package/src/builders/browser-esbuild/options.d.ts +26 -4
- package/src/builders/browser-esbuild/options.js +56 -5
- package/src/builders/browser-esbuild/profiling.d.ts +11 -0
- package/src/builders/browser-esbuild/profiling.js +64 -0
- package/src/builders/browser-esbuild/sass-plugin.js +11 -5
- package/src/builders/browser-esbuild/schema.json +2 -2
- package/src/builders/browser-esbuild/watcher.d.ts +23 -0
- package/src/builders/browser-esbuild/watcher.js +93 -0
- package/src/builders/dev-server/index.d.ts +2 -0
- package/src/builders/dev-server/index.js +10 -7
- package/src/builders/karma/find-tests-plugin.js +1 -0
- package/src/builders/karma/index.d.ts +1 -1
- package/src/builders/karma/index.js +50 -9
- package/src/builders/karma/schema.d.ts +1 -1
- package/src/builders/karma/schema.json +1 -1
- package/src/builders/server/schema.json +1 -1
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +3 -1
- package/src/utils/process-bundle.js +1 -1
- package/src/utils/service-worker.d.ts +3 -0
- package/src/utils/service-worker.js +29 -2
- package/src/webpack/configs/common.js +31 -7
- package/src/webpack/configs/index.d.ts +0 -1
- package/src/webpack/configs/index.js +0 -1
- package/src/webpack/configs/styles.d.ts +1 -7
- package/src/webpack/configs/styles.js +70 -60
- package/src/webpack/plugins/occurrences-plugin.d.ts +18 -0
- package/src/webpack/plugins/occurrences-plugin.js +79 -0
- package/src/webpack/plugins/scripts-webpack-plugin.js +24 -5
- package/src/webpack/plugins/styles-webpack-plugin.d.ts +19 -0
- package/src/webpack/plugins/styles-webpack-plugin.js +71 -0
- package/src/webpack/utils/helpers.d.ts +5 -1
- package/src/webpack/utils/helpers.js +24 -14
- package/src/webpack/utils/stats.d.ts +13 -8
- package/src/webpack/utils/stats.js +57 -6
- package/src/webpack/configs/analytics.d.ts +0 -11
- package/src/webpack/configs/analytics.js +0 -27
- package/src/webpack/plugins/analytics.d.ts +0 -66
- package/src/webpack/plugins/analytics.js +0 -236
|
@@ -33,67 +33,62 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
33
33
|
exports.buildEsbuildBrowser = void 0;
|
|
34
34
|
const architect_1 = require("@angular-devkit/architect");
|
|
35
35
|
const assert = __importStar(require("assert"));
|
|
36
|
-
const
|
|
36
|
+
const fs = __importStar(require("fs/promises"));
|
|
37
37
|
const path = __importStar(require("path"));
|
|
38
38
|
const utils_1 = require("../../utils");
|
|
39
39
|
const copy_assets_1 = require("../../utils/copy-assets");
|
|
40
40
|
const error_1 = require("../../utils/error");
|
|
41
41
|
const esbuild_targets_1 = require("../../utils/esbuild-targets");
|
|
42
42
|
const index_html_generator_1 = require("../../utils/index-file/index-html-generator");
|
|
43
|
-
const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
|
|
44
43
|
const service_worker_1 = require("../../utils/service-worker");
|
|
45
44
|
const supported_browsers_1 = require("../../utils/supported-browsers");
|
|
46
|
-
const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
|
|
47
|
-
const configs_1 = require("../../webpack/configs");
|
|
48
45
|
const compiler_plugin_1 = require("./compiler-plugin");
|
|
49
46
|
const esbuild_1 = require("./esbuild");
|
|
50
47
|
const experimental_warnings_1 = require("./experimental-warnings");
|
|
51
48
|
const options_1 = require("./options");
|
|
52
49
|
const stylesheets_1 = require("./stylesheets");
|
|
50
|
+
const watcher_1 = require("./watcher");
|
|
53
51
|
/**
|
|
54
|
-
*
|
|
55
|
-
* The options are compatible with the Webpack-based builder.
|
|
56
|
-
* @param options The browser builder options to use when setting up the application build
|
|
57
|
-
* @param context The Architect builder context object
|
|
58
|
-
* @returns A promise with the builder result output
|
|
52
|
+
* Represents the result of a single builder execute call.
|
|
59
53
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (options.aot !== true) {
|
|
66
|
-
context.logger.error('JIT mode is currently not supported by this experimental builder. AOT mode must be used.');
|
|
67
|
-
return { success: false };
|
|
54
|
+
class ExecutionResult {
|
|
55
|
+
constructor(success, codeRebuild, codeBundleCache) {
|
|
56
|
+
this.success = success;
|
|
57
|
+
this.codeRebuild = codeRebuild;
|
|
58
|
+
this.codeBundleCache = codeBundleCache;
|
|
68
59
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!projectName) {
|
|
74
|
-
context.logger.error(`The 'browser-esbuild' builder requires a target to be specified.`);
|
|
75
|
-
return { success: false };
|
|
60
|
+
get output() {
|
|
61
|
+
return {
|
|
62
|
+
success: this.success,
|
|
63
|
+
};
|
|
76
64
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
65
|
+
createRebuildState(fileChanges) {
|
|
66
|
+
var _a;
|
|
67
|
+
(_a = this.codeBundleCache) === null || _a === void 0 ? void 0 : _a.invalidate([...fileChanges.modified, ...fileChanges.removed]);
|
|
68
|
+
return {
|
|
69
|
+
codeRebuild: this.codeRebuild,
|
|
70
|
+
codeBundleCache: this.codeBundleCache,
|
|
71
|
+
fileChanges,
|
|
72
|
+
};
|
|
81
73
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
(0, error_1.assertIsError)(e);
|
|
88
|
-
context.logger.error('Unable to create output directory: ' + e.message);
|
|
89
|
-
return { success: false };
|
|
74
|
+
dispose() {
|
|
75
|
+
var _a;
|
|
76
|
+
(_a = this.codeRebuild) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
90
77
|
}
|
|
78
|
+
}
|
|
79
|
+
async function execute(options, context, rebuildState) {
|
|
80
|
+
var _a, _b, _c, _d;
|
|
81
|
+
const startTime = process.hrtime.bigint();
|
|
82
|
+
const { projectRoot, workspaceRoot, optimizationOptions, outputPath, assets, serviceWorkerOptions, indexHtmlOptions, } = options;
|
|
91
83
|
const target = (0, esbuild_targets_1.transformSupportedBrowsersToTargets)((0, supported_browsers_1.getSupportedBrowsers)(projectRoot, context.logger));
|
|
84
|
+
const codeBundleCache = options.watch
|
|
85
|
+
? (_a = rebuildState === null || rebuildState === void 0 ? void 0 : rebuildState.codeBundleCache) !== null && _a !== void 0 ? _a : new compiler_plugin_1.SourceFileCache()
|
|
86
|
+
: undefined;
|
|
92
87
|
const [codeResults, styleResults] = await Promise.all([
|
|
93
88
|
// Execute esbuild to bundle the application code
|
|
94
|
-
|
|
89
|
+
(0, esbuild_1.bundle)((_b = rebuildState === null || rebuildState === void 0 ? void 0 : rebuildState.codeRebuild) !== null && _b !== void 0 ? _b : createCodeBundleOptions(options, target, codeBundleCache)),
|
|
95
90
|
// Execute esbuild to bundle the global stylesheets
|
|
96
|
-
bundleGlobalStylesheets(
|
|
91
|
+
bundleGlobalStylesheets(options, target),
|
|
97
92
|
]);
|
|
98
93
|
// Log all warnings and errors generated during bundling
|
|
99
94
|
await (0, esbuild_1.logMessages)(context, {
|
|
@@ -102,7 +97,7 @@ async function buildEsbuildBrowser(options, context) {
|
|
|
102
97
|
});
|
|
103
98
|
// Return if the bundling failed to generate output files or there are errors
|
|
104
99
|
if (!codeResults.outputFiles || codeResults.errors.length) {
|
|
105
|
-
return
|
|
100
|
+
return new ExecutionResult(false, rebuildState === null || rebuildState === void 0 ? void 0 : rebuildState.codeRebuild, codeBundleCache);
|
|
106
101
|
}
|
|
107
102
|
// Structure the code bundling output files
|
|
108
103
|
const initialFiles = [];
|
|
@@ -110,13 +105,14 @@ async function buildEsbuildBrowser(options, context) {
|
|
|
110
105
|
for (const outputFile of codeResults.outputFiles) {
|
|
111
106
|
// Entries in the metafile are relative to the `absWorkingDir` option which is set to the workspaceRoot
|
|
112
107
|
const relativeFilePath = path.relative(workspaceRoot, outputFile.path);
|
|
113
|
-
const entryPoint = (
|
|
108
|
+
const entryPoint = (_d = (_c = codeResults.metafile) === null || _c === void 0 ? void 0 : _c.outputs[relativeFilePath]) === null || _d === void 0 ? void 0 : _d.entryPoint;
|
|
114
109
|
outputFile.path = relativeFilePath;
|
|
115
110
|
if (entryPoint) {
|
|
116
111
|
// An entryPoint value indicates an initial file
|
|
117
112
|
initialFiles.push({
|
|
118
113
|
file: outputFile.path,
|
|
119
|
-
|
|
114
|
+
// The first part of the filename is the name of file (e.g., "polyfills" for "polyfills.7S5G3MDY.js")
|
|
115
|
+
name: path.basename(outputFile.path).split('.')[0],
|
|
120
116
|
extension: path.extname(outputFile.path),
|
|
121
117
|
});
|
|
122
118
|
}
|
|
@@ -127,18 +123,14 @@ async function buildEsbuildBrowser(options, context) {
|
|
|
127
123
|
initialFiles.push(...styleResults.initialFiles);
|
|
128
124
|
// Return if the global stylesheet bundling has errors
|
|
129
125
|
if (styleResults.errors.length) {
|
|
130
|
-
return
|
|
126
|
+
return new ExecutionResult(false, codeResults.rebuild, codeBundleCache);
|
|
131
127
|
}
|
|
132
128
|
// Generate index HTML file
|
|
133
|
-
if (
|
|
134
|
-
const entrypoints = (0, package_chunk_sort_1.generateEntryPoints)({
|
|
135
|
-
scripts: (_e = options.scripts) !== null && _e !== void 0 ? _e : [],
|
|
136
|
-
styles: (_f = options.styles) !== null && _f !== void 0 ? _f : [],
|
|
137
|
-
});
|
|
129
|
+
if (indexHtmlOptions) {
|
|
138
130
|
// Create an index HTML generator that reads from the in-memory output files
|
|
139
131
|
const indexHtmlGenerator = new index_html_generator_1.IndexHtmlGenerator({
|
|
140
|
-
indexPath:
|
|
141
|
-
entrypoints,
|
|
132
|
+
indexPath: indexHtmlOptions.input,
|
|
133
|
+
entrypoints: indexHtmlOptions.insertionOrder,
|
|
142
134
|
sri: options.subresourceIntegrity,
|
|
143
135
|
optimization: optimizationOptions,
|
|
144
136
|
crossOrigin: options.crossOrigin,
|
|
@@ -166,29 +158,29 @@ async function buildEsbuildBrowser(options, context) {
|
|
|
166
158
|
for (const warning of warnings) {
|
|
167
159
|
context.logger.warn(warning);
|
|
168
160
|
}
|
|
169
|
-
outputFiles.push(createOutputFileFromText(
|
|
161
|
+
outputFiles.push(createOutputFileFromText(indexHtmlOptions.output, content));
|
|
170
162
|
}
|
|
171
163
|
// Copy assets
|
|
172
164
|
if (assets) {
|
|
173
165
|
await (0, copy_assets_1.copyAssets)(assets, [outputPath], workspaceRoot);
|
|
174
166
|
}
|
|
175
167
|
// Write output files
|
|
176
|
-
await Promise.all(outputFiles.map((file) =>
|
|
168
|
+
await Promise.all(outputFiles.map((file) => fs.writeFile(path.join(outputPath, file.path), file.contents)));
|
|
177
169
|
// Augment the application with service worker support
|
|
178
170
|
// TODO: This should eventually operate on the in-memory files prior to writing the output files
|
|
179
|
-
if (
|
|
171
|
+
if (serviceWorkerOptions) {
|
|
180
172
|
try {
|
|
181
|
-
await (0, service_worker_1.
|
|
173
|
+
await (0, service_worker_1.augmentAppWithServiceWorkerEsbuild)(workspaceRoot, serviceWorkerOptions, outputPath, options.baseHref || '/');
|
|
182
174
|
}
|
|
183
175
|
catch (error) {
|
|
184
176
|
context.logger.error(error instanceof Error ? error.message : `${error}`);
|
|
185
|
-
return
|
|
177
|
+
return new ExecutionResult(false, codeResults.rebuild, codeBundleCache);
|
|
186
178
|
}
|
|
187
179
|
}
|
|
188
|
-
|
|
189
|
-
|
|
180
|
+
const buildTime = Number(process.hrtime.bigint() - startTime) / 10 ** 9;
|
|
181
|
+
context.logger.info(`Complete. [${buildTime.toFixed(3)} seconds]`);
|
|
182
|
+
return new ExecutionResult(true, codeResults.rebuild, codeBundleCache);
|
|
190
183
|
}
|
|
191
|
-
exports.buildEsbuildBrowser = buildEsbuildBrowser;
|
|
192
184
|
function createOutputFileFromText(path, text) {
|
|
193
185
|
return {
|
|
194
186
|
path,
|
|
@@ -198,18 +190,12 @@ function createOutputFileFromText(path, text) {
|
|
|
198
190
|
},
|
|
199
191
|
};
|
|
200
192
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (options.fileReplacements) {
|
|
205
|
-
for (const replacement of options.fileReplacements) {
|
|
206
|
-
fileReplacements !== null && fileReplacements !== void 0 ? fileReplacements : (fileReplacements = {});
|
|
207
|
-
fileReplacements[path.join(workspaceRoot, replacement.replace)] = path.join(workspaceRoot, replacement.with);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return (0, esbuild_1.bundle)({
|
|
193
|
+
function createCodeBundleOptions(options, target, sourceFileCache) {
|
|
194
|
+
const { workspaceRoot, entryPoints, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, } = options;
|
|
195
|
+
return {
|
|
211
196
|
absWorkingDir: workspaceRoot,
|
|
212
197
|
bundle: true,
|
|
198
|
+
incremental: options.watch,
|
|
213
199
|
format: 'esm',
|
|
214
200
|
entryPoints,
|
|
215
201
|
entryNames: outputNames.bundles,
|
|
@@ -234,10 +220,10 @@ async function bundleCode(workspaceRoot, entryPoints, outputNames, options, opti
|
|
|
234
220
|
sourcemap: sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true),
|
|
235
221
|
splitting: true,
|
|
236
222
|
tsconfig,
|
|
237
|
-
external:
|
|
223
|
+
external: externalDependencies,
|
|
238
224
|
write: false,
|
|
239
225
|
platform: 'browser',
|
|
240
|
-
preserveSymlinks
|
|
226
|
+
preserveSymlinks,
|
|
241
227
|
plugins: [
|
|
242
228
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
243
229
|
// JS/TS options
|
|
@@ -245,8 +231,9 @@ async function bundleCode(workspaceRoot, entryPoints, outputNames, options, opti
|
|
|
245
231
|
sourcemap: !!sourcemapOptions.scripts,
|
|
246
232
|
thirdPartySourcemaps: sourcemapOptions.vendor,
|
|
247
233
|
tsconfig,
|
|
248
|
-
advancedOptimizations
|
|
234
|
+
advancedOptimizations,
|
|
249
235
|
fileReplacements,
|
|
236
|
+
sourceFileCache,
|
|
250
237
|
},
|
|
251
238
|
// Component stylesheet options
|
|
252
239
|
{
|
|
@@ -258,8 +245,8 @@ async function bundleCode(workspaceRoot, entryPoints, outputNames, options, opti
|
|
|
258
245
|
// of sourcemap processing.
|
|
259
246
|
!!sourcemapOptions.styles && (sourcemapOptions.hidden ? false : 'inline'),
|
|
260
247
|
outputNames,
|
|
261
|
-
includePaths:
|
|
262
|
-
externalDependencies
|
|
248
|
+
includePaths: stylePreprocessorOptions === null || stylePreprocessorOptions === void 0 ? void 0 : stylePreprocessorOptions.includePaths,
|
|
249
|
+
externalDependencies,
|
|
263
250
|
target,
|
|
264
251
|
}),
|
|
265
252
|
],
|
|
@@ -267,21 +254,15 @@ async function bundleCode(workspaceRoot, entryPoints, outputNames, options, opti
|
|
|
267
254
|
...(optimizationOptions.scripts ? { 'ngDevMode': 'false' } : undefined),
|
|
268
255
|
'ngJitMode': 'false',
|
|
269
256
|
},
|
|
270
|
-
}
|
|
257
|
+
};
|
|
271
258
|
}
|
|
272
|
-
async function bundleGlobalStylesheets(
|
|
273
|
-
|
|
259
|
+
async function bundleGlobalStylesheets(options, target) {
|
|
260
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, outputNames, globalStyles, preserveSymlinks, externalDependencies, stylePreprocessorOptions, } = options;
|
|
274
261
|
const outputFiles = [];
|
|
275
262
|
const initialFiles = [];
|
|
276
263
|
const errors = [];
|
|
277
264
|
const warnings = [];
|
|
278
|
-
|
|
279
|
-
const { entryPoints: stylesheetEntrypoints, noInjectNames } = (0, configs_1.resolveGlobalStyles)(options.styles || [], workspaceRoot,
|
|
280
|
-
// preserveSymlinks is always true here to allow the bundler to handle the option
|
|
281
|
-
true,
|
|
282
|
-
// skipResolution to leverage the bundler's more comprehensive resolution
|
|
283
|
-
true);
|
|
284
|
-
for (const [name, files] of Object.entries(stylesheetEntrypoints)) {
|
|
265
|
+
for (const { name, files, initial } of globalStyles) {
|
|
285
266
|
const virtualEntryData = files
|
|
286
267
|
.map((file) => `@import '${file.replace(/\\/g, '/')}';`)
|
|
287
268
|
.join('\n');
|
|
@@ -289,10 +270,10 @@ async function bundleGlobalStylesheets(workspaceRoot, outputNames, options, opti
|
|
|
289
270
|
workspaceRoot,
|
|
290
271
|
optimization: !!optimizationOptions.styles.minify,
|
|
291
272
|
sourcemap: !!sourcemapOptions.styles && (sourcemapOptions.hidden ? 'external' : true),
|
|
292
|
-
outputNames:
|
|
293
|
-
includePaths:
|
|
294
|
-
preserveSymlinks
|
|
295
|
-
externalDependencies
|
|
273
|
+
outputNames: initial ? outputNames : { media: outputNames.media },
|
|
274
|
+
includePaths: stylePreprocessorOptions === null || stylePreprocessorOptions === void 0 ? void 0 : stylePreprocessorOptions.includePaths,
|
|
275
|
+
preserveSymlinks,
|
|
276
|
+
externalDependencies,
|
|
296
277
|
target,
|
|
297
278
|
});
|
|
298
279
|
errors.push(...sheetResult.errors);
|
|
@@ -312,7 +293,7 @@ async function bundleGlobalStylesheets(workspaceRoot, outputNames, options, opti
|
|
|
312
293
|
sheetContents = sheetContents.replace('sourceMappingURL=stdin.css.map', `sourceMappingURL=${name}.css.map`);
|
|
313
294
|
}
|
|
314
295
|
outputFiles.push(createOutputFileFromText(sheetPath, sheetContents));
|
|
315
|
-
if (
|
|
296
|
+
if (initial) {
|
|
316
297
|
initialFiles.push({
|
|
317
298
|
file: sheetPath,
|
|
318
299
|
name,
|
|
@@ -323,4 +304,81 @@ async function bundleGlobalStylesheets(workspaceRoot, outputNames, options, opti
|
|
|
323
304
|
}
|
|
324
305
|
return { outputFiles, initialFiles, errors, warnings };
|
|
325
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Main execution function for the esbuild-based application builder.
|
|
309
|
+
* The options are compatible with the Webpack-based builder.
|
|
310
|
+
* @param initialOptions The browser builder options to use when setting up the application build
|
|
311
|
+
* @param context The Architect builder context object
|
|
312
|
+
* @returns An async iterable with the builder result output
|
|
313
|
+
*/
|
|
314
|
+
async function* buildEsbuildBrowser(initialOptions, context) {
|
|
315
|
+
var _a;
|
|
316
|
+
// Only AOT is currently supported
|
|
317
|
+
if (initialOptions.aot !== true) {
|
|
318
|
+
context.logger.error('JIT mode is currently not supported by this experimental builder. AOT mode must be used.');
|
|
319
|
+
return { success: false };
|
|
320
|
+
}
|
|
321
|
+
// Inform user of experimental status of builder and options
|
|
322
|
+
(0, experimental_warnings_1.logExperimentalWarnings)(initialOptions, context);
|
|
323
|
+
// Determine project name from builder context target
|
|
324
|
+
const projectName = (_a = context.target) === null || _a === void 0 ? void 0 : _a.project;
|
|
325
|
+
if (!projectName) {
|
|
326
|
+
context.logger.error(`The 'browser-esbuild' builder requires a target to be specified.`);
|
|
327
|
+
return { success: false };
|
|
328
|
+
}
|
|
329
|
+
const normalizedOptions = await (0, options_1.normalizeOptions)(context, projectName, initialOptions);
|
|
330
|
+
// Clean output path if enabled
|
|
331
|
+
if (initialOptions.deleteOutputPath) {
|
|
332
|
+
(0, utils_1.deleteOutputDir)(normalizedOptions.workspaceRoot, initialOptions.outputPath);
|
|
333
|
+
}
|
|
334
|
+
// Create output directory if needed
|
|
335
|
+
try {
|
|
336
|
+
await fs.mkdir(normalizedOptions.outputPath, { recursive: true });
|
|
337
|
+
}
|
|
338
|
+
catch (e) {
|
|
339
|
+
(0, error_1.assertIsError)(e);
|
|
340
|
+
context.logger.error('Unable to create output directory: ' + e.message);
|
|
341
|
+
return { success: false };
|
|
342
|
+
}
|
|
343
|
+
// Initial build
|
|
344
|
+
let result = await execute(normalizedOptions, context);
|
|
345
|
+
yield result.output;
|
|
346
|
+
// Finish if watch mode is not enabled
|
|
347
|
+
if (!initialOptions.watch) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
context.logger.info('Watch mode enabled. Watching for file changes...');
|
|
351
|
+
// Setup a watcher
|
|
352
|
+
const watcher = (0, watcher_1.createWatcher)({
|
|
353
|
+
polling: typeof initialOptions.poll === 'number',
|
|
354
|
+
interval: initialOptions.poll,
|
|
355
|
+
// Ignore the output path to avoid infinite rebuild cycles
|
|
356
|
+
ignored: [normalizedOptions.outputPath],
|
|
357
|
+
});
|
|
358
|
+
// Temporarily watch the entire project
|
|
359
|
+
watcher.add(normalizedOptions.projectRoot);
|
|
360
|
+
// Watch workspace root node modules
|
|
361
|
+
// Includes Yarn PnP manifest files (https://yarnpkg.com/advanced/pnp-spec/)
|
|
362
|
+
watcher.add(path.join(normalizedOptions.workspaceRoot, 'node_modules'));
|
|
363
|
+
watcher.add(path.join(normalizedOptions.workspaceRoot, '.pnp.cjs'));
|
|
364
|
+
watcher.add(path.join(normalizedOptions.workspaceRoot, '.pnp.data.json'));
|
|
365
|
+
// Wait for changes and rebuild as needed
|
|
366
|
+
try {
|
|
367
|
+
for await (const changes of watcher) {
|
|
368
|
+
context.logger.info('Changes detected. Rebuilding...');
|
|
369
|
+
if (initialOptions.verbose) {
|
|
370
|
+
context.logger.info(changes.toDebugString());
|
|
371
|
+
}
|
|
372
|
+
result = await execute(normalizedOptions, context, result.createRebuildState(changes));
|
|
373
|
+
yield result.output;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
finally {
|
|
377
|
+
// Stop the watcher
|
|
378
|
+
await watcher.close();
|
|
379
|
+
// Cleanup incremental rebuild state
|
|
380
|
+
result.dispose();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
exports.buildEsbuildBrowser = buildEsbuildBrowser;
|
|
326
384
|
exports.default = (0, architect_1.createBuilder)(buildEsbuildBrowser);
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import { BuilderContext } from '@angular-devkit/architect';
|
|
9
|
-
import { Schema as BrowserBuilderOptions } from '
|
|
9
|
+
import { Schema as BrowserBuilderOptions } from './schema';
|
|
10
|
+
export declare type NormalizedBrowserOptions = Awaited<ReturnType<typeof normalizeOptions>>;
|
|
10
11
|
/**
|
|
11
12
|
* Normalize the user provided options by creating full paths for all path based options
|
|
12
13
|
* and converting multi-form options into a single form that can be directly used
|
|
@@ -18,17 +19,38 @@ import { Schema as BrowserBuilderOptions } from '../browser/schema';
|
|
|
18
19
|
* @returns An object containing normalized options required to perform the build.
|
|
19
20
|
*/
|
|
20
21
|
export declare function normalizeOptions(context: BuilderContext, projectName: string, options: BrowserBuilderOptions): Promise<{
|
|
22
|
+
advancedOptimizations: boolean | undefined;
|
|
23
|
+
baseHref: string | undefined;
|
|
24
|
+
crossOrigin: import("./schema").CrossOrigin | undefined;
|
|
25
|
+
externalDependencies: string[] | undefined;
|
|
26
|
+
poll: number | undefined;
|
|
27
|
+
preserveSymlinks: boolean | undefined;
|
|
28
|
+
stylePreprocessorOptions: import("./schema").StylePreprocessorOptions | undefined;
|
|
29
|
+
subresourceIntegrity: boolean | undefined;
|
|
30
|
+
verbose: boolean | undefined;
|
|
31
|
+
watch: boolean | undefined;
|
|
21
32
|
workspaceRoot: string;
|
|
22
33
|
entryPoints: Record<string, string>;
|
|
23
|
-
entryPointNameLookup: ReadonlyMap<string, string>;
|
|
24
34
|
optimizationOptions: import("../../utils").NormalizedOptimizationOptions;
|
|
25
35
|
outputPath: string;
|
|
26
|
-
sourcemapOptions: import("
|
|
36
|
+
sourcemapOptions: import("../..").SourceMapObject;
|
|
27
37
|
tsconfig: string;
|
|
28
38
|
projectRoot: string;
|
|
29
|
-
assets: import("
|
|
39
|
+
assets: import("../..").AssetPatternObject[] | undefined;
|
|
30
40
|
outputNames: {
|
|
31
41
|
bundles: string;
|
|
32
42
|
media: string;
|
|
33
43
|
};
|
|
44
|
+
fileReplacements: Record<string, string> | undefined;
|
|
45
|
+
globalStyles: {
|
|
46
|
+
name: string;
|
|
47
|
+
files: string[];
|
|
48
|
+
initial: boolean;
|
|
49
|
+
}[];
|
|
50
|
+
serviceWorkerOptions: string | undefined;
|
|
51
|
+
indexHtmlOptions: {
|
|
52
|
+
input: string;
|
|
53
|
+
output: string;
|
|
54
|
+
insertionOrder: import("../../utils/package-chunk-sort").EntryPointsType[];
|
|
55
|
+
} | undefined;
|
|
34
56
|
}>;
|
|
@@ -34,7 +34,10 @@ exports.normalizeOptions = void 0;
|
|
|
34
34
|
const path = __importStar(require("path"));
|
|
35
35
|
const utils_1 = require("../../utils");
|
|
36
36
|
const normalize_polyfills_1 = require("../../utils/normalize-polyfills");
|
|
37
|
-
const
|
|
37
|
+
const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
|
|
38
|
+
const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
|
|
39
|
+
const helpers_1 = require("../../webpack/utils/helpers");
|
|
40
|
+
const schema_1 = require("./schema");
|
|
38
41
|
/**
|
|
39
42
|
* Normalize the user provided options by creating full paths for all path based options
|
|
40
43
|
* and converting multi-form options into a single form that can be directly used
|
|
@@ -46,7 +49,7 @@ const schema_1 = require("../browser/schema");
|
|
|
46
49
|
* @returns An object containing normalized options required to perform the build.
|
|
47
50
|
*/
|
|
48
51
|
async function normalizeOptions(context, projectName, options) {
|
|
49
|
-
var _a, _b, _c, _d;
|
|
52
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
50
53
|
const workspaceRoot = context.workspaceRoot;
|
|
51
54
|
const projectMetadata = await context.getProjectMetadata(projectName);
|
|
52
55
|
const projectRoot = path.join(workspaceRoot, (_a = projectMetadata.root) !== null && _a !== void 0 ? _a : '');
|
|
@@ -76,6 +79,27 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
76
79
|
if (options.resourcesOutputPath) {
|
|
77
80
|
outputNames.media = path.join(options.resourcesOutputPath, outputNames.media);
|
|
78
81
|
}
|
|
82
|
+
let fileReplacements;
|
|
83
|
+
if (options.fileReplacements) {
|
|
84
|
+
for (const replacement of options.fileReplacements) {
|
|
85
|
+
fileReplacements !== null && fileReplacements !== void 0 ? fileReplacements : (fileReplacements = {});
|
|
86
|
+
fileReplacements[path.join(workspaceRoot, replacement.replace)] = path.join(workspaceRoot, replacement.with);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const globalStyles = [];
|
|
90
|
+
if ((_e = options.styles) === null || _e === void 0 ? void 0 : _e.length) {
|
|
91
|
+
const { entryPoints: stylesheetEntrypoints, noInjectNames } = (0, helpers_1.normalizeGlobalStyles)(options.styles || []);
|
|
92
|
+
for (const [name, files] of Object.entries(stylesheetEntrypoints)) {
|
|
93
|
+
globalStyles.push({ name, files, initial: !noInjectNames.includes(name) });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
let serviceWorkerOptions;
|
|
97
|
+
if (options.serviceWorker) {
|
|
98
|
+
// If ngswConfigPath is not specified, the default is 'ngsw-config.json' within the project root
|
|
99
|
+
serviceWorkerOptions = options.ngswConfigPath
|
|
100
|
+
? path.join(workspaceRoot, options.ngswConfigPath)
|
|
101
|
+
: path.join(projectRoot, 'ngsw-config.json');
|
|
102
|
+
}
|
|
79
103
|
// Setup bundler entry points
|
|
80
104
|
const entryPoints = {
|
|
81
105
|
main: mainEntryPoint,
|
|
@@ -83,12 +107,35 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
83
107
|
if (polyfillsEntryPoint) {
|
|
84
108
|
entryPoints['polyfills'] = polyfillsEntryPoint;
|
|
85
109
|
}
|
|
86
|
-
|
|
87
|
-
|
|
110
|
+
let indexHtmlOptions;
|
|
111
|
+
if (options.index) {
|
|
112
|
+
indexHtmlOptions = {
|
|
113
|
+
input: path.join(workspaceRoot, (0, webpack_browser_config_1.getIndexInputFile)(options.index)),
|
|
114
|
+
// The output file will be created within the configured output path
|
|
115
|
+
output: (0, webpack_browser_config_1.getIndexOutputFile)(options.index),
|
|
116
|
+
// TODO: Use existing information from above to create the insertion order
|
|
117
|
+
insertionOrder: (0, package_chunk_sort_1.generateEntryPoints)({
|
|
118
|
+
scripts: (_f = options.scripts) !== null && _f !== void 0 ? _f : [],
|
|
119
|
+
styles: (_g = options.styles) !== null && _g !== void 0 ? _g : [],
|
|
120
|
+
}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// Initial options to keep
|
|
124
|
+
const { baseHref, buildOptimizer, crossOrigin, externalDependencies, poll, preserveSymlinks, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, } = options;
|
|
125
|
+
// Return all the normalized options
|
|
88
126
|
return {
|
|
127
|
+
advancedOptimizations: buildOptimizer,
|
|
128
|
+
baseHref,
|
|
129
|
+
crossOrigin,
|
|
130
|
+
externalDependencies,
|
|
131
|
+
poll,
|
|
132
|
+
preserveSymlinks,
|
|
133
|
+
stylePreprocessorOptions,
|
|
134
|
+
subresourceIntegrity,
|
|
135
|
+
verbose,
|
|
136
|
+
watch,
|
|
89
137
|
workspaceRoot,
|
|
90
138
|
entryPoints,
|
|
91
|
-
entryPointNameLookup,
|
|
92
139
|
optimizationOptions,
|
|
93
140
|
outputPath,
|
|
94
141
|
sourcemapOptions,
|
|
@@ -96,6 +143,10 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
96
143
|
projectRoot,
|
|
97
144
|
assets,
|
|
98
145
|
outputNames,
|
|
146
|
+
fileReplacements,
|
|
147
|
+
globalStyles,
|
|
148
|
+
serviceWorkerOptions,
|
|
149
|
+
indexHtmlOptions,
|
|
99
150
|
};
|
|
100
151
|
}
|
|
101
152
|
exports.normalizeOptions = normalizeOptions;
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
export declare function resetCumulativeDurations(): void;
|
|
9
|
+
export declare function logCumulativeDurations(): void;
|
|
10
|
+
export declare function profileAsync<T>(name: string, action: () => Promise<T>, cumulative?: boolean): Promise<T>;
|
|
11
|
+
export declare function profileSync<T>(name: string, action: () => T, cumulative?: boolean): T;
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.profileSync = exports.profileAsync = exports.logCumulativeDurations = exports.resetCumulativeDurations = void 0;
|
|
11
|
+
const environment_options_1 = require("../../utils/environment-options");
|
|
12
|
+
let cumulativeDurations;
|
|
13
|
+
function resetCumulativeDurations() {
|
|
14
|
+
cumulativeDurations === null || cumulativeDurations === void 0 ? void 0 : cumulativeDurations.clear();
|
|
15
|
+
}
|
|
16
|
+
exports.resetCumulativeDurations = resetCumulativeDurations;
|
|
17
|
+
function logCumulativeDurations() {
|
|
18
|
+
if (!environment_options_1.debugPerformance || !cumulativeDurations) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const [name, duration] of cumulativeDurations) {
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
console.log(`DURATION[${name}]: ${duration.toFixed(9)} seconds`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.logCumulativeDurations = logCumulativeDurations;
|
|
27
|
+
function recordDuration(name, startTime, cumulative) {
|
|
28
|
+
var _a;
|
|
29
|
+
const duration = Number(process.hrtime.bigint() - startTime) / 10 ** 9;
|
|
30
|
+
if (cumulative) {
|
|
31
|
+
cumulativeDurations !== null && cumulativeDurations !== void 0 ? cumulativeDurations : (cumulativeDurations = new Map());
|
|
32
|
+
cumulativeDurations.set(name, ((_a = cumulativeDurations.get(name)) !== null && _a !== void 0 ? _a : 0) + duration);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.log(`DURATION[${name}]: ${duration.toFixed(9)} seconds`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function profileAsync(name, action, cumulative) {
|
|
40
|
+
if (!environment_options_1.debugPerformance) {
|
|
41
|
+
return action();
|
|
42
|
+
}
|
|
43
|
+
const startTime = process.hrtime.bigint();
|
|
44
|
+
try {
|
|
45
|
+
return await action();
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
recordDuration(name, startTime, cumulative);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.profileAsync = profileAsync;
|
|
52
|
+
function profileSync(name, action, cumulative) {
|
|
53
|
+
if (!environment_options_1.debugPerformance) {
|
|
54
|
+
return action();
|
|
55
|
+
}
|
|
56
|
+
const startTime = process.hrtime.bigint();
|
|
57
|
+
try {
|
|
58
|
+
return action();
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
recordDuration(name, startTime, cumulative);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.profileSync = profileSync;
|
|
@@ -31,7 +31,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
33
|
exports.createSassPlugin = void 0;
|
|
34
|
-
const
|
|
34
|
+
const node_path_1 = require("node:path");
|
|
35
|
+
const node_url_1 = require("node:url");
|
|
35
36
|
function createSassPlugin(options) {
|
|
36
37
|
return {
|
|
37
38
|
name: 'angular-sass',
|
|
@@ -59,14 +60,16 @@ function createSassPlugin(options) {
|
|
|
59
60
|
});
|
|
60
61
|
return {
|
|
61
62
|
loader: 'css',
|
|
62
|
-
contents: sourceMap
|
|
63
|
-
|
|
63
|
+
contents: sourceMap
|
|
64
|
+
? `${css}\n${sourceMapToUrlComment(sourceMap, (0, node_path_1.dirname)(args.path))}`
|
|
65
|
+
: css,
|
|
66
|
+
watchFiles: loadedUrls.map((url) => (0, node_url_1.fileURLToPath)(url)),
|
|
64
67
|
warnings,
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
catch (error) {
|
|
68
71
|
if (error instanceof sass.Exception) {
|
|
69
|
-
const file = error.span.url ? (0,
|
|
72
|
+
const file = error.span.url ? (0, node_url_1.fileURLToPath)(error.span.url) : undefined;
|
|
70
73
|
return {
|
|
71
74
|
loader: 'css',
|
|
72
75
|
errors: [
|
|
@@ -84,7 +87,10 @@ function createSassPlugin(options) {
|
|
|
84
87
|
};
|
|
85
88
|
}
|
|
86
89
|
exports.createSassPlugin = createSassPlugin;
|
|
87
|
-
function sourceMapToUrlComment(sourceMap) {
|
|
90
|
+
function sourceMapToUrlComment(sourceMap, root) {
|
|
91
|
+
// Remove `file` protocol from all sourcemap sources and adjust to be relative to the input file.
|
|
92
|
+
// This allows esbuild to correctly process the paths.
|
|
93
|
+
sourceMap.sources = sourceMap.sources.map((source) => (0, node_path_1.relative)(root, (0, node_url_1.fileURLToPath)(source)));
|
|
88
94
|
const urlSourceMap = Buffer.from(JSON.stringify(sourceMap), 'utf-8').toString('base64');
|
|
89
95
|
return `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${urlSourceMap} */`;
|
|
90
96
|
}
|