@angular/build 19.0.0-next.8 → 19.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -5
- package/package.json +22 -19
- package/src/builders/application/build-action.js +9 -9
- package/src/builders/application/chunk-optimizer.js +1 -4
- package/src/builders/application/execute-build.js +34 -6
- package/src/builders/application/execute-post-bundle.js +9 -1
- package/src/builders/application/index.d.ts +0 -16
- package/src/builders/application/index.js +15 -10
- package/src/builders/application/options.d.ts +11 -1
- package/src/builders/application/options.js +17 -10
- package/src/builders/application/results.d.ts +5 -3
- package/src/builders/application/schema.d.ts +86 -0
- package/src/builders/application/schema.js +19 -1
- package/src/builders/application/schema.json +73 -4
- package/src/builders/application/setup-bundling.d.ts +3 -1
- package/src/builders/application/setup-bundling.js +33 -6
- package/src/builders/dev-server/vite-server.d.ts +2 -2
- package/src/builders/dev-server/vite-server.js +46 -16
- package/src/index.d.ts +1 -0
- package/src/tools/angular/angular-host.d.ts +1 -1
- package/src/tools/angular/angular-host.js +1 -4
- package/src/tools/angular/compilation/angular-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.js +39 -0
- package/src/tools/angular/compilation/parallel-compilation.js +2 -2
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +5 -2
- package/src/tools/babel/plugins/add-code-coverage.d.ts +14 -0
- package/src/tools/babel/plugins/add-code-coverage.js +44 -0
- package/src/tools/babel/plugins/types.d.ts +20 -0
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +3 -4
- package/src/tools/esbuild/angular/compiler-plugin.js +55 -34
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +17 -18
- package/src/tools/esbuild/angular/component-stylesheets.js +63 -38
- package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +1 -1
- package/src/tools/esbuild/angular/jit-plugin-callbacks.js +11 -3
- package/src/tools/esbuild/application-code-bundle.d.ts +5 -4
- package/src/tools/esbuild/application-code-bundle.js +66 -41
- package/src/tools/esbuild/bundler-context.d.ts +2 -1
- package/src/tools/esbuild/bundler-context.js +10 -12
- package/src/tools/esbuild/bundler-execution-result.d.ts +5 -2
- package/src/tools/esbuild/bundler-execution-result.js +5 -1
- package/src/tools/esbuild/commonjs-checker.js +2 -2
- package/src/tools/esbuild/compiler-plugin-options.d.ts +1 -4
- package/src/tools/esbuild/compiler-plugin-options.js +14 -36
- package/src/tools/esbuild/global-scripts.js +1 -1
- package/src/tools/esbuild/global-styles.js +4 -1
- package/src/tools/esbuild/index-html-generator.js +8 -0
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +1 -0
- package/src/tools/esbuild/javascript-transformer-worker.js +5 -1
- package/src/tools/esbuild/javascript-transformer.d.ts +2 -2
- package/src/tools/esbuild/javascript-transformer.js +7 -3
- package/src/tools/esbuild/server-bundle-metadata-plugin.d.ts +22 -0
- package/src/tools/esbuild/server-bundle-metadata-plugin.js +36 -0
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +2 -0
- package/src/tools/esbuild/stylesheets/bundle-options.js +2 -1
- package/src/tools/esbuild/stylesheets/sass-language.js +4 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +9 -0
- package/src/tools/esbuild/utils.js +13 -31
- package/src/tools/sass/worker.js +19 -0
- package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +19 -3
- package/src/tools/vite/middlewares/component-middleware.d.ts +9 -0
- package/src/tools/vite/middlewares/component-middleware.js +33 -0
- package/src/tools/vite/middlewares/index.d.ts +1 -0
- package/src/tools/vite/middlewares/index.js +3 -1
- package/src/tools/vite/middlewares/ssr-middleware.js +13 -12
- package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +2 -1
- package/src/tools/vite/plugins/setup-middlewares-plugin.js +2 -1
- package/src/tools/vite/utils.d.ts +1 -0
- package/src/typings.d.ts +1 -1
- package/src/utils/environment-options.js +1 -1
- package/src/utils/index-file/auto-csp.d.ts +23 -0
- package/src/utils/index-file/auto-csp.js +283 -0
- package/src/utils/index-file/html-rewriting-stream.d.ts +5 -1
- package/src/utils/index-file/index-html-generator.d.ts +4 -0
- package/src/utils/index-file/index-html-generator.js +16 -0
- package/src/utils/index-file/inline-critical-css.js +17 -18
- package/src/utils/index-file/ngcm-attribute.d.ts +15 -0
- package/src/utils/index-file/ngcm-attribute.js +37 -0
- package/src/utils/index-file/valid-self-closing-tags.js +27 -0
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/fetch-patch.d.ts +1 -1
- package/src/utils/server-rendering/fetch-patch.js +2 -2
- package/src/utils/server-rendering/launch-server.d.ts +14 -0
- package/src/utils/server-rendering/launch-server.js +63 -0
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +7 -0
- package/src/utils/server-rendering/manifest.d.ts +1 -1
- package/src/utils/server-rendering/manifest.js +4 -13
- package/src/utils/server-rendering/prerender.js +10 -6
- package/src/utils/server-rendering/render-worker.d.ts +4 -1
- package/src/utils/server-rendering/render-worker.js +13 -3
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +5 -4
- package/src/utils/server-rendering/routes-extractor-worker.js +14 -4
- package/src/utils/server-rendering/utils.d.ts +11 -0
- package/src/utils/server-rendering/utils.js +17 -0
- package/src/utils/supported-browsers.js +1 -0
|
@@ -0,0 +1,20 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
declare module 'istanbul-lib-instrument' {
|
|
10
|
+
export interface Visitor {
|
|
11
|
+
enter(path: import('@babel/core').NodePath<types.Program>): void;
|
|
12
|
+
exit(path: import('@babel/core').NodePath<types.Program>): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function programVisitor(
|
|
16
|
+
types: typeof import('@babel/core').types,
|
|
17
|
+
filePath?: string,
|
|
18
|
+
options?: { inputSourceMap?: object | null },
|
|
19
|
+
): Visitor;
|
|
20
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Plugin } from 'esbuild';
|
|
9
9
|
import { LoadResultCache } from '../load-result-cache';
|
|
10
|
-
import {
|
|
10
|
+
import { ComponentStylesheetBundler } from './component-stylesheets';
|
|
11
11
|
import { SourceFileCache } from './source-file-cache';
|
|
12
12
|
export interface CompilerPluginOptions {
|
|
13
13
|
sourcemap: boolean | 'external';
|
|
@@ -22,7 +22,6 @@ export interface CompilerPluginOptions {
|
|
|
22
22
|
loadResultCache?: LoadResultCache;
|
|
23
23
|
incremental: boolean;
|
|
24
24
|
externalRuntimeStyles?: boolean;
|
|
25
|
+
instrumentForCoverage?: (request: string) => boolean;
|
|
25
26
|
}
|
|
26
|
-
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions,
|
|
27
|
-
inlineStyleLanguage: string;
|
|
28
|
-
}): Plugin;
|
|
27
|
+
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, stylesheetBundler: ComponentStylesheetBundler): Plugin;
|
|
@@ -43,11 +43,10 @@ const javascript_transformer_1 = require("../javascript-transformer");
|
|
|
43
43
|
const load_result_cache_1 = require("../load-result-cache");
|
|
44
44
|
const profiling_1 = require("../profiling");
|
|
45
45
|
const compilation_state_1 = require("./compilation-state");
|
|
46
|
-
const component_stylesheets_1 = require("./component-stylesheets");
|
|
47
46
|
const file_reference_tracker_1 = require("./file-reference-tracker");
|
|
48
47
|
const jit_plugin_callbacks_1 = require("./jit-plugin-callbacks");
|
|
49
48
|
// eslint-disable-next-line max-lines-per-function
|
|
50
|
-
function createCompilerPlugin(pluginOptions,
|
|
49
|
+
function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
51
50
|
return {
|
|
52
51
|
name: 'angular-compiler',
|
|
53
52
|
// eslint-disable-next-line max-lines-per-function
|
|
@@ -101,8 +100,6 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
101
100
|
let shouldTsIgnoreJs = true;
|
|
102
101
|
// Determines if transpilation should be handle by TypeScript or esbuild
|
|
103
102
|
let useTypeScriptTranspilation = true;
|
|
104
|
-
// Track incremental component stylesheet builds
|
|
105
|
-
const stylesheetBundler = new component_stylesheets_1.ComponentStylesheetBundler(styleOptions, pluginOptions.incremental);
|
|
106
103
|
let sharedTSCompilationState;
|
|
107
104
|
// To fully invalidate files, track resource referenced files and their referencing source
|
|
108
105
|
const referencedFileTracker = new file_reference_tracker_1.FileReferenceTracker();
|
|
@@ -121,14 +118,17 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
121
118
|
// Angular compiler which does not have direct knowledge of transitive resource
|
|
122
119
|
// dependencies or web worker processing.
|
|
123
120
|
let modifiedFiles;
|
|
124
|
-
let invalidatedStylesheetEntries;
|
|
125
121
|
if (pluginOptions.sourceFileCache?.modifiedFiles.size &&
|
|
126
122
|
referencedFileTracker &&
|
|
127
123
|
!pluginOptions.noopTypeScriptCompilation) {
|
|
128
124
|
// TODO: Differentiate between changed input files and stale output files
|
|
129
125
|
modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles);
|
|
130
126
|
pluginOptions.sourceFileCache.invalidate(modifiedFiles);
|
|
131
|
-
|
|
127
|
+
// External runtime styles are invalidated and rebuilt at the beginning of a rebuild to avoid
|
|
128
|
+
// the need to execute the application bundler for component style only changes.
|
|
129
|
+
if (!pluginOptions.externalRuntimeStyles) {
|
|
130
|
+
stylesheetBundler.invalidate(modifiedFiles);
|
|
131
|
+
}
|
|
132
132
|
}
|
|
133
133
|
if (!pluginOptions.noopTypeScriptCompilation &&
|
|
134
134
|
compilation.update &&
|
|
@@ -140,7 +140,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
140
140
|
fileReplacements: pluginOptions.fileReplacements,
|
|
141
141
|
modifiedFiles,
|
|
142
142
|
sourceFileCache: pluginOptions.sourceFileCache,
|
|
143
|
-
async transformStylesheet(data, containingFile, stylesheetFile, order) {
|
|
143
|
+
async transformStylesheet(data, containingFile, stylesheetFile, order, className) {
|
|
144
144
|
let stylesheetResult;
|
|
145
145
|
// Stylesheet file only exists for external stylesheets
|
|
146
146
|
if (stylesheetFile) {
|
|
@@ -148,8 +148,8 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
148
148
|
}
|
|
149
149
|
else {
|
|
150
150
|
stylesheetResult = await stylesheetBundler.bundleInline(data, containingFile,
|
|
151
|
-
// Inline stylesheets from a template style element are always CSS
|
|
152
|
-
containingFile.endsWith('.html') ? 'css' :
|
|
151
|
+
// Inline stylesheets from a template style element are always CSS; Otherwise, use default.
|
|
152
|
+
containingFile.endsWith('.html') ? 'css' : undefined,
|
|
153
153
|
// When external runtime styles are enabled, an identifier for the style that does not change
|
|
154
154
|
// based on the content is required to avoid emitted JS code changes. Any JS code changes will
|
|
155
155
|
// invalid the output and force a full page reload for HMR cases. The containing file and order
|
|
@@ -158,14 +158,16 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
158
158
|
? (0, node_crypto_1.createHash)('sha-256')
|
|
159
159
|
.update(containingFile)
|
|
160
160
|
.update((order ?? 0).toString())
|
|
161
|
+
.update(className ?? '')
|
|
161
162
|
.digest('hex')
|
|
162
163
|
: undefined);
|
|
163
164
|
}
|
|
164
|
-
|
|
165
|
-
if (errors) {
|
|
166
|
-
(result.errors ??= []).push(...errors);
|
|
165
|
+
(result.warnings ??= []).push(...stylesheetResult.warnings);
|
|
166
|
+
if (stylesheetResult.errors) {
|
|
167
|
+
(result.errors ??= []).push(...stylesheetResult.errors);
|
|
168
|
+
return '';
|
|
167
169
|
}
|
|
168
|
-
|
|
170
|
+
const { contents, outputFiles, metafile, referencedFiles } = stylesheetResult;
|
|
169
171
|
additionalResults.set(stylesheetFile ?? containingFile, {
|
|
170
172
|
outputFiles,
|
|
171
173
|
metafile,
|
|
@@ -215,7 +217,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
215
217
|
let referencedFiles;
|
|
216
218
|
let externalStylesheets;
|
|
217
219
|
try {
|
|
218
|
-
const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks));
|
|
220
|
+
const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks, build.initialOptions.conditions));
|
|
219
221
|
shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs;
|
|
220
222
|
// Isolated modules option ensures safe non-TypeScript transpilation.
|
|
221
223
|
// Typescript printing support for sourcemaps is not yet integrated.
|
|
@@ -250,13 +252,6 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
250
252
|
for (const [stylesheetFile, externalId] of externalStylesheets) {
|
|
251
253
|
await bundleExternalStylesheet(stylesheetBundler, stylesheetFile, externalId, result, additionalResults);
|
|
252
254
|
}
|
|
253
|
-
// Process any updated stylesheets
|
|
254
|
-
if (invalidatedStylesheetEntries) {
|
|
255
|
-
for (const stylesheetFile of invalidatedStylesheetEntries) {
|
|
256
|
-
// externalId is already linked in the bundler context so only enabling is required here
|
|
257
|
-
await bundleExternalStylesheet(stylesheetBundler, stylesheetFile, true, result, additionalResults);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
255
|
}
|
|
261
256
|
// Update TypeScript file output cache for all affected files
|
|
262
257
|
try {
|
|
@@ -339,13 +334,27 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
339
334
|
// A string indicates untransformed output from the TS/NG compiler.
|
|
340
335
|
// This step is unneeded when using esbuild transpilation.
|
|
341
336
|
const sideEffects = await hasSideEffects(request);
|
|
342
|
-
|
|
337
|
+
const instrumentForCoverage = pluginOptions.instrumentForCoverage?.(request);
|
|
338
|
+
contents = await javascriptTransformer.transformData(request, contents, true /* skipLinker */, sideEffects, instrumentForCoverage);
|
|
343
339
|
// Store as the returned Uint8Array to allow caching the fully transformed code
|
|
344
340
|
typeScriptFileCache.set(request, contents);
|
|
345
341
|
}
|
|
342
|
+
let loader;
|
|
343
|
+
if (useTypeScriptTranspilation || isJS) {
|
|
344
|
+
// TypeScript has transpiled to JS or is already JS
|
|
345
|
+
loader = 'js';
|
|
346
|
+
}
|
|
347
|
+
else if (request.at(-1) === 'x') {
|
|
348
|
+
// TSX and TS have different syntax rules. Only set if input is a TSX file.
|
|
349
|
+
loader = 'tsx';
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
// Otherwise, directly bundle TS
|
|
353
|
+
loader = 'ts';
|
|
354
|
+
}
|
|
346
355
|
return {
|
|
347
356
|
contents,
|
|
348
|
-
loader
|
|
357
|
+
loader,
|
|
349
358
|
};
|
|
350
359
|
});
|
|
351
360
|
build.onLoad({ filter: /\.[cm]?js$/ }, (0, load_result_cache_1.createCachedLoad)(pluginOptions.loadResultCache, async (args) => {
|
|
@@ -360,7 +369,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
360
369
|
}));
|
|
361
370
|
// Setup bundling of component templates and stylesheets when in JIT mode
|
|
362
371
|
if (pluginOptions.jit) {
|
|
363
|
-
(0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults,
|
|
372
|
+
(0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults, pluginOptions.loadResultCache);
|
|
364
373
|
}
|
|
365
374
|
build.onEnd((result) => {
|
|
366
375
|
// Ensure other compilations are unblocked if the main compilation throws during start
|
|
@@ -383,7 +392,6 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
383
392
|
});
|
|
384
393
|
build.onDispose(() => {
|
|
385
394
|
sharedTSCompilationState?.dispose();
|
|
386
|
-
void stylesheetBundler.dispose();
|
|
387
395
|
void compilation.close?.();
|
|
388
396
|
void cacheStore?.close();
|
|
389
397
|
});
|
|
@@ -404,17 +412,25 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
404
412
|
};
|
|
405
413
|
}
|
|
406
414
|
async function bundleExternalStylesheet(stylesheetBundler, stylesheetFile, externalId, result, additionalResults) {
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
415
|
+
const styleResult = await stylesheetBundler.bundleFile(stylesheetFile, externalId);
|
|
416
|
+
(result.warnings ??= []).push(...styleResult.warnings);
|
|
417
|
+
if (styleResult.errors) {
|
|
418
|
+
(result.errors ??= []).push(...styleResult.errors);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
const { outputFiles, metafile } = styleResult;
|
|
422
|
+
// Clear inputs to prevent triggering a rebuild of the application code for component
|
|
423
|
+
// stylesheet file only changes when the dev server enables the internal-only external
|
|
424
|
+
// stylesheet option. This does not affect builds since only the dev server can enable
|
|
425
|
+
// the internal option.
|
|
426
|
+
metafile.inputs = {};
|
|
427
|
+
additionalResults.set(stylesheetFile, {
|
|
428
|
+
outputFiles,
|
|
429
|
+
metafile,
|
|
430
|
+
});
|
|
410
431
|
}
|
|
411
|
-
(result.warnings ??= []).push(...warnings);
|
|
412
|
-
additionalResults.set(stylesheetFile, {
|
|
413
|
-
outputFiles,
|
|
414
|
-
metafile,
|
|
415
|
-
});
|
|
416
432
|
}
|
|
417
|
-
function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks) {
|
|
433
|
+
function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks, customConditions) {
|
|
418
434
|
return (compilerOptions) => {
|
|
419
435
|
// target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum)
|
|
420
436
|
if (compilerOptions.target === undefined || compilerOptions.target < 9 /** ES2022 */) {
|
|
@@ -462,6 +478,11 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
|
|
|
462
478
|
notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }],
|
|
463
479
|
});
|
|
464
480
|
}
|
|
481
|
+
// Synchronize custom resolve conditions.
|
|
482
|
+
// Set if using the supported bundler resolution mode (bundler is the default in new projects)
|
|
483
|
+
if (compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */) {
|
|
484
|
+
compilerOptions.customConditions = customConditions;
|
|
485
|
+
}
|
|
465
486
|
return {
|
|
466
487
|
...compilerOptions,
|
|
467
488
|
noEmitOnError: false,
|
|
@@ -5,8 +5,12 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { BundleContextResult } from '../bundler-context';
|
|
9
9
|
import { BundleStylesheetOptions } from '../stylesheets/bundle-options';
|
|
10
|
+
export type ComponentStylesheetResult = BundleContextResult & {
|
|
11
|
+
contents: string;
|
|
12
|
+
referencedFiles: Set<string> | undefined;
|
|
13
|
+
};
|
|
10
14
|
/**
|
|
11
15
|
* Bundles component stylesheets. A stylesheet can be either an inline stylesheet that
|
|
12
16
|
* is contained within the Component's metadata definition or an external file referenced
|
|
@@ -15,35 +19,30 @@ import { BundleStylesheetOptions } from '../stylesheets/bundle-options';
|
|
|
15
19
|
export declare class ComponentStylesheetBundler {
|
|
16
20
|
#private;
|
|
17
21
|
private readonly options;
|
|
22
|
+
private readonly defaultInlineLanguage;
|
|
18
23
|
private readonly incremental;
|
|
19
24
|
/**
|
|
20
25
|
*
|
|
21
26
|
* @param options An object containing the stylesheet bundling options.
|
|
22
27
|
* @param cache A load result cache to use when bundling.
|
|
23
28
|
*/
|
|
24
|
-
constructor(options: BundleStylesheetOptions, incremental: boolean);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
bundleInline(data: string, filename: string, language
|
|
34
|
-
errors: import("esbuild").Message[] | undefined;
|
|
35
|
-
warnings: import("esbuild").Message[];
|
|
36
|
-
contents: string;
|
|
37
|
-
outputFiles: OutputFile[];
|
|
38
|
-
metafile: import("esbuild").Metafile | undefined;
|
|
39
|
-
referencedFiles: Set<string> | undefined;
|
|
40
|
-
}>;
|
|
29
|
+
constructor(options: BundleStylesheetOptions, defaultInlineLanguage: string, incremental: boolean);
|
|
30
|
+
/**
|
|
31
|
+
* Bundle a file-based component stylesheet for use within an AOT compiled Angular application.
|
|
32
|
+
* @param entry The file path of the stylesheet.
|
|
33
|
+
* @param externalId Either an external identifier string for initial bundling or a boolean for rebuilds, if external.
|
|
34
|
+
* @param direct If true, the output will be used directly by the builder; false if used inside the compiler plugin.
|
|
35
|
+
* @returns A component bundle result object.
|
|
36
|
+
*/
|
|
37
|
+
bundleFile(entry: string, externalId?: string | boolean, direct?: boolean): Promise<ComponentStylesheetResult>;
|
|
38
|
+
bundleInline(data: string, filename: string, language?: string, externalId?: string): Promise<ComponentStylesheetResult>;
|
|
41
39
|
/**
|
|
42
40
|
* Invalidates both file and inline based component style bundling state for a set of modified files.
|
|
43
41
|
* @param files The group of files that have been modified
|
|
44
42
|
* @returns An array of file based stylesheet entries if any were invalidated; otherwise, undefined.
|
|
45
43
|
*/
|
|
46
44
|
invalidate(files: Iterable<string>): string[] | undefined;
|
|
45
|
+
collectReferencedFiles(): string[];
|
|
47
46
|
dispose(): Promise<void>;
|
|
48
47
|
private extractResult;
|
|
49
48
|
}
|
|
@@ -24,6 +24,7 @@ const bundle_options_1 = require("../stylesheets/bundle-options");
|
|
|
24
24
|
*/
|
|
25
25
|
class ComponentStylesheetBundler {
|
|
26
26
|
options;
|
|
27
|
+
defaultInlineLanguage;
|
|
27
28
|
incremental;
|
|
28
29
|
#fileContexts = new cache_1.MemoryCache();
|
|
29
30
|
#inlineContexts = new cache_1.MemoryCache();
|
|
@@ -32,17 +33,26 @@ class ComponentStylesheetBundler {
|
|
|
32
33
|
* @param options An object containing the stylesheet bundling options.
|
|
33
34
|
* @param cache A load result cache to use when bundling.
|
|
34
35
|
*/
|
|
35
|
-
constructor(options, incremental) {
|
|
36
|
+
constructor(options, defaultInlineLanguage, incremental) {
|
|
36
37
|
this.options = options;
|
|
38
|
+
this.defaultInlineLanguage = defaultInlineLanguage;
|
|
37
39
|
this.incremental = incremental;
|
|
38
40
|
}
|
|
39
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Bundle a file-based component stylesheet for use within an AOT compiled Angular application.
|
|
43
|
+
* @param entry The file path of the stylesheet.
|
|
44
|
+
* @param externalId Either an external identifier string for initial bundling or a boolean for rebuilds, if external.
|
|
45
|
+
* @param direct If true, the output will be used directly by the builder; false if used inside the compiler plugin.
|
|
46
|
+
* @returns A component bundle result object.
|
|
47
|
+
*/
|
|
48
|
+
async bundleFile(entry, externalId, direct) {
|
|
40
49
|
const bundlerContext = await this.#fileContexts.getOrCreate(entry, () => {
|
|
41
50
|
return new bundler_context_1.BundlerContext(this.options.workspaceRoot, this.incremental, (loadCache) => {
|
|
42
51
|
const buildOptions = (0, bundle_options_1.createStylesheetBundleOptions)(this.options, loadCache);
|
|
43
52
|
if (externalId) {
|
|
44
53
|
(0, node_assert_1.default)(typeof externalId === 'string', 'Initial external component stylesheets must have a string identifier');
|
|
45
54
|
buildOptions.entryPoints = { [externalId]: entry };
|
|
55
|
+
buildOptions.entryNames = '[name]';
|
|
46
56
|
delete buildOptions.publicPath;
|
|
47
57
|
}
|
|
48
58
|
else {
|
|
@@ -51,9 +61,9 @@ class ComponentStylesheetBundler {
|
|
|
51
61
|
return buildOptions;
|
|
52
62
|
});
|
|
53
63
|
});
|
|
54
|
-
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId);
|
|
64
|
+
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId, !!direct);
|
|
55
65
|
}
|
|
56
|
-
async bundleInline(data, filename, language, externalId) {
|
|
66
|
+
async bundleInline(data, filename, language = this.defaultInlineLanguage, externalId) {
|
|
57
67
|
// Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve
|
|
58
68
|
// to the actual stylesheet file path.
|
|
59
69
|
// TODO: Consider xxhash instead for hashing
|
|
@@ -70,6 +80,7 @@ class ComponentStylesheetBundler {
|
|
|
70
80
|
});
|
|
71
81
|
if (externalId) {
|
|
72
82
|
buildOptions.entryPoints = { [externalId]: `${namespace};${entry}` };
|
|
83
|
+
buildOptions.entryNames = '[name]';
|
|
73
84
|
delete buildOptions.publicPath;
|
|
74
85
|
}
|
|
75
86
|
else {
|
|
@@ -100,7 +111,7 @@ class ComponentStylesheetBundler {
|
|
|
100
111
|
});
|
|
101
112
|
});
|
|
102
113
|
// Extract the result of the bundling from the output files
|
|
103
|
-
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId);
|
|
114
|
+
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId, false);
|
|
104
115
|
}
|
|
105
116
|
/**
|
|
106
117
|
* Invalidates both file and inline based component style bundling state for a set of modified files.
|
|
@@ -124,61 +135,75 @@ class ComponentStylesheetBundler {
|
|
|
124
135
|
}
|
|
125
136
|
return entries;
|
|
126
137
|
}
|
|
138
|
+
collectReferencedFiles() {
|
|
139
|
+
const files = [];
|
|
140
|
+
for (const context of this.#fileContexts.values()) {
|
|
141
|
+
files.push(...context.watchFiles);
|
|
142
|
+
}
|
|
143
|
+
return files;
|
|
144
|
+
}
|
|
127
145
|
async dispose() {
|
|
128
146
|
const contexts = [...this.#fileContexts.values(), ...this.#inlineContexts.values()];
|
|
129
147
|
this.#fileContexts.clear();
|
|
130
148
|
this.#inlineContexts.clear();
|
|
131
149
|
await Promise.allSettled(contexts.map((context) => context.dispose()));
|
|
132
150
|
}
|
|
133
|
-
extractResult(result, referencedFiles, external) {
|
|
151
|
+
extractResult(result, referencedFiles, external, direct) {
|
|
134
152
|
let contents = '';
|
|
135
|
-
let metafile;
|
|
136
153
|
const outputFiles = [];
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
const { errors, warnings } = result;
|
|
155
|
+
if (errors) {
|
|
156
|
+
return { errors, warnings, referencedFiles, contents: '' };
|
|
157
|
+
}
|
|
158
|
+
for (const outputFile of result.outputFiles) {
|
|
159
|
+
const filename = node_path_1.default.basename(outputFile.path);
|
|
160
|
+
if (outputFile.type === bundler_context_1.BuildOutputFileType.Media || filename.endsWith('.css.map')) {
|
|
161
|
+
// The output files could also contain resources (images/fonts/etc.) that were referenced and the map files.
|
|
162
|
+
// Clone the output file to avoid amending the original path which would causes problems during rebuild.
|
|
163
|
+
const clonedOutputFile = outputFile.clone();
|
|
164
|
+
// Needed for Bazel as otherwise the files will not be written in the correct place,
|
|
165
|
+
// this is because esbuild will resolve the output file from the outdir which is currently set to `workspaceRoot` twice,
|
|
166
|
+
// once in the stylesheet and the other in the application code bundler.
|
|
167
|
+
// Ex: `../../../../../app.component.css.map`.
|
|
168
|
+
if (!direct) {
|
|
148
169
|
clonedOutputFile.path = node_path_1.default.join(this.options.workspaceRoot, outputFile.path);
|
|
149
|
-
outputFiles.push(clonedOutputFile);
|
|
150
170
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
171
|
+
outputFiles.push(clonedOutputFile);
|
|
172
|
+
}
|
|
173
|
+
else if (filename.endsWith('.css')) {
|
|
174
|
+
if (external) {
|
|
175
|
+
const clonedOutputFile = outputFile.clone();
|
|
176
|
+
if (!direct) {
|
|
154
177
|
clonedOutputFile.path = node_path_1.default.join(this.options.workspaceRoot, outputFile.path);
|
|
155
|
-
outputFiles.push(clonedOutputFile);
|
|
156
|
-
contents = node_path_1.default.posix.join(this.options.publicPath ?? '', filename);
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
contents = outputFile.text;
|
|
160
178
|
}
|
|
179
|
+
outputFiles.push(clonedOutputFile);
|
|
180
|
+
contents = node_path_1.default.posix.join(this.options.publicPath ?? '', filename);
|
|
161
181
|
}
|
|
162
182
|
else {
|
|
163
|
-
|
|
183
|
+
contents = outputFile.text;
|
|
164
184
|
}
|
|
165
185
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Object.values(metafile.outputs).forEach((output) => {
|
|
170
|
-
delete output.entryPoint;
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
172
|
-
output['ng-component'] = true;
|
|
173
|
-
});
|
|
186
|
+
else {
|
|
187
|
+
throw new Error(`Unexpected non CSS/Media file "${filename}" outputted during component stylesheet processing.`);
|
|
188
|
+
}
|
|
174
189
|
}
|
|
190
|
+
const metafile = result.metafile;
|
|
191
|
+
// Remove entryPoint fields from outputs to prevent the internal component styles from being
|
|
192
|
+
// treated as initial files. Also mark the entry as a component resource for stat reporting.
|
|
193
|
+
Object.values(metafile.outputs).forEach((output) => {
|
|
194
|
+
delete output.entryPoint;
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
196
|
+
output['ng-component'] = true;
|
|
197
|
+
});
|
|
175
198
|
return {
|
|
176
|
-
errors
|
|
177
|
-
warnings
|
|
199
|
+
errors,
|
|
200
|
+
warnings,
|
|
178
201
|
contents,
|
|
179
202
|
outputFiles,
|
|
180
203
|
metafile,
|
|
181
204
|
referencedFiles,
|
|
205
|
+
externalImports: result.externalImports,
|
|
206
|
+
initialFiles: new Map(),
|
|
182
207
|
};
|
|
183
208
|
}
|
|
184
209
|
}
|
|
@@ -20,4 +20,4 @@ import { ComponentStylesheetBundler } from './component-stylesheets';
|
|
|
20
20
|
export declare function setupJitPluginCallbacks(build: PluginBuild, stylesheetBundler: ComponentStylesheetBundler, additionalResultFiles: Map<string, {
|
|
21
21
|
outputFiles?: OutputFile[];
|
|
22
22
|
metafile?: Metafile;
|
|
23
|
-
}>,
|
|
23
|
+
}>, loadCache?: LoadResultCache): void;
|
|
@@ -51,7 +51,7 @@ async function loadEntry(entry, root, skipRead) {
|
|
|
51
51
|
* @param styleOptions The options to use when bundling stylesheets.
|
|
52
52
|
* @param additionalResultFiles A Map where stylesheet resources will be added.
|
|
53
53
|
*/
|
|
54
|
-
function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles,
|
|
54
|
+
function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles, loadCache) {
|
|
55
55
|
const root = build.initialOptions.absWorkingDir ?? '';
|
|
56
56
|
// Add a resolve callback to capture and parse any JIT URIs that were added by the
|
|
57
57
|
// JIT resource TypeScript transformer.
|
|
@@ -90,9 +90,17 @@ function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles
|
|
|
90
90
|
stylesheetResult = await stylesheetBundler.bundleFile(entry.path);
|
|
91
91
|
}
|
|
92
92
|
else {
|
|
93
|
-
stylesheetResult = await stylesheetBundler.bundleInline(entry.contents, entry.path
|
|
93
|
+
stylesheetResult = await stylesheetBundler.bundleInline(entry.contents, entry.path);
|
|
94
94
|
}
|
|
95
|
-
const {
|
|
95
|
+
const { errors, warnings, referencedFiles } = stylesheetResult;
|
|
96
|
+
if (stylesheetResult.errors) {
|
|
97
|
+
return {
|
|
98
|
+
errors,
|
|
99
|
+
warnings,
|
|
100
|
+
watchFiles: referencedFiles && [...referencedFiles],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const { contents, outputFiles, metafile } = stylesheetResult;
|
|
96
104
|
additionalResultFiles.set(entry.path, { outputFiles, metafile });
|
|
97
105
|
return {
|
|
98
106
|
errors,
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { BuildOptions } from 'esbuild';
|
|
9
9
|
import type { NormalizedApplicationBuildOptions } from '../../builders/application/options';
|
|
10
|
+
import { ComponentStylesheetBundler } from './angular/component-stylesheets';
|
|
10
11
|
import { SourceFileCache } from './angular/source-file-cache';
|
|
11
12
|
import { BundlerOptionsFactory } from './bundler-context';
|
|
12
|
-
export declare function createBrowserCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache
|
|
13
|
-
export declare function createBrowserPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache
|
|
13
|
+
export declare function createBrowserCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BuildOptions;
|
|
14
|
+
export declare function createBrowserPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BuildOptions | BundlerOptionsFactory | undefined;
|
|
14
15
|
export declare function createServerPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BundlerOptionsFactory | undefined;
|
|
15
|
-
export declare function createServerMainCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|
|
16
|
-
export declare function createSsrEntryCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|
|
16
|
+
export declare function createServerMainCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BuildOptions;
|
|
17
|
+
export declare function createSsrEntryCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BuildOptions;
|