@angular/build 19.1.0-next.2 → 19.1.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 +1 -1
- package/builders.json +5 -0
- package/index.d.ts +8 -0
- package/index.js +24 -0
- package/package.json +20 -16
- package/private/index.d.ts +8 -0
- package/private/index.js +24 -0
- package/src/builders/application/build-action.d.ts +1 -0
- package/src/builders/application/build-action.js +93 -11
- package/src/builders/application/execute-build.js +5 -2
- package/src/builders/application/index.d.ts +5 -12
- package/src/builders/application/index.js +35 -21
- package/src/builders/application/options.d.ts +6 -0
- package/src/builders/application/options.js +1 -0
- package/src/builders/application/results.d.ts +4 -1
- package/src/builders/application/setup-bundling.d.ts +2 -1
- package/src/builders/application/setup-bundling.js +2 -2
- package/src/builders/dev-server/index.d.ts +4 -2
- package/src/builders/dev-server/index.js +2 -1
- package/src/builders/dev-server/vite-server.d.ts +5 -1
- package/src/builders/dev-server/vite-server.js +101 -77
- package/src/builders/extract-i18n/index.d.ts +4 -2
- package/src/builders/extract-i18n/index.js +2 -1
- package/src/builders/ng-packagr/builder.d.ts +19 -0
- package/src/builders/ng-packagr/builder.js +103 -0
- package/src/builders/ng-packagr/index.d.ts +14 -0
- package/src/builders/ng-packagr/index.js +15 -0
- package/src/builders/ng-packagr/schema.d.ts +21 -0
- package/src/builders/ng-packagr/schema.js +4 -0
- package/src/builders/ng-packagr/schema.json +27 -0
- package/src/index.d.ts +2 -1
- package/src/index.js +3 -1
- package/src/private.d.ts +4 -7
- package/src/private.js +4 -1
- package/src/tools/babel/plugins/pure-toplevel-functions.js +14 -3
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +2 -4
- package/src/tools/esbuild/angular/compiler-plugin.js +21 -10
- package/src/tools/esbuild/angular-localize-init-warning-plugin.d.ts +16 -0
- package/src/tools/esbuild/angular-localize-init-warning-plugin.js +49 -0
- package/src/tools/esbuild/application-code-bundle.d.ts +2 -1
- package/src/tools/esbuild/application-code-bundle.js +37 -26
- package/src/tools/esbuild/bundler-execution-result.d.ts +10 -3
- package/src/tools/esbuild/bundler-execution-result.js +13 -10
- package/src/tools/esbuild/compiler-plugin-options.js +0 -1
- package/src/tools/esbuild/javascript-transformer.js +8 -4
- package/src/tools/vite/middlewares/assets-middleware.d.ts +2 -2
- package/src/tools/vite/middlewares/assets-middleware.js +4 -4
- package/src/tools/vite/plugins/angular-memory-plugin.js +10 -5
- package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +2 -2
- package/src/tools/vite/utils.d.ts +5 -1
- package/src/tools/vite/utils.js +2 -1
- package/src/utils/bundle-calculator.d.ts +1 -0
- package/src/utils/bundle-calculator.js +5 -4
- package/src/utils/environment-options.js +1 -1
- package/src/utils/i18n-options.js +3 -3
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/fetch-patch.js +2 -2
- package/tsconfig-build.json +0 -6
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
import type { Plugin } from 'esbuild';
|
|
9
|
+
import { AngularCompilation } from '../../angular/compilation';
|
|
9
10
|
import { LoadResultCache } from '../load-result-cache';
|
|
10
11
|
import { ComponentStylesheetBundler } from './component-stylesheets';
|
|
11
12
|
import { SourceFileCache } from './source-file-cache';
|
|
@@ -13,9 +14,6 @@ export interface CompilerPluginOptions {
|
|
|
13
14
|
sourcemap: boolean | 'external';
|
|
14
15
|
tsconfig: string;
|
|
15
16
|
jit?: boolean;
|
|
16
|
-
browserOnlyBuild?: boolean;
|
|
17
|
-
/** Skip TypeScript compilation setup. This is useful to re-use the TypeScript compilation from another plugin. */
|
|
18
|
-
noopTypeScriptCompilation?: boolean;
|
|
19
17
|
advancedOptimizations?: boolean;
|
|
20
18
|
thirdPartySourcemaps?: boolean;
|
|
21
19
|
fileReplacements?: Record<string, string>;
|
|
@@ -26,4 +24,4 @@ export interface CompilerPluginOptions {
|
|
|
26
24
|
instrumentForCoverage?: (request: string) => boolean;
|
|
27
25
|
templateUpdates?: Map<string, string>;
|
|
28
26
|
}
|
|
29
|
-
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, stylesheetBundler: ComponentStylesheetBundler): Plugin;
|
|
27
|
+
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, compilationOrFactory: AngularCompilation | (() => Promise<AngularCompilation>), stylesheetBundler: ComponentStylesheetBundler): Plugin;
|
|
@@ -56,7 +56,7 @@ const compilation_state_1 = require("./compilation-state");
|
|
|
56
56
|
const file_reference_tracker_1 = require("./file-reference-tracker");
|
|
57
57
|
const jit_plugin_callbacks_1 = require("./jit-plugin-callbacks");
|
|
58
58
|
// eslint-disable-next-line max-lines-per-function
|
|
59
|
-
function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
59
|
+
function createCompilerPlugin(pluginOptions, compilationOrFactory, stylesheetBundler) {
|
|
60
60
|
return {
|
|
61
61
|
name: 'angular-compiler',
|
|
62
62
|
// eslint-disable-next-line max-lines-per-function
|
|
@@ -94,16 +94,17 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
94
94
|
// Setup defines based on the values used by the Angular compiler-cli
|
|
95
95
|
build.initialOptions.define ??= {};
|
|
96
96
|
build.initialOptions.define['ngI18nClosureMode'] ??= 'false';
|
|
97
|
+
// The factory is only relevant for compatibility purposes with the private API.
|
|
98
|
+
// TODO: Update private API in the next major to allow compilation function factory removal here.
|
|
99
|
+
const compilation = typeof compilationOrFactory === 'function'
|
|
100
|
+
? await compilationOrFactory()
|
|
101
|
+
: compilationOrFactory;
|
|
97
102
|
// The in-memory cache of TypeScript file outputs will be used during the build in `onLoad` callbacks for TS files.
|
|
98
103
|
// A string value indicates direct TS/NG output and a Uint8Array indicates fully transformed code.
|
|
99
104
|
const typeScriptFileCache = pluginOptions.sourceFileCache?.typeScriptFileCache ??
|
|
100
105
|
new Map();
|
|
101
106
|
// The resources from component stylesheets and web workers that will be added to the build results output files
|
|
102
107
|
const additionalResults = new Map();
|
|
103
|
-
// Create new reusable compilation for the appropriate mode based on the `jit` plugin option
|
|
104
|
-
const compilation = pluginOptions.noopTypeScriptCompilation
|
|
105
|
-
? new compilation_1.NoopCompilation()
|
|
106
|
-
: await (0, compilation_1.createAngularCompilation)(!!pluginOptions.jit, !!pluginOptions.browserOnlyBuild);
|
|
107
108
|
// Compilation is initially assumed to have errors until emitted
|
|
108
109
|
let hasCompilationErrors = true;
|
|
109
110
|
// Determines if TypeScript should process JavaScript files based on tsconfig `allowJs` option
|
|
@@ -128,8 +129,8 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
128
129
|
// Angular compiler which does not have direct knowledge of transitive resource
|
|
129
130
|
// dependencies or web worker processing.
|
|
130
131
|
let modifiedFiles;
|
|
131
|
-
if (
|
|
132
|
-
|
|
132
|
+
if (!(compilation instanceof compilation_1.NoopCompilation) &&
|
|
133
|
+
pluginOptions.sourceFileCache?.modifiedFiles.size) {
|
|
133
134
|
// TODO: Differentiate between changed input files and stale output files
|
|
134
135
|
modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles);
|
|
135
136
|
pluginOptions.sourceFileCache.invalidate(modifiedFiles);
|
|
@@ -141,9 +142,7 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
141
142
|
// Remove any stale additional results based on modified files
|
|
142
143
|
modifiedFiles.forEach((file) => additionalResults.delete(file));
|
|
143
144
|
}
|
|
144
|
-
if (
|
|
145
|
-
compilation.update &&
|
|
146
|
-
pluginOptions.sourceFileCache?.modifiedFiles.size) {
|
|
145
|
+
if (compilation.update && pluginOptions.sourceFileCache?.modifiedFiles.size) {
|
|
147
146
|
await compilation.update(modifiedFiles ?? pluginOptions.sourceFileCache.modifiedFiles);
|
|
148
147
|
}
|
|
149
148
|
// Create Angular compiler host options
|
|
@@ -523,6 +522,18 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
|
|
|
523
522
|
notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }],
|
|
524
523
|
});
|
|
525
524
|
}
|
|
525
|
+
if (compilerOptions.isolatedModules && compilerOptions.emitDecoratorMetadata) {
|
|
526
|
+
setupWarnings?.push({
|
|
527
|
+
text: `TypeScript compiler option 'isolatedModules' may prevent the 'emitDecoratorMetadata' option from emitting all metadata.`,
|
|
528
|
+
location: null,
|
|
529
|
+
notes: [
|
|
530
|
+
{
|
|
531
|
+
text: `The 'emitDecoratorMetadata' option is not required by Angular` +
|
|
532
|
+
'and can be removed if not explictly required by the project.',
|
|
533
|
+
},
|
|
534
|
+
],
|
|
535
|
+
});
|
|
536
|
+
}
|
|
526
537
|
// Synchronize custom resolve conditions.
|
|
527
538
|
// Set if using the supported bundler resolution mode (bundler is the default in new projects)
|
|
528
539
|
if (compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { Plugin } from 'esbuild';
|
|
9
|
+
/**
|
|
10
|
+
* This plugin addresses an issue where '@angular/localize/init' is directly imported,
|
|
11
|
+
* potentially resulting in undefined behavior. By detecting such imports, the plugin
|
|
12
|
+
* issues a warning and suggests including '@angular/localize/init' as a polyfill.
|
|
13
|
+
*
|
|
14
|
+
* @returns An esbuild plugin.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createAngularLocalizeInitWarningPlugin(): Plugin;
|
|
@@ -0,0 +1,49 @@
|
|
|
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.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createAngularLocalizeInitWarningPlugin = createAngularLocalizeInitWarningPlugin;
|
|
11
|
+
const NG_LOCALIZE_RESOLUTION = Symbol('NG_LOCALIZE_RESOLUTION');
|
|
12
|
+
/**
|
|
13
|
+
* This plugin addresses an issue where '@angular/localize/init' is directly imported,
|
|
14
|
+
* potentially resulting in undefined behavior. By detecting such imports, the plugin
|
|
15
|
+
* issues a warning and suggests including '@angular/localize/init' as a polyfill.
|
|
16
|
+
*
|
|
17
|
+
* @returns An esbuild plugin.
|
|
18
|
+
*/
|
|
19
|
+
function createAngularLocalizeInitWarningPlugin() {
|
|
20
|
+
return {
|
|
21
|
+
name: 'angular-localize-init-warning',
|
|
22
|
+
setup(build) {
|
|
23
|
+
build.onResolve({ filter: /^@angular\/localize\/init/ }, async (args) => {
|
|
24
|
+
if (args.pluginData?.[NG_LOCALIZE_RESOLUTION]) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
|
|
28
|
+
pluginData[NG_LOCALIZE_RESOLUTION] = true;
|
|
29
|
+
const result = await build.resolve(args.path, {
|
|
30
|
+
importer,
|
|
31
|
+
kind,
|
|
32
|
+
namespace,
|
|
33
|
+
pluginData,
|
|
34
|
+
resolveDir,
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
...result,
|
|
38
|
+
warnings: [
|
|
39
|
+
...result.warnings,
|
|
40
|
+
{
|
|
41
|
+
text: `Direct import of '@angular/localize/init' detected. This may lead to undefined behavior.`,
|
|
42
|
+
notes: [{ text: `Include '@angular/localize/init' as a polyfill instead.` }],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { BuildOptions } from 'esbuild';
|
|
9
9
|
import type { NormalizedApplicationBuildOptions } from '../../builders/application/options';
|
|
10
|
+
import { AngularCompilation } from '../angular/compilation';
|
|
10
11
|
import { ComponentStylesheetBundler } from './angular/component-stylesheets';
|
|
11
12
|
import { SourceFileCache } from './angular/source-file-cache';
|
|
12
13
|
import { BundlerOptionsFactory } from './bundler-context';
|
|
13
14
|
import type { LoadResultCache } from './load-result-cache';
|
|
14
|
-
export declare function createBrowserCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler, templateUpdates: Map<string, string> | undefined): BundlerOptionsFactory;
|
|
15
|
+
export declare function createBrowserCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler, angularCompilation: AngularCompilation, templateUpdates: Map<string, string> | undefined): BundlerOptionsFactory;
|
|
15
16
|
export declare function createBrowserPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BuildOptions | BundlerOptionsFactory | undefined;
|
|
16
17
|
export declare function createServerPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], loadResultCache: LoadResultCache | undefined): BundlerOptionsFactory | undefined;
|
|
17
18
|
export declare function createServerMainCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BundlerOptionsFactory;
|
|
@@ -21,7 +21,9 @@ const node_path_1 = require("node:path");
|
|
|
21
21
|
const schema_1 = require("../../builders/application/schema");
|
|
22
22
|
const environment_options_1 = require("../../utils/environment-options");
|
|
23
23
|
const manifest_1 = require("../../utils/server-rendering/manifest");
|
|
24
|
+
const compilation_1 = require("../angular/compilation");
|
|
24
25
|
const compiler_plugin_1 = require("./angular/compiler-plugin");
|
|
26
|
+
const angular_localize_init_warning_plugin_1 = require("./angular-localize-init-warning-plugin");
|
|
25
27
|
const compiler_plugin_options_1 = require("./compiler-plugin-options");
|
|
26
28
|
const external_packages_plugin_1 = require("./external-packages-plugin");
|
|
27
29
|
const i18n_locale_plugin_1 = require("./i18n-locale-plugin");
|
|
@@ -32,7 +34,7 @@ const sourcemap_ignorelist_plugin_1 = require("./sourcemap-ignorelist-plugin");
|
|
|
32
34
|
const utils_1 = require("./utils");
|
|
33
35
|
const virtual_module_plugin_1 = require("./virtual-module-plugin");
|
|
34
36
|
const wasm_plugin_1 = require("./wasm-plugin");
|
|
35
|
-
function createBrowserCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler, templateUpdates) {
|
|
37
|
+
function createBrowserCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler, angularCompilation, templateUpdates) {
|
|
36
38
|
return (loadCache) => {
|
|
37
39
|
const { entryPoints, outputNames, polyfills } = options;
|
|
38
40
|
const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache, loadCache, templateUpdates);
|
|
@@ -53,9 +55,10 @@ function createBrowserCodeBundleOptions(options, target, sourceFileCache, styles
|
|
|
53
55
|
(0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
|
|
54
56
|
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: loadCache }),
|
|
55
57
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
58
|
+
(0, angular_localize_init_warning_plugin_1.createAngularLocalizeInitWarningPlugin)(),
|
|
56
59
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
57
60
|
// JS/TS options
|
|
58
|
-
pluginOptions,
|
|
61
|
+
pluginOptions, angularCompilation,
|
|
59
62
|
// Component stylesheet bundler
|
|
60
63
|
stylesheetBundler),
|
|
61
64
|
],
|
|
@@ -63,19 +66,7 @@ function createBrowserCodeBundleOptions(options, target, sourceFileCache, styles
|
|
|
63
66
|
if (options.plugins) {
|
|
64
67
|
buildOptions.plugins?.push(...options.plugins);
|
|
65
68
|
}
|
|
66
|
-
|
|
67
|
-
// Package files affected by a customized loader should not be implicitly marked as external
|
|
68
|
-
if (options.loaderExtensions ||
|
|
69
|
-
options.plugins ||
|
|
70
|
-
typeof options.externalPackages === 'object') {
|
|
71
|
-
// Plugin must be added after custom plugins to ensure any added loader options are considered
|
|
72
|
-
buildOptions.plugins?.push((0, external_packages_plugin_1.createExternalPackagesPlugin)(options.externalPackages !== true ? options.externalPackages : undefined));
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
// Safe to use the packages external option directly
|
|
76
|
-
buildOptions.packages = 'external';
|
|
77
|
-
}
|
|
78
|
-
}
|
|
69
|
+
appendOptionsForExternalPackages(options, buildOptions);
|
|
79
70
|
return buildOptions;
|
|
80
71
|
};
|
|
81
72
|
}
|
|
@@ -107,7 +98,9 @@ function createBrowserPolyfillBundleOptions(options, target, sourceFileCache, st
|
|
|
107
98
|
const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache);
|
|
108
99
|
buildOptions.plugins.push((0, compiler_plugin_1.createCompilerPlugin)(
|
|
109
100
|
// JS/TS options
|
|
110
|
-
|
|
101
|
+
pluginOptions,
|
|
102
|
+
// Browser compilation handles the actual Angular code compilation
|
|
103
|
+
new compilation_1.NoopCompilation(),
|
|
111
104
|
// Component stylesheet options are unused for polyfills but required by the plugin
|
|
112
105
|
stylesheetBundler));
|
|
113
106
|
}
|
|
@@ -196,18 +189,18 @@ function createServerMainCodeBundleOptions(options, target, sourceFileCache, sty
|
|
|
196
189
|
plugins: [
|
|
197
190
|
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: loadResultCache }),
|
|
198
191
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
192
|
+
(0, angular_localize_init_warning_plugin_1.createAngularLocalizeInitWarningPlugin)(),
|
|
199
193
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
200
194
|
// JS/TS options
|
|
201
|
-
|
|
195
|
+
pluginOptions,
|
|
196
|
+
// Browser compilation handles the actual Angular code compilation
|
|
197
|
+
new compilation_1.NoopCompilation(),
|
|
202
198
|
// Component stylesheet bundler
|
|
203
199
|
stylesheetBundler),
|
|
204
200
|
],
|
|
205
201
|
};
|
|
206
202
|
buildOptions.plugins ??= [];
|
|
207
|
-
if (externalPackages) {
|
|
208
|
-
buildOptions.packages = 'external';
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
203
|
+
if (!externalPackages) {
|
|
211
204
|
buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
|
|
212
205
|
}
|
|
213
206
|
// Mark manifest and polyfills file as external as these are generated by a different bundle step.
|
|
@@ -266,6 +259,7 @@ function createServerMainCodeBundleOptions(options, target, sourceFileCache, sty
|
|
|
266
259
|
if (options.plugins) {
|
|
267
260
|
buildOptions.plugins.push(...options.plugins);
|
|
268
261
|
}
|
|
262
|
+
appendOptionsForExternalPackages(options, buildOptions);
|
|
269
263
|
return buildOptions;
|
|
270
264
|
};
|
|
271
265
|
}
|
|
@@ -299,18 +293,18 @@ function createSsrEntryCodeBundleOptions(options, target, sourceFileCache, style
|
|
|
299
293
|
supported: (0, utils_1.getFeatureSupport)(target, true),
|
|
300
294
|
plugins: [
|
|
301
295
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
296
|
+
(0, angular_localize_init_warning_plugin_1.createAngularLocalizeInitWarningPlugin)(),
|
|
302
297
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
303
298
|
// JS/TS options
|
|
304
|
-
|
|
299
|
+
pluginOptions,
|
|
300
|
+
// Browser compilation handles the actual Angular code compilation
|
|
301
|
+
new compilation_1.NoopCompilation(),
|
|
305
302
|
// Component stylesheet bundler
|
|
306
303
|
stylesheetBundler),
|
|
307
304
|
],
|
|
308
305
|
};
|
|
309
306
|
buildOptions.plugins ??= [];
|
|
310
|
-
if (externalPackages) {
|
|
311
|
-
buildOptions.packages = 'external';
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
307
|
+
if (!externalPackages) {
|
|
314
308
|
buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
|
|
315
309
|
}
|
|
316
310
|
// Mark manifest file as external. As this will be generated later on.
|
|
@@ -366,6 +360,7 @@ function createSsrEntryCodeBundleOptions(options, target, sourceFileCache, style
|
|
|
366
360
|
if (options.plugins) {
|
|
367
361
|
buildOptions.plugins.push(...options.plugins);
|
|
368
362
|
}
|
|
363
|
+
appendOptionsForExternalPackages(options, buildOptions);
|
|
369
364
|
return buildOptions;
|
|
370
365
|
};
|
|
371
366
|
}
|
|
@@ -524,3 +519,19 @@ function entryFileToWorkspaceRelative(workspaceRoot, entryFile) {
|
|
|
524
519
|
.replace(/.[mc]?ts$/, '')
|
|
525
520
|
.replace(/\\/g, '/'));
|
|
526
521
|
}
|
|
522
|
+
function appendOptionsForExternalPackages(options, buildOptions) {
|
|
523
|
+
if (!options.externalPackages) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
buildOptions.plugins ??= [];
|
|
527
|
+
// Package files affected by a customized loader should not be implicitly marked as external
|
|
528
|
+
if (options.loaderExtensions || options.plugins || typeof options.externalPackages === 'object') {
|
|
529
|
+
// Plugin must be added after custom plugins to ensure any added loader options are considered
|
|
530
|
+
buildOptions.plugins.push((0, external_packages_plugin_1.createExternalPackagesPlugin)(options.externalPackages !== true ? options.externalPackages : undefined));
|
|
531
|
+
buildOptions.packages = undefined;
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
// Safe to use the packages external option directly
|
|
535
|
+
buildOptions.packages = 'external';
|
|
536
|
+
}
|
|
537
|
+
}
|
|
@@ -22,7 +22,11 @@ export interface RebuildState {
|
|
|
22
22
|
componentStyleBundler: ComponentStylesheetBundler;
|
|
23
23
|
codeBundleCache?: SourceFileCache;
|
|
24
24
|
fileChanges: ChangedFiles;
|
|
25
|
-
|
|
25
|
+
previousOutputInfo: ReadonlyMap<string, {
|
|
26
|
+
hash: string;
|
|
27
|
+
type: BuildOutputFileType;
|
|
28
|
+
}>;
|
|
29
|
+
previousAssetsInfo: ReadonlyMap<string, string>;
|
|
26
30
|
templateUpdates?: Map<string, string>;
|
|
27
31
|
}
|
|
28
32
|
export interface ExternalResultMetadata {
|
|
@@ -81,8 +85,11 @@ export declare class ExecutionResult {
|
|
|
81
85
|
errors: (PartialMessage | Message)[];
|
|
82
86
|
externalMetadata: ExternalResultMetadata | undefined;
|
|
83
87
|
};
|
|
84
|
-
get watchFiles(): string[]
|
|
88
|
+
get watchFiles(): Readonly<string[]>;
|
|
85
89
|
createRebuildState(fileChanges: ChangedFiles): RebuildState;
|
|
86
|
-
findChangedFiles(previousOutputHashes:
|
|
90
|
+
findChangedFiles(previousOutputHashes: ReadonlyMap<string, {
|
|
91
|
+
hash: string;
|
|
92
|
+
type: BuildOutputFileType;
|
|
93
|
+
}>): Set<string>;
|
|
87
94
|
dispose(): Promise<void>;
|
|
88
95
|
}
|
|
@@ -103,16 +103,18 @@ class ExecutionResult {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
get watchFiles() {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.
|
|
110
|
-
|
|
106
|
+
const { typescriptContexts, otherContexts } = this.rebuildContexts;
|
|
107
|
+
return [
|
|
108
|
+
// Bundler contexts internally normalize file dependencies.
|
|
109
|
+
...typescriptContexts.flatMap((context) => [...context.watchFiles]),
|
|
110
|
+
...otherContexts.flatMap((context) => [...context.watchFiles]),
|
|
111
111
|
// These files originate from TS/NG and can have POSIX path separators even on Windows.
|
|
112
112
|
// To ensure path comparisons are valid, all these paths must be normalized.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
...(this.codeBundleCache?.referencedFiles?.map(node_path_1.normalize) ?? []),
|
|
114
|
+
// The assets source files.
|
|
115
|
+
...this.assetFiles.map(({ source }) => source),
|
|
116
|
+
...this.extraWatchFiles,
|
|
117
|
+
];
|
|
116
118
|
}
|
|
117
119
|
createRebuildState(fileChanges) {
|
|
118
120
|
return {
|
|
@@ -120,14 +122,15 @@ class ExecutionResult {
|
|
|
120
122
|
codeBundleCache: this.codeBundleCache,
|
|
121
123
|
componentStyleBundler: this.componentStyleBundler,
|
|
122
124
|
fileChanges,
|
|
123
|
-
|
|
125
|
+
previousOutputInfo: new Map(this.outputFiles.map(({ path, hash, type }) => [path, { hash, type }])),
|
|
126
|
+
previousAssetsInfo: new Map(this.assetFiles.map(({ source, destination }) => [source, destination])),
|
|
124
127
|
templateUpdates: this.templateUpdates,
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
findChangedFiles(previousOutputHashes) {
|
|
128
131
|
const changed = new Set();
|
|
129
132
|
for (const file of this.outputFiles) {
|
|
130
|
-
const previousHash = previousOutputHashes.get(file.path);
|
|
133
|
+
const previousHash = previousOutputHashes.get(file.path)?.hash;
|
|
131
134
|
if (previousHash === undefined || previousHash !== file.hash) {
|
|
132
135
|
changed.add(file.path);
|
|
133
136
|
}
|
|
@@ -12,7 +12,6 @@ function createCompilerPluginOptions(options, sourceFileCache, loadResultCache,
|
|
|
12
12
|
const { sourcemapOptions, tsconfig, fileReplacements, advancedOptimizations, jit, externalRuntimeStyles, instrumentForCoverage, } = options;
|
|
13
13
|
const incremental = !!options.watch;
|
|
14
14
|
return {
|
|
15
|
-
browserOnlyBuild: !options.serverEntryPoint,
|
|
16
15
|
sourcemap: !!sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true),
|
|
17
16
|
thirdPartySourcemaps: sourcemapOptions.vendor,
|
|
18
17
|
tsconfig,
|
|
@@ -39,12 +39,16 @@ class JavaScriptTransformer {
|
|
|
39
39
|
this.#fileCacheKeyBase = Buffer.from(JSON.stringify(this.#commonOptions), 'utf-8');
|
|
40
40
|
}
|
|
41
41
|
#ensureWorkerPool() {
|
|
42
|
-
|
|
42
|
+
const workerPoolOptions = {
|
|
43
43
|
filename: require.resolve('./javascript-transformer-worker'),
|
|
44
44
|
maxThreads: this.maxThreads,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
};
|
|
46
|
+
// Prevent passing SSR `--import` (loader-hooks) from parent to child worker.
|
|
47
|
+
const filteredExecArgv = process.execArgv.filter((v) => v !== utils_1.IMPORT_EXEC_ARGV);
|
|
48
|
+
if (process.execArgv.length !== filteredExecArgv.length) {
|
|
49
|
+
workerPoolOptions.execArgv = filteredExecArgv;
|
|
50
|
+
}
|
|
51
|
+
this.#workerPool ??= new worker_pool_1.WorkerPool(workerPoolOptions);
|
|
48
52
|
return this.#workerPool;
|
|
49
53
|
}
|
|
50
54
|
/**
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
import type { Connect, ViteDevServer } from 'vite';
|
|
9
|
-
import { AngularMemoryOutputFiles } from '../utils';
|
|
9
|
+
import { AngularMemoryOutputFiles, AngularOutputAssets } from '../utils';
|
|
10
10
|
export interface ComponentStyleRecord {
|
|
11
11
|
rawContent: Uint8Array;
|
|
12
12
|
used?: Set<string>;
|
|
13
13
|
reload?: boolean;
|
|
14
14
|
}
|
|
15
|
-
export declare function createAngularAssetsMiddleware(server: ViteDevServer, assets:
|
|
15
|
+
export declare function createAngularAssetsMiddleware(server: ViteDevServer, assets: AngularOutputAssets, outputFiles: AngularMemoryOutputFiles, componentStyles: Map<string, ComponentStyleRecord>, encapsulateStyle: (style: Uint8Array, componentId: string) => string): Connect.NextHandleFunction;
|
|
@@ -22,15 +22,15 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
22
22
|
const extension = (0, node_path_1.extname)(pathname);
|
|
23
23
|
const pathnameHasTrailingSlash = pathname[pathname.length - 1] === '/';
|
|
24
24
|
// Rewrite all build assets to a vite raw fs URL
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
25
|
+
const asset = assets.get(pathname);
|
|
26
|
+
if (asset) {
|
|
27
27
|
// Workaround to disable Vite transformer middleware.
|
|
28
28
|
// See: https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/middlewares/transform.ts#L201 and
|
|
29
29
|
// https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/transformRequest.ts#L204-L206
|
|
30
30
|
req.headers.accept = 'text/html';
|
|
31
31
|
// The encoding needs to match what happens in the vite static middleware.
|
|
32
32
|
// ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
|
|
33
|
-
req.url = `${server.config.base}@fs/${encodeURI(
|
|
33
|
+
req.url = `${server.config.base}@fs/${encodeURI(asset.source)}`;
|
|
34
34
|
next();
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
@@ -43,7 +43,7 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
43
43
|
: // Non-trailing slash check for fallback `.html`
|
|
44
44
|
assets.get(pathname + '.html');
|
|
45
45
|
if (htmlAssetSourcePath) {
|
|
46
|
-
req.url = `${server.config.base}@fs/${encodeURI(htmlAssetSourcePath)}`;
|
|
46
|
+
req.url = `${server.config.base}@fs/${encodeURI(htmlAssetSourcePath.source)}`;
|
|
47
47
|
next();
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -16,6 +16,7 @@ const promises_1 = require("node:fs/promises");
|
|
|
16
16
|
const node_path_1 = require("node:path");
|
|
17
17
|
const load_esm_1 = require("../../../utils/load-esm");
|
|
18
18
|
const ANGULAR_PREFIX = '/@ng/';
|
|
19
|
+
const VITE_FS_PREFIX = '/@fs/';
|
|
19
20
|
async function createAngularMemoryPlugin(options) {
|
|
20
21
|
const { virtualProjectRoot, outputFiles, external } = options;
|
|
21
22
|
const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
@@ -24,6 +25,9 @@ async function createAngularMemoryPlugin(options) {
|
|
|
24
25
|
// Ensures plugin hooks run before built-in Vite hooks
|
|
25
26
|
enforce: 'pre',
|
|
26
27
|
async resolveId(source, importer, { ssr }) {
|
|
28
|
+
if (source.startsWith(VITE_FS_PREFIX)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
27
31
|
// For SSR with component HMR, pass through as a virtual module
|
|
28
32
|
if (ssr && source.startsWith(ANGULAR_PREFIX)) {
|
|
29
33
|
return '\0' + source;
|
|
@@ -35,25 +39,26 @@ async function createAngularMemoryPlugin(options) {
|
|
|
35
39
|
return source;
|
|
36
40
|
}
|
|
37
41
|
if (importer) {
|
|
38
|
-
|
|
42
|
+
const normalizedImporter = normalizePath(importer);
|
|
43
|
+
if (source[0] === '.' && normalizedImporter.startsWith(virtualProjectRoot)) {
|
|
39
44
|
// Remove query if present
|
|
40
|
-
const [importerFile] =
|
|
45
|
+
const [importerFile] = normalizedImporter.split('?', 1);
|
|
41
46
|
source = '/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), source);
|
|
42
47
|
}
|
|
43
48
|
else if (!ssr &&
|
|
44
49
|
source[0] === '/' &&
|
|
45
50
|
importer.endsWith('index.html') &&
|
|
46
|
-
|
|
51
|
+
normalizedImporter.startsWith(virtualProjectRoot)) {
|
|
47
52
|
// This is only needed when using SSR and `angularSsrMiddleware` (old style) to correctly resolve
|
|
48
53
|
// .js files when using lazy-loading.
|
|
49
54
|
// Remove query if present
|
|
50
|
-
const [importerFile] =
|
|
55
|
+
const [importerFile] = normalizedImporter.split('?', 1);
|
|
51
56
|
source =
|
|
52
57
|
'/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), (0, node_path_1.basename)(source));
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
const [file] = source.split('?', 1);
|
|
56
|
-
if (outputFiles.has(file)) {
|
|
61
|
+
if (outputFiles.has(normalizePath(file))) {
|
|
57
62
|
return (0, node_path_1.join)(virtualProjectRoot, source);
|
|
58
63
|
}
|
|
59
64
|
},
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Connect, Plugin } from 'vite';
|
|
9
9
|
import { ComponentStyleRecord } from '../middlewares';
|
|
10
|
-
import { AngularMemoryOutputFiles } from '../utils';
|
|
10
|
+
import { AngularMemoryOutputFiles, AngularOutputAssets } from '../utils';
|
|
11
11
|
export declare enum ServerSsrMode {
|
|
12
12
|
/**
|
|
13
13
|
* No SSR
|
|
@@ -32,7 +32,7 @@ export declare enum ServerSsrMode {
|
|
|
32
32
|
}
|
|
33
33
|
interface AngularSetupMiddlewaresPluginOptions {
|
|
34
34
|
outputFiles: AngularMemoryOutputFiles;
|
|
35
|
-
assets:
|
|
35
|
+
assets: AngularOutputAssets;
|
|
36
36
|
extensionMiddleware?: Connect.NextHandleFunction[];
|
|
37
37
|
indexHtmlTransformer?: (content: string) => Promise<string>;
|
|
38
38
|
componentStyles: Map<string, ComponentStyleRecord>;
|
|
@@ -12,10 +12,13 @@ export type AngularMemoryOutputFiles = Map<string, {
|
|
|
12
12
|
hash: string;
|
|
13
13
|
servable: boolean;
|
|
14
14
|
}>;
|
|
15
|
+
export type AngularOutputAssets = Map<string, {
|
|
16
|
+
source: string;
|
|
17
|
+
}>;
|
|
15
18
|
export declare function pathnameWithoutBasePath(url: string, basePath: string): string;
|
|
16
19
|
export declare function lookupMimeTypeFromRequest(url: string): string | undefined;
|
|
17
20
|
export type EsbuildLoaderOption = Exclude<DepOptimizationConfig['esbuildOptions'], undefined>['loader'];
|
|
18
|
-
export declare function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless, prebundleTransformer, ssr, loader, thirdPartySourcemaps, }: {
|
|
21
|
+
export declare function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless, prebundleTransformer, ssr, loader, thirdPartySourcemaps, define, }: {
|
|
19
22
|
disabled: boolean;
|
|
20
23
|
exclude: string[];
|
|
21
24
|
include: string[];
|
|
@@ -25,4 +28,5 @@ export declare function getDepOptimizationConfig({ disabled, exclude, include, t
|
|
|
25
28
|
zoneless: boolean;
|
|
26
29
|
loader?: EsbuildLoaderOption;
|
|
27
30
|
thirdPartySourcemaps: boolean;
|
|
31
|
+
define: Record<string, string> | undefined;
|
|
28
32
|
}): DepOptimizationConfig;
|
package/src/tools/vite/utils.js
CHANGED
|
@@ -28,7 +28,7 @@ function lookupMimeTypeFromRequest(url) {
|
|
|
28
28
|
}
|
|
29
29
|
return extension && (0, mrmime_1.lookup)(extension);
|
|
30
30
|
}
|
|
31
|
-
function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless, prebundleTransformer, ssr, loader, thirdPartySourcemaps, }) {
|
|
31
|
+
function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless, prebundleTransformer, ssr, loader, thirdPartySourcemaps, define = {}, }) {
|
|
32
32
|
const plugins = [
|
|
33
33
|
{
|
|
34
34
|
name: `angular-vite-optimize-deps${ssr ? '-ssr' : ''}${thirdPartySourcemaps ? '-vendor-sourcemap' : ''}`,
|
|
@@ -57,6 +57,7 @@ function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless
|
|
|
57
57
|
plugins,
|
|
58
58
|
loader,
|
|
59
59
|
define: {
|
|
60
|
+
...define,
|
|
60
61
|
'ngServerMode': `${ssr}`,
|
|
61
62
|
},
|
|
62
63
|
resolveExtensions: ['.mjs', '.js', '.cjs'],
|
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.ThresholdSeverity = exports.BudgetType = void 0;
|
|
10
|
+
exports.ThresholdSeverity = exports.BYTES_IN_KILOBYTE = exports.BudgetType = void 0;
|
|
11
11
|
exports.calculateThresholds = calculateThresholds;
|
|
12
12
|
exports.checkBudgets = checkBudgets;
|
|
13
13
|
exports.checkThresholds = checkThresholds;
|
|
14
14
|
const schema_1 = require("../builders/application/schema");
|
|
15
15
|
Object.defineProperty(exports, "BudgetType", { enumerable: true, get: function () { return schema_1.Type; } });
|
|
16
16
|
const format_bytes_1 = require("./format-bytes");
|
|
17
|
+
exports.BYTES_IN_KILOBYTE = 1000;
|
|
17
18
|
var ThresholdType;
|
|
18
19
|
(function (ThresholdType) {
|
|
19
20
|
ThresholdType["Max"] = "maximum";
|
|
@@ -242,13 +243,13 @@ function calculateBytes(input, baseline, factor = 1) {
|
|
|
242
243
|
value = (baselineBytes * value) / 100;
|
|
243
244
|
break;
|
|
244
245
|
case 'kb':
|
|
245
|
-
value *=
|
|
246
|
+
value *= exports.BYTES_IN_KILOBYTE;
|
|
246
247
|
break;
|
|
247
248
|
case 'mb':
|
|
248
|
-
value *=
|
|
249
|
+
value *= exports.BYTES_IN_KILOBYTE * exports.BYTES_IN_KILOBYTE;
|
|
249
250
|
break;
|
|
250
251
|
case 'gb':
|
|
251
|
-
value *=
|
|
252
|
+
value *= exports.BYTES_IN_KILOBYTE * exports.BYTES_IN_KILOBYTE * exports.BYTES_IN_KILOBYTE;
|
|
252
253
|
break;
|
|
253
254
|
}
|
|
254
255
|
if (baselineBytes === 0) {
|
|
@@ -83,7 +83,7 @@ exports.useJSONBuildLogs = isPresent(buildLogsJsonVariable) && isEnabled(buildLo
|
|
|
83
83
|
const optimizeChunksVariable = process.env['NG_BUILD_OPTIMIZE_CHUNKS'];
|
|
84
84
|
exports.shouldOptimizeChunks = isPresent(optimizeChunksVariable) && isEnabled(optimizeChunksVariable);
|
|
85
85
|
const hmrComponentStylesVariable = process.env['NG_HMR_CSTYLES'];
|
|
86
|
-
exports.useComponentStyleHmr =
|
|
86
|
+
exports.useComponentStyleHmr = isPresent(hmrComponentStylesVariable) && isEnabled(hmrComponentStylesVariable);
|
|
87
87
|
const hmrComponentTemplateVariable = process.env['NG_HMR_TEMPLATES'];
|
|
88
88
|
exports.useComponentTemplateHmr = !isPresent(hmrComponentTemplateVariable) || !isDisabled(hmrComponentTemplateVariable);
|
|
89
89
|
const partialSsrBuildVariable = process.env['NG_BUILD_PARTIAL_SSR'];
|