@angular/build 19.0.0-next.10 → 19.0.0-next.11
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 +13 -13
- package/src/builders/application/options.d.ts +3 -1
- package/src/builders/application/options.js +2 -1
- package/src/builders/application/results.d.ts +5 -3
- package/src/builders/application/schema.d.ts +57 -0
- package/src/builders/application/schema.js +19 -1
- package/src/builders/application/schema.json +33 -0
- package/src/builders/dev-server/vite-server.d.ts +1 -1
- package/src/builders/dev-server/vite-server.js +26 -7
- package/src/tools/angular/angular-host.d.ts +1 -1
- package/src/tools/angular/angular-host.js +1 -4
- package/src/tools/angular/compilation/parallel-compilation.js +2 -2
- package/src/tools/angular/compilation/parallel-worker.js +3 -1
- package/src/tools/esbuild/angular/compiler-plugin.js +27 -8
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +3 -2
- package/src/tools/esbuild/angular/component-stylesheets.js +4 -2
- package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +1 -1
- package/src/tools/esbuild/angular/jit-plugin-callbacks.js +2 -2
- package/src/tools/esbuild/application-code-bundle.js +46 -25
- package/src/tools/esbuild/bundler-context.js +7 -10
- package/src/tools/esbuild/compiler-plugin-options.js +3 -0
- package/src/tools/esbuild/global-scripts.js +1 -1
- package/src/tools/esbuild/global-styles.js +3 -0
- 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 +12 -1
- 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 +2 -2
- 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 +6 -6
- 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/utils/environment-options.js +1 -1
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/launch-server.js +5 -5
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +1 -1
- package/src/utils/supported-browsers.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "19.0.0-next.
|
|
3
|
+
"version": "19.0.0-next.11",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,41 +23,41 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.1900.0-next.
|
|
27
|
-
"@babel/core": "7.25.
|
|
26
|
+
"@angular-devkit/architect": "0.1900.0-next.11",
|
|
27
|
+
"@babel/core": "7.25.8",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.25.7",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
30
|
"@babel/plugin-syntax-import-attributes": "7.25.7",
|
|
31
31
|
"@inquirer/confirm": "5.0.0",
|
|
32
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
|
-
"critters": "0.0.
|
|
34
|
+
"critters": "0.0.25",
|
|
35
35
|
"esbuild": "0.24.0",
|
|
36
36
|
"fast-glob": "3.3.2",
|
|
37
37
|
"https-proxy-agent": "7.0.5",
|
|
38
38
|
"istanbul-lib-instrument": "6.0.3",
|
|
39
39
|
"listr2": "8.2.5",
|
|
40
|
-
"magic-string": "0.30.
|
|
40
|
+
"magic-string": "0.30.12",
|
|
41
41
|
"mrmime": "2.0.0",
|
|
42
42
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
43
43
|
"picomatch": "4.0.2",
|
|
44
44
|
"piscina": "4.7.0",
|
|
45
45
|
"rollup": "4.24.0",
|
|
46
|
-
"sass": "1.79.
|
|
46
|
+
"sass": "1.79.5",
|
|
47
47
|
"semver": "7.6.3",
|
|
48
|
-
"vite": "5.4.
|
|
48
|
+
"vite": "5.4.9",
|
|
49
49
|
"watchpack": "2.4.2"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
52
|
"lmdb": "3.1.3"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@angular/compiler": "^19.0.0-next.
|
|
56
|
-
"@angular/compiler-cli": "^19.0.0-next.
|
|
57
|
-
"@angular/localize": "^19.0.0-next.
|
|
58
|
-
"@angular/platform-server": "^19.0.0-next.
|
|
59
|
-
"@angular/service-worker": "^19.0.0-next.
|
|
60
|
-
"@angular/ssr": "^19.0.0-next.
|
|
55
|
+
"@angular/compiler": "^19.0.0-next.9",
|
|
56
|
+
"@angular/compiler-cli": "^19.0.0-next.9",
|
|
57
|
+
"@angular/localize": "^19.0.0-next.9",
|
|
58
|
+
"@angular/platform-server": "^19.0.0-next.9",
|
|
59
|
+
"@angular/service-worker": "^19.0.0-next.9",
|
|
60
|
+
"@angular/ssr": "^19.0.0-next.11",
|
|
61
61
|
"less": "^4.2.0",
|
|
62
62
|
"postcss": "^8.4.0",
|
|
63
63
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
@@ -9,7 +9,7 @@ import type { BuilderContext } from '@angular-devkit/architect';
|
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import { I18nOptions } from '../../utils/i18n-options';
|
|
11
11
|
import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
|
|
12
|
-
import { Schema as ApplicationBuilderOptions, I18NTranslation, OutputMode, OutputPathClass } from './schema';
|
|
12
|
+
import { Schema as ApplicationBuilderOptions, ExperimentalPlatform, I18NTranslation, OutputMode, OutputPathClass } from './schema';
|
|
13
13
|
/**
|
|
14
14
|
* The filename for the client-side rendered HTML template.
|
|
15
15
|
* This template is used for client-side rendering (CSR) in a web application.
|
|
@@ -119,8 +119,10 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
119
119
|
outputMode: OutputMode | undefined;
|
|
120
120
|
ssrOptions: {
|
|
121
121
|
entry?: undefined;
|
|
122
|
+
platform?: undefined;
|
|
122
123
|
} | {
|
|
123
124
|
entry: string | undefined;
|
|
125
|
+
platform: ExperimentalPlatform;
|
|
124
126
|
} | undefined;
|
|
125
127
|
verbose: boolean | undefined;
|
|
126
128
|
watch: boolean | undefined;
|
|
@@ -153,9 +153,10 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
153
153
|
ssrOptions = {};
|
|
154
154
|
}
|
|
155
155
|
else if (typeof options.ssr === 'object') {
|
|
156
|
-
const { entry } = options.ssr;
|
|
156
|
+
const { entry, experimentalPlatform = schema_1.ExperimentalPlatform.Node } = options.ssr;
|
|
157
157
|
ssrOptions = {
|
|
158
158
|
entry: entry && node_path_1.default.join(workspaceRoot, entry),
|
|
159
|
+
platform: experimentalPlatform,
|
|
159
160
|
};
|
|
160
161
|
}
|
|
161
162
|
let appShellOptions;
|
|
@@ -61,7 +61,9 @@ export interface ResultMessage {
|
|
|
61
61
|
}
|
|
62
62
|
export interface ComponentUpdateResult extends BaseResult {
|
|
63
63
|
kind: ResultKind.ComponentUpdate;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
updates: {
|
|
65
|
+
id: string;
|
|
66
|
+
type: 'style' | 'template';
|
|
67
|
+
content: string;
|
|
68
|
+
}[];
|
|
67
69
|
}
|
|
@@ -500,6 +500,37 @@ export interface SsrClass {
|
|
|
500
500
|
* The server entry-point that when executed will spawn the web server.
|
|
501
501
|
*/
|
|
502
502
|
entry?: string;
|
|
503
|
+
/**
|
|
504
|
+
* Specifies the platform for which the server bundle is generated. This affects the APIs
|
|
505
|
+
* and modules available in the server-side code.
|
|
506
|
+
*
|
|
507
|
+
* - `node`: (Default) Generates a bundle optimized for Node.js environments.
|
|
508
|
+
* - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
|
|
509
|
+
* workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
|
|
510
|
+
* making the bundle more portable.
|
|
511
|
+
*
|
|
512
|
+
* Please note that this feature does not provide polyfills for Node.js modules.
|
|
513
|
+
* Additionally, it is experimental, and the schematics may undergo changes in future
|
|
514
|
+
* versions.
|
|
515
|
+
*/
|
|
516
|
+
experimentalPlatform?: ExperimentalPlatform;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Specifies the platform for which the server bundle is generated. This affects the APIs
|
|
520
|
+
* and modules available in the server-side code.
|
|
521
|
+
*
|
|
522
|
+
* - `node`: (Default) Generates a bundle optimized for Node.js environments.
|
|
523
|
+
* - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
|
|
524
|
+
* workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
|
|
525
|
+
* making the bundle more portable.
|
|
526
|
+
*
|
|
527
|
+
* Please note that this feature does not provide polyfills for Node.js modules.
|
|
528
|
+
* Additionally, it is experimental, and the schematics may undergo changes in future
|
|
529
|
+
* versions.
|
|
530
|
+
*/
|
|
531
|
+
export declare enum ExperimentalPlatform {
|
|
532
|
+
Neutral = "neutral",
|
|
533
|
+
Node = "node"
|
|
503
534
|
}
|
|
504
535
|
/**
|
|
505
536
|
* Options to pass to style preprocessors.
|
|
@@ -509,6 +540,32 @@ export interface StylePreprocessorOptions {
|
|
|
509
540
|
* Paths to include. Paths will be resolved to workspace root.
|
|
510
541
|
*/
|
|
511
542
|
includePaths?: string[];
|
|
543
|
+
/**
|
|
544
|
+
* Options to pass to the sass preprocessor.
|
|
545
|
+
*/
|
|
546
|
+
sass?: Sass;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Options to pass to the sass preprocessor.
|
|
550
|
+
*/
|
|
551
|
+
export interface Sass {
|
|
552
|
+
/**
|
|
553
|
+
* A set of deprecations to treat as fatal. If a deprecation warning of any provided type is
|
|
554
|
+
* encountered during compilation, the compiler will error instead. If a Version is
|
|
555
|
+
* provided, then all deprecations that were active in that compiler version will be treated
|
|
556
|
+
* as fatal.
|
|
557
|
+
*/
|
|
558
|
+
fatalDeprecations?: string[];
|
|
559
|
+
/**
|
|
560
|
+
* A set of future deprecations to opt into early. Future deprecations passed here will be
|
|
561
|
+
* treated as active by the compiler, emitting warnings as necessary.
|
|
562
|
+
*/
|
|
563
|
+
futureDeprecations?: string[];
|
|
564
|
+
/**
|
|
565
|
+
* A set of active deprecations to ignore. If a deprecation warning of any provided type is
|
|
566
|
+
* encountered during compilation, the compiler will ignore it instead.
|
|
567
|
+
*/
|
|
568
|
+
silenceDeprecations?: string[];
|
|
512
569
|
}
|
|
513
570
|
export type StyleElement = StyleClass | string;
|
|
514
571
|
export interface StyleClass {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
|
3
3
|
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.OutputMode = exports.OutputHashing = exports.InlineStyleLanguage = exports.I18NTranslation = exports.CrossOrigin = exports.Type = void 0;
|
|
5
|
+
exports.ExperimentalPlatform = exports.OutputMode = exports.OutputHashing = exports.InlineStyleLanguage = exports.I18NTranslation = exports.CrossOrigin = exports.Type = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* The type of budget.
|
|
8
8
|
*/
|
|
@@ -66,3 +66,21 @@ var OutputMode;
|
|
|
66
66
|
OutputMode["Server"] = "server";
|
|
67
67
|
OutputMode["Static"] = "static";
|
|
68
68
|
})(OutputMode || (exports.OutputMode = OutputMode = {}));
|
|
69
|
+
/**
|
|
70
|
+
* Specifies the platform for which the server bundle is generated. This affects the APIs
|
|
71
|
+
* and modules available in the server-side code.
|
|
72
|
+
*
|
|
73
|
+
* - `node`: (Default) Generates a bundle optimized for Node.js environments.
|
|
74
|
+
* - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
|
|
75
|
+
* workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
|
|
76
|
+
* making the bundle more portable.
|
|
77
|
+
*
|
|
78
|
+
* Please note that this feature does not provide polyfills for Node.js modules.
|
|
79
|
+
* Additionally, it is experimental, and the schematics may undergo changes in future
|
|
80
|
+
* versions.
|
|
81
|
+
*/
|
|
82
|
+
var ExperimentalPlatform;
|
|
83
|
+
(function (ExperimentalPlatform) {
|
|
84
|
+
ExperimentalPlatform["Neutral"] = "neutral";
|
|
85
|
+
ExperimentalPlatform["Node"] = "node";
|
|
86
|
+
})(ExperimentalPlatform || (exports.ExperimentalPlatform = ExperimentalPlatform = {}));
|
|
@@ -125,6 +125,34 @@
|
|
|
125
125
|
"type": "string"
|
|
126
126
|
},
|
|
127
127
|
"default": []
|
|
128
|
+
},
|
|
129
|
+
"sass": {
|
|
130
|
+
"description": "Options to pass to the sass preprocessor.",
|
|
131
|
+
"type": "object",
|
|
132
|
+
"properties": {
|
|
133
|
+
"fatalDeprecations": {
|
|
134
|
+
"description": "A set of deprecations to treat as fatal. If a deprecation warning of any provided type is encountered during compilation, the compiler will error instead. If a Version is provided, then all deprecations that were active in that compiler version will be treated as fatal.",
|
|
135
|
+
"type": "array",
|
|
136
|
+
"items": {
|
|
137
|
+
"type": "string"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"silenceDeprecations": {
|
|
141
|
+
"description": " A set of active deprecations to ignore. If a deprecation warning of any provided type is encountered during compilation, the compiler will ignore it instead.",
|
|
142
|
+
"type": "array",
|
|
143
|
+
"items": {
|
|
144
|
+
"type": "string"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"futureDeprecations": {
|
|
148
|
+
"description": "A set of future deprecations to opt into early. Future deprecations passed here will be treated as active by the compiler, emitting warnings as necessary.",
|
|
149
|
+
"type": "array",
|
|
150
|
+
"items": {
|
|
151
|
+
"type": "string"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"additionalProperties": false
|
|
128
156
|
}
|
|
129
157
|
},
|
|
130
158
|
"additionalProperties": false
|
|
@@ -518,6 +546,11 @@
|
|
|
518
546
|
"entry": {
|
|
519
547
|
"type": "string",
|
|
520
548
|
"description": "The server entry-point that when executed will spawn the web server."
|
|
549
|
+
},
|
|
550
|
+
"experimentalPlatform": {
|
|
551
|
+
"description": "Specifies the platform for which the server bundle is generated. This affects the APIs and modules available in the server-side code. \n\n- `node`: (Default) Generates a bundle optimized for Node.js environments. \n- `neutral`: Generates a platform-neutral bundle suitable for environments like edge workers, and other serverless platforms. This option avoids using Node.js-specific APIs, making the bundle more portable. \n\nPlease note that this feature does not provide polyfills for Node.js modules. Additionally, it is experimental, and the schematics may undergo changes in future versions.",
|
|
552
|
+
"default": "node",
|
|
553
|
+
"enum": ["node", "neutral"]
|
|
521
554
|
}
|
|
522
555
|
},
|
|
523
556
|
"additionalProperties": false
|
|
@@ -32,6 +32,6 @@ export declare function serveWithVite(serverOptions: NormalizedDevServerOptions,
|
|
|
32
32
|
middleware?: Connect.NextHandleFunction[];
|
|
33
33
|
buildPlugins?: Plugin[];
|
|
34
34
|
}): AsyncIterableIterator<DevServerBuilderOutput>;
|
|
35
|
-
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssrMode: ServerSsrMode, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, usedComponentStyles: Map<string, string
|
|
35
|
+
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssrMode: ServerSsrMode, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, usedComponentStyles: Map<string, Set<string>>, templateUpdates: Map<string, string>, prebundleLoaderExtensions: EsbuildLoaderOption | undefined, extensionMiddleware?: Connect.NextHandleFunction[], indexHtmlTransformer?: (content: string) => Promise<string>, thirdPartySourcemaps?: boolean): Promise<InlineConfig>;
|
|
36
36
|
type EsbuildLoaderOption = Exclude<DepOptimizationConfig['esbuildOptions'], undefined>['loader'];
|
|
37
37
|
export {};
|
|
@@ -92,8 +92,13 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
92
92
|
// https://nodejs.org/api/process.html#processsetsourcemapsenabledval
|
|
93
93
|
process.setSourceMapsEnabled(true);
|
|
94
94
|
}
|
|
95
|
-
//
|
|
96
|
-
browserOptions.externalRuntimeStyles = environment_options_1.useComponentStyleHmr;
|
|
95
|
+
// Enable to support component style hot reloading (`NG_HMR_CSTYLES=0` can be used to disable)
|
|
96
|
+
browserOptions.externalRuntimeStyles = !!serverOptions.liveReload && environment_options_1.useComponentStyleHmr;
|
|
97
|
+
if (browserOptions.externalRuntimeStyles) {
|
|
98
|
+
// Preload the @angular/compiler package to avoid first stylesheet request delays.
|
|
99
|
+
// Once @angular/build is native ESM, this should be re-evaluated.
|
|
100
|
+
void (0, load_esm_1.loadEsmModule)('@angular/compiler');
|
|
101
|
+
}
|
|
97
102
|
// Setup the prebundling transformer that will be shared across Vite prebundling requests
|
|
98
103
|
const prebundleTransformer = new internal_1.JavaScriptTransformer(
|
|
99
104
|
// Always enable JIT linking to support applications built with and without AOT.
|
|
@@ -116,6 +121,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
116
121
|
explicitServer: [],
|
|
117
122
|
};
|
|
118
123
|
const usedComponentStyles = new Map();
|
|
124
|
+
const templateUpdates = new Map();
|
|
119
125
|
// Add cleanup logic via a builder teardown.
|
|
120
126
|
let deferred;
|
|
121
127
|
context.addTeardown(async () => {
|
|
@@ -157,6 +163,8 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
157
163
|
assetFiles.set('/' + normalizePath(outputPath), normalizePath(file.inputPath));
|
|
158
164
|
}
|
|
159
165
|
}
|
|
166
|
+
// Clear stale template updates on a code rebuilds
|
|
167
|
+
templateUpdates.clear();
|
|
160
168
|
// Analyze result files for changes
|
|
161
169
|
analyzeResultFiles(normalizePath, htmlIndexPath, result.files, generatedFiles);
|
|
162
170
|
break;
|
|
@@ -166,8 +174,18 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
166
174
|
break;
|
|
167
175
|
case results_1.ResultKind.ComponentUpdate:
|
|
168
176
|
(0, node_assert_1.default)(serverOptions.hmr, 'Component updates are only supported with HMR enabled.');
|
|
169
|
-
|
|
170
|
-
|
|
177
|
+
(0, node_assert_1.default)(server, 'Builder must provide an initial full build before component update results.');
|
|
178
|
+
for (const componentUpdate of result.updates) {
|
|
179
|
+
if (componentUpdate.type === 'template') {
|
|
180
|
+
templateUpdates.set(componentUpdate.id, componentUpdate.content);
|
|
181
|
+
server.ws.send('angular:component-update', {
|
|
182
|
+
id: componentUpdate.id,
|
|
183
|
+
timestamp: Date.now(),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
context.logger.info('Component update sent to client(s).');
|
|
188
|
+
continue;
|
|
171
189
|
default:
|
|
172
190
|
context.logger.warn(`Unknown result kind [${result.kind}] provided by build.`);
|
|
173
191
|
continue;
|
|
@@ -259,7 +277,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
259
277
|
});
|
|
260
278
|
}
|
|
261
279
|
// Setup server and start listening
|
|
262
|
-
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
280
|
+
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, templateUpdates, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
263
281
|
server = await createServer(serverConfiguration);
|
|
264
282
|
await server.listen();
|
|
265
283
|
const urls = server.resolvedUrls;
|
|
@@ -328,7 +346,7 @@ async function handleUpdate(normalizePath, generatedFiles, server, serverOptions
|
|
|
328
346
|
// are not typically reused across components.
|
|
329
347
|
const componentIds = usedComponentStyles.get(filePath);
|
|
330
348
|
if (componentIds) {
|
|
331
|
-
return componentIds.map((id) => ({
|
|
349
|
+
return Array.from(componentIds).map((id) => ({
|
|
332
350
|
type: 'css-update',
|
|
333
351
|
timestamp,
|
|
334
352
|
path: `${filePath}?ngcomp` + (id ? `=${id}` : ''),
|
|
@@ -409,7 +427,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
409
427
|
}
|
|
410
428
|
}
|
|
411
429
|
}
|
|
412
|
-
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, zoneless, usedComponentStyles, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
430
|
+
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, zoneless, usedComponentStyles, templateUpdates, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
413
431
|
const proxy = await (0, utils_1.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig);
|
|
414
432
|
// dynamically import Vite for ESM compatibility
|
|
415
433
|
const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
@@ -502,6 +520,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
502
520
|
indexHtmlTransformer,
|
|
503
521
|
extensionMiddleware,
|
|
504
522
|
usedComponentStyles,
|
|
523
|
+
templateUpdates,
|
|
505
524
|
ssrMode,
|
|
506
525
|
}),
|
|
507
526
|
(0, plugins_1.createRemoveIdPrefixPlugin)(externalMetadata.explicitBrowser),
|
|
@@ -14,7 +14,7 @@ export interface AngularHostOptions {
|
|
|
14
14
|
sourceFileCache?: Map<string, ts.SourceFile>;
|
|
15
15
|
modifiedFiles?: Set<string>;
|
|
16
16
|
externalStylesheets?: Map<string, string>;
|
|
17
|
-
transformStylesheet(data: string, containingFile: string, stylesheetFile?: string, order?: number): Promise<string | null>;
|
|
17
|
+
transformStylesheet(data: string, containingFile: string, stylesheetFile?: string, order?: number, className?: string): Promise<string | null>;
|
|
18
18
|
processWebWorker(workerFile: string, containingFile: string): string;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
@@ -113,10 +113,7 @@ function createAngularCompilerHost(typescript, compilerOptions, hostOptions) {
|
|
|
113
113
|
if (data.trim().length === 0) {
|
|
114
114
|
return { content: '' };
|
|
115
115
|
}
|
|
116
|
-
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined,
|
|
117
|
-
// TODO: Remove once available in compiler-cli types
|
|
118
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
-
context.order);
|
|
116
|
+
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined, context.order, context.className);
|
|
120
117
|
return typeof result === 'string' ? { content: result } : null;
|
|
121
118
|
};
|
|
122
119
|
host.resourceNameToFileName = function (resourceName, containingFile) {
|
|
@@ -37,9 +37,9 @@ class ParallelCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
37
37
|
initialize(tsconfig, hostOptions, compilerOptionsTransformer) {
|
|
38
38
|
const stylesheetChannel = new node_worker_threads_1.MessageChannel();
|
|
39
39
|
// The request identifier is required because Angular can issue multiple concurrent requests
|
|
40
|
-
stylesheetChannel.port1.on('message', ({ requestId, data, containingFile, stylesheetFile }) => {
|
|
40
|
+
stylesheetChannel.port1.on('message', ({ requestId, data, containingFile, stylesheetFile, order, className }) => {
|
|
41
41
|
hostOptions
|
|
42
|
-
.transformStylesheet(data, containingFile, stylesheetFile)
|
|
42
|
+
.transformStylesheet(data, containingFile, stylesheetFile, order, className)
|
|
43
43
|
.then((value) => stylesheetChannel.port1.postMessage({ requestId, value }))
|
|
44
44
|
.catch((error) => stylesheetChannel.port1.postMessage({ requestId, error }));
|
|
45
45
|
});
|
|
@@ -37,7 +37,7 @@ async function initialize(request) {
|
|
|
37
37
|
fileReplacements: request.fileReplacements,
|
|
38
38
|
sourceFileCache,
|
|
39
39
|
modifiedFiles: sourceFileCache.modifiedFiles,
|
|
40
|
-
transformStylesheet(data, containingFile, stylesheetFile) {
|
|
40
|
+
transformStylesheet(data, containingFile, stylesheetFile, order, className) {
|
|
41
41
|
const requestId = (0, node_crypto_1.randomUUID)();
|
|
42
42
|
const resultPromise = new Promise((resolve, reject) => stylesheetRequests.set(requestId, [resolve, reject]));
|
|
43
43
|
request.stylesheetPort.postMessage({
|
|
@@ -45,6 +45,8 @@ async function initialize(request) {
|
|
|
45
45
|
data,
|
|
46
46
|
containingFile,
|
|
47
47
|
stylesheetFile,
|
|
48
|
+
order,
|
|
49
|
+
className,
|
|
48
50
|
});
|
|
49
51
|
return resultPromise;
|
|
50
52
|
},
|
|
@@ -102,7 +102,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
102
102
|
// Determines if transpilation should be handle by TypeScript or esbuild
|
|
103
103
|
let useTypeScriptTranspilation = true;
|
|
104
104
|
// Track incremental component stylesheet builds
|
|
105
|
-
const stylesheetBundler = new component_stylesheets_1.ComponentStylesheetBundler(styleOptions, pluginOptions.incremental);
|
|
105
|
+
const stylesheetBundler = new component_stylesheets_1.ComponentStylesheetBundler(styleOptions, styleOptions.inlineStyleLanguage, pluginOptions.incremental);
|
|
106
106
|
let sharedTSCompilationState;
|
|
107
107
|
// To fully invalidate files, track resource referenced files and their referencing source
|
|
108
108
|
const referencedFileTracker = new file_reference_tracker_1.FileReferenceTracker();
|
|
@@ -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,6 +158,7 @@ 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
|
}
|
|
@@ -215,7 +216,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
215
216
|
let referencedFiles;
|
|
216
217
|
let externalStylesheets;
|
|
217
218
|
try {
|
|
218
|
-
const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks));
|
|
219
|
+
const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks, build.initialOptions.conditions));
|
|
219
220
|
shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs;
|
|
220
221
|
// Isolated modules option ensures safe non-TypeScript transpilation.
|
|
221
222
|
// Typescript printing support for sourcemaps is not yet integrated.
|
|
@@ -344,9 +345,22 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
344
345
|
// Store as the returned Uint8Array to allow caching the fully transformed code
|
|
345
346
|
typeScriptFileCache.set(request, contents);
|
|
346
347
|
}
|
|
348
|
+
let loader;
|
|
349
|
+
if (useTypeScriptTranspilation || isJS) {
|
|
350
|
+
// TypeScript has transpiled to JS or is already JS
|
|
351
|
+
loader = 'js';
|
|
352
|
+
}
|
|
353
|
+
else if (request.at(-1) === 'x') {
|
|
354
|
+
// TSX and TS have different syntax rules. Only set if input is a TSX file.
|
|
355
|
+
loader = 'tsx';
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
// Otherwise, directly bundle TS
|
|
359
|
+
loader = 'ts';
|
|
360
|
+
}
|
|
347
361
|
return {
|
|
348
362
|
contents,
|
|
349
|
-
loader
|
|
363
|
+
loader,
|
|
350
364
|
};
|
|
351
365
|
});
|
|
352
366
|
build.onLoad({ filter: /\.[cm]?js$/ }, (0, load_result_cache_1.createCachedLoad)(pluginOptions.loadResultCache, async (args) => {
|
|
@@ -361,7 +375,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
361
375
|
}));
|
|
362
376
|
// Setup bundling of component templates and stylesheets when in JIT mode
|
|
363
377
|
if (pluginOptions.jit) {
|
|
364
|
-
(0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults,
|
|
378
|
+
(0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults, pluginOptions.loadResultCache);
|
|
365
379
|
}
|
|
366
380
|
build.onEnd((result) => {
|
|
367
381
|
// Ensure other compilations are unblocked if the main compilation throws during start
|
|
@@ -415,7 +429,7 @@ async function bundleExternalStylesheet(stylesheetBundler, stylesheetFile, exter
|
|
|
415
429
|
metafile,
|
|
416
430
|
});
|
|
417
431
|
}
|
|
418
|
-
function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks) {
|
|
432
|
+
function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks, customConditions) {
|
|
419
433
|
return (compilerOptions) => {
|
|
420
434
|
// target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum)
|
|
421
435
|
if (compilerOptions.target === undefined || compilerOptions.target < 9 /** ES2022 */) {
|
|
@@ -463,6 +477,11 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
|
|
|
463
477
|
notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }],
|
|
464
478
|
});
|
|
465
479
|
}
|
|
480
|
+
// Synchronize custom resolve conditions.
|
|
481
|
+
// Set if using the supported bundler resolution mode (bundler is the default in new projects)
|
|
482
|
+
if (compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */) {
|
|
483
|
+
compilerOptions.customConditions = customConditions;
|
|
484
|
+
}
|
|
466
485
|
return {
|
|
467
486
|
...compilerOptions,
|
|
468
487
|
noEmitOnError: false,
|
|
@@ -15,13 +15,14 @@ import { BundleStylesheetOptions } from '../stylesheets/bundle-options';
|
|
|
15
15
|
export declare class ComponentStylesheetBundler {
|
|
16
16
|
#private;
|
|
17
17
|
private readonly options;
|
|
18
|
+
private readonly defaultInlineLanguage;
|
|
18
19
|
private readonly incremental;
|
|
19
20
|
/**
|
|
20
21
|
*
|
|
21
22
|
* @param options An object containing the stylesheet bundling options.
|
|
22
23
|
* @param cache A load result cache to use when bundling.
|
|
23
24
|
*/
|
|
24
|
-
constructor(options: BundleStylesheetOptions, incremental: boolean);
|
|
25
|
+
constructor(options: BundleStylesheetOptions, defaultInlineLanguage: string, incremental: boolean);
|
|
25
26
|
bundleFile(entry: string, externalId?: string | boolean): Promise<{
|
|
26
27
|
errors: import("esbuild").Message[] | undefined;
|
|
27
28
|
warnings: import("esbuild").Message[];
|
|
@@ -30,7 +31,7 @@ export declare class ComponentStylesheetBundler {
|
|
|
30
31
|
metafile: import("esbuild").Metafile | undefined;
|
|
31
32
|
referencedFiles: Set<string> | undefined;
|
|
32
33
|
}>;
|
|
33
|
-
bundleInline(data: string, filename: string, language
|
|
34
|
+
bundleInline(data: string, filename: string, language?: string, externalId?: string): Promise<{
|
|
34
35
|
errors: import("esbuild").Message[] | undefined;
|
|
35
36
|
warnings: import("esbuild").Message[];
|
|
36
37
|
contents: string;
|
|
@@ -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,8 +33,9 @@ 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
|
async bundleFile(entry, externalId) {
|
|
@@ -53,7 +55,7 @@ class ComponentStylesheetBundler {
|
|
|
53
55
|
});
|
|
54
56
|
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId);
|
|
55
57
|
}
|
|
56
|
-
async bundleInline(data, filename, language, externalId) {
|
|
58
|
+
async bundleInline(data, filename, language = this.defaultInlineLanguage, externalId) {
|
|
57
59
|
// Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve
|
|
58
60
|
// to the actual stylesheet file path.
|
|
59
61
|
// TODO: Consider xxhash instead for hashing
|
|
@@ -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,7 +90,7 @@ 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
95
|
const { contents, outputFiles, errors, warnings, metafile, referencedFiles } = stylesheetResult;
|
|
96
96
|
additionalResultFiles.set(entry.path, { outputFiles, metafile });
|