@angular-devkit/build-angular 17.1.0-rc.0 → 17.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/package.json +14 -14
- package/src/builders/application/build-action.js +5 -0
- package/src/builders/application/execute-build.js +18 -77
- package/src/builders/application/index.js +3 -0
- package/src/builders/application/setup-bundling.d.ts +19 -0
- package/src/builders/application/setup-bundling.js +71 -0
- package/src/builders/dev-server/builder.d.ts +6 -0
- package/src/builders/dev-server/builder.js +28 -15
- package/src/builders/dev-server/vite-server.js +4 -0
- package/src/builders/web-test-runner/index.js +1 -1
- package/src/tools/esbuild/bundler-execution-result.d.ts +5 -1
- package/src/tools/esbuild/bundler-execution-result.js +25 -1
- package/src/tools/esbuild/utils.d.ts +3 -3
- package/src/tools/esbuild/utils.js +7 -7
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "17.1.0
|
|
3
|
+
"version": "17.1.0",
|
|
4
4
|
"description": "Angular Webpack Build Facade",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
7
7
|
"builders": "builders.json",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@ampproject/remapping": "2.2.1",
|
|
10
|
-
"@angular-devkit/architect": "0.1701.0
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1701.0
|
|
12
|
-
"@angular-devkit/core": "17.1.0
|
|
10
|
+
"@angular-devkit/architect": "0.1701.0",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1701.0",
|
|
12
|
+
"@angular-devkit/core": "17.1.0",
|
|
13
13
|
"@babel/core": "7.23.7",
|
|
14
14
|
"@babel/generator": "7.23.6",
|
|
15
15
|
"@babel/helper-annotate-as-pure": "7.22.5",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@babel/preset-env": "7.23.7",
|
|
21
21
|
"@babel/runtime": "7.23.7",
|
|
22
22
|
"@discoveryjs/json-ext": "0.5.7",
|
|
23
|
-
"@ngtools/webpack": "17.1.0
|
|
23
|
+
"@ngtools/webpack": "17.1.0",
|
|
24
24
|
"@vitejs/plugin-basic-ssl": "1.0.2",
|
|
25
25
|
"ansi-colors": "4.1.3",
|
|
26
26
|
"autoprefixer": "10.4.16",
|
|
@@ -49,21 +49,21 @@
|
|
|
49
49
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
50
50
|
"picomatch": "3.0.1",
|
|
51
51
|
"piscina": "4.2.1",
|
|
52
|
-
"postcss": "8.4.
|
|
52
|
+
"postcss": "8.4.33",
|
|
53
53
|
"postcss-loader": "7.3.4",
|
|
54
54
|
"resolve-url-loader": "5.0.0",
|
|
55
55
|
"rxjs": "7.8.1",
|
|
56
56
|
"sass": "1.69.7",
|
|
57
57
|
"sass-loader": "13.3.3",
|
|
58
58
|
"semver": "7.5.4",
|
|
59
|
-
"source-map-loader": "
|
|
59
|
+
"source-map-loader": "5.0.0",
|
|
60
60
|
"source-map-support": "0.5.21",
|
|
61
61
|
"terser": "5.26.0",
|
|
62
62
|
"text-table": "0.2.0",
|
|
63
63
|
"tree-kill": "1.2.2",
|
|
64
64
|
"tslib": "2.6.2",
|
|
65
65
|
"undici": "6.2.1",
|
|
66
|
-
"vite": "5.0.
|
|
66
|
+
"vite": "5.0.11",
|
|
67
67
|
"watchpack": "2.4.0",
|
|
68
68
|
"webpack": "5.89.0",
|
|
69
69
|
"webpack-dev-middleware": "6.1.1",
|
|
@@ -75,16 +75,16 @@
|
|
|
75
75
|
"esbuild": "0.19.11"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@angular/compiler-cli": "^17.0.0
|
|
79
|
-
"@angular/localize": "^17.0.0
|
|
80
|
-
"@angular/platform-server": "^17.0.0
|
|
81
|
-
"@angular/service-worker": "^17.0.0
|
|
82
|
-
"@web/test-runner": "^0.
|
|
78
|
+
"@angular/compiler-cli": "^17.0.0",
|
|
79
|
+
"@angular/localize": "^17.0.0",
|
|
80
|
+
"@angular/platform-server": "^17.0.0",
|
|
81
|
+
"@angular/service-worker": "^17.0.0",
|
|
82
|
+
"@web/test-runner": "^0.18.0",
|
|
83
83
|
"browser-sync": "^3.0.2",
|
|
84
84
|
"jest": "^29.5.0",
|
|
85
85
|
"jest-environment-jsdom": "^29.5.0",
|
|
86
86
|
"karma": "^6.3.0",
|
|
87
|
-
"ng-packagr": "^17.0.0
|
|
87
|
+
"ng-packagr": "^17.0.0",
|
|
88
88
|
"protractor": "^7.0.0",
|
|
89
89
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
90
90
|
"typescript": ">=5.2 <5.4"
|
|
@@ -52,7 +52,10 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
52
52
|
// Initial build
|
|
53
53
|
let result;
|
|
54
54
|
try {
|
|
55
|
+
// Perform the build action
|
|
55
56
|
result = await withProgress('Building...', () => action());
|
|
57
|
+
// Log all diagnostic (error/warning) messages from the build
|
|
58
|
+
await (0, utils_1.logMessages)(logger, result);
|
|
56
59
|
}
|
|
57
60
|
finally {
|
|
58
61
|
// Ensure Sass workers are shutdown if not watching
|
|
@@ -139,6 +142,8 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
139
142
|
logger.info(changes.toDebugString());
|
|
140
143
|
}
|
|
141
144
|
result = await withProgress('Changes detected. Rebuilding...', () => action(result.createRebuildState(changes)));
|
|
145
|
+
// Log all diagnostic (error/warning) messages from the rebuild
|
|
146
|
+
await (0, utils_1.logMessages)(logger, result);
|
|
142
147
|
// Update watched locations provided by the new build result.
|
|
143
148
|
// Keep watching all previous files if there are any errors; otherwise consider all
|
|
144
149
|
// files stale until confirmed present in the new result's watch files.
|
|
@@ -9,13 +9,10 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.executeBuild = void 0;
|
|
11
11
|
const source_file_cache_1 = require("../../tools/esbuild/angular/source-file-cache");
|
|
12
|
-
const application_code_bundle_1 = require("../../tools/esbuild/application-code-bundle");
|
|
13
12
|
const budget_stats_1 = require("../../tools/esbuild/budget-stats");
|
|
14
13
|
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
15
14
|
const bundler_execution_result_1 = require("../../tools/esbuild/bundler-execution-result");
|
|
16
15
|
const commonjs_checker_1 = require("../../tools/esbuild/commonjs-checker");
|
|
17
|
-
const global_scripts_1 = require("../../tools/esbuild/global-scripts");
|
|
18
|
-
const global_styles_1 = require("../../tools/esbuild/global-styles");
|
|
19
16
|
const license_extractor_1 = require("../../tools/esbuild/license-extractor");
|
|
20
17
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
21
18
|
const bundle_calculator_1 = require("../../utils/bundle-calculator");
|
|
@@ -24,11 +21,11 @@ const copy_assets_1 = require("../../utils/copy-assets");
|
|
|
24
21
|
const supported_browsers_1 = require("../../utils/supported-browsers");
|
|
25
22
|
const execute_post_bundle_1 = require("./execute-post-bundle");
|
|
26
23
|
const i18n_1 = require("./i18n");
|
|
27
|
-
|
|
24
|
+
const setup_bundling_1 = require("./setup-bundling");
|
|
28
25
|
async function executeBuild(options, context, rebuildState) {
|
|
29
|
-
const { projectRoot, workspaceRoot, i18nOptions, optimizationOptions,
|
|
26
|
+
const { projectRoot, workspaceRoot, i18nOptions, optimizationOptions, assets, cacheOptions, prerenderOptions, } = options;
|
|
27
|
+
// TODO: Consider integrating into watch mode. Would require full rebuild on target changes.
|
|
30
28
|
const browsers = (0, supported_browsers_1.getSupportedBrowsers)(projectRoot, context.logger);
|
|
31
|
-
const target = (0, utils_1.transformSupportedBrowsersToTargets)(browsers);
|
|
32
29
|
// Load active translations if inlining
|
|
33
30
|
// TODO: Integrate into watch mode and only load changed translations
|
|
34
31
|
if (i18nOptions.shouldInline) {
|
|
@@ -39,53 +36,11 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
39
36
|
const codeBundleCache = rebuildState?.codeBundleCache ??
|
|
40
37
|
new source_file_cache_1.SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined);
|
|
41
38
|
if (bundlerContexts === undefined) {
|
|
42
|
-
bundlerContexts =
|
|
43
|
-
// Browser application code
|
|
44
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, (0, application_code_bundle_1.createBrowserCodeBundleOptions)(options, target, codeBundleCache)));
|
|
45
|
-
// Browser polyfills code
|
|
46
|
-
const browserPolyfillBundleOptions = (0, application_code_bundle_1.createBrowserPolyfillBundleOptions)(options, target, codeBundleCache);
|
|
47
|
-
if (browserPolyfillBundleOptions) {
|
|
48
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, browserPolyfillBundleOptions));
|
|
49
|
-
}
|
|
50
|
-
// Global Stylesheets
|
|
51
|
-
if (options.globalStyles.length > 0) {
|
|
52
|
-
for (const initial of [true, false]) {
|
|
53
|
-
const bundleOptions = (0, global_styles_1.createGlobalStylesBundleOptions)(options, target, initial);
|
|
54
|
-
if (bundleOptions) {
|
|
55
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, bundleOptions, () => initial));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Global Scripts
|
|
60
|
-
if (options.globalScripts.length > 0) {
|
|
61
|
-
for (const initial of [true, false]) {
|
|
62
|
-
const bundleOptions = (0, global_scripts_1.createGlobalScriptsBundleOptions)(options, target, initial);
|
|
63
|
-
if (bundleOptions) {
|
|
64
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, bundleOptions, () => initial));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// Skip server build when none of the features are enabled.
|
|
69
|
-
if (serverEntryPoint && (prerenderOptions || appShellOptions || ssrOptions)) {
|
|
70
|
-
const nodeTargets = [...target, ...(0, utils_1.getSupportedNodeTargets)()];
|
|
71
|
-
// Server application code
|
|
72
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, (0, application_code_bundle_1.createServerCodeBundleOptions)({
|
|
73
|
-
...options,
|
|
74
|
-
// Disable external deps for server bundles.
|
|
75
|
-
// This is because it breaks Vite 'optimizeDeps' for SSR.
|
|
76
|
-
externalPackages: false,
|
|
77
|
-
}, nodeTargets, codeBundleCache), () => false));
|
|
78
|
-
// Server polyfills code
|
|
79
|
-
const serverPolyfillBundleOptions = (0, application_code_bundle_1.createServerPolyfillBundleOptions)(options, nodeTargets, codeBundleCache);
|
|
80
|
-
if (serverPolyfillBundleOptions) {
|
|
81
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, serverPolyfillBundleOptions, () => false));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
39
|
+
bundlerContexts = (0, setup_bundling_1.setupBundlerContexts)(options, browsers, codeBundleCache);
|
|
84
40
|
}
|
|
85
41
|
const bundlingResult = await bundler_context_1.BundlerContext.bundleAll(bundlerContexts, rebuildState?.fileChanges.all);
|
|
86
|
-
// Log all warnings and errors generated during bundling
|
|
87
|
-
await (0, utils_1.logMessages)(context, bundlingResult);
|
|
88
42
|
const executionResult = new bundler_execution_result_1.ExecutionResult(bundlerContexts, codeBundleCache);
|
|
43
|
+
executionResult.addWarnings(bundlingResult.warnings);
|
|
89
44
|
// Return if the bundling has errors
|
|
90
45
|
if (bundlingResult.errors) {
|
|
91
46
|
executionResult.addErrors(bundlingResult.errors);
|
|
@@ -111,14 +66,13 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
111
66
|
if (options.budgets) {
|
|
112
67
|
const compatStats = (0, budget_stats_1.generateBudgetStats)(metafile, initialFiles);
|
|
113
68
|
budgetFailures = [...(0, bundle_calculator_1.checkBudgets)(options.budgets, compatStats, true)];
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
await printWarningsAndErrorsToConsoleAndAddToResult(context, executionResult, warnings, errors);
|
|
69
|
+
for (const { message, severity } of budgetFailures) {
|
|
70
|
+
if (severity === 'error') {
|
|
71
|
+
executionResult.addError(message);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
executionResult.addWarning(message);
|
|
75
|
+
}
|
|
122
76
|
}
|
|
123
77
|
}
|
|
124
78
|
// Calculate estimated transfer size if scripts are optimized
|
|
@@ -129,7 +83,7 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
129
83
|
// Check metafile for CommonJS module usage if optimizing scripts
|
|
130
84
|
if (optimizationOptions.scripts) {
|
|
131
85
|
const messages = (0, commonjs_checker_1.checkCommonJSModules)(metafile, options.allowedCommonJsDependencies);
|
|
132
|
-
|
|
86
|
+
executionResult.addWarnings(messages);
|
|
133
87
|
}
|
|
134
88
|
// Copy assets
|
|
135
89
|
if (assets) {
|
|
@@ -143,25 +97,22 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
143
97
|
}
|
|
144
98
|
// Perform i18n translation inlining if enabled
|
|
145
99
|
let prerenderedRoutes;
|
|
146
|
-
let errors;
|
|
147
|
-
let warnings;
|
|
148
100
|
if (i18nOptions.shouldInline) {
|
|
149
101
|
const result = await (0, i18n_1.inlineI18n)(options, executionResult, initialFiles);
|
|
150
|
-
|
|
151
|
-
|
|
102
|
+
executionResult.addErrors(result.errors);
|
|
103
|
+
executionResult.addWarnings(result.warnings);
|
|
152
104
|
prerenderedRoutes = result.prerenderedRoutes;
|
|
153
105
|
}
|
|
154
106
|
else {
|
|
155
107
|
const result = await (0, execute_post_bundle_1.executePostBundleSteps)(options, executionResult.outputFiles, executionResult.assetFiles, initialFiles,
|
|
156
108
|
// Set lang attribute to the defined source locale if present
|
|
157
109
|
i18nOptions.hasDefinedSourceLocale ? i18nOptions.sourceLocale : undefined);
|
|
158
|
-
|
|
159
|
-
|
|
110
|
+
executionResult.addErrors(result.errors);
|
|
111
|
+
executionResult.addWarnings(result.warnings);
|
|
160
112
|
prerenderedRoutes = result.prerenderedRoutes;
|
|
161
113
|
executionResult.outputFiles.push(...result.additionalOutputFiles);
|
|
162
114
|
executionResult.assetFiles.push(...result.additionalAssets);
|
|
163
115
|
}
|
|
164
|
-
await printWarningsAndErrorsToConsoleAndAddToResult(context, executionResult, warnings, errors);
|
|
165
116
|
if (prerenderOptions) {
|
|
166
117
|
executionResult.addOutputFile('prerendered-routes.json', JSON.stringify({ routes: prerenderedRoutes.sort((a, b) => a.localeCompare(b)) }, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
167
118
|
let prerenderMsg = `Prerendered ${prerenderedRoutes.length} static route`;
|
|
@@ -173,7 +124,7 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
173
124
|
}
|
|
174
125
|
context.logger.info(color_1.colors.magenta(prerenderMsg) + '\n');
|
|
175
126
|
}
|
|
176
|
-
(0, utils_1.logBuildStats)(context, metafile, initialFiles, budgetFailures, changedFiles, estimatedTransferSizes);
|
|
127
|
+
(0, utils_1.logBuildStats)(context.logger, metafile, initialFiles, budgetFailures, changedFiles, estimatedTransferSizes);
|
|
177
128
|
// Write metafile if stats option is enabled
|
|
178
129
|
if (options.stats) {
|
|
179
130
|
executionResult.addOutputFile('stats.json', JSON.stringify(metafile, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
@@ -181,13 +132,3 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
181
132
|
return executionResult;
|
|
182
133
|
}
|
|
183
134
|
exports.executeBuild = executeBuild;
|
|
184
|
-
async function printWarningsAndErrorsToConsoleAndAddToResult(context, executionResult, warnings, errors) {
|
|
185
|
-
const errorMessages = errors.map((text) => ({ text, location: null }));
|
|
186
|
-
if (errorMessages.length) {
|
|
187
|
-
executionResult.addErrors(errorMessages);
|
|
188
|
-
}
|
|
189
|
-
await (0, utils_1.logMessages)(context, {
|
|
190
|
-
errors: errorMessages,
|
|
191
|
-
warnings: warnings.map((text) => ({ text, location: null })),
|
|
192
|
-
});
|
|
193
|
-
}
|
|
@@ -92,6 +92,9 @@ function buildApplication(options, context, pluginsOrExtensions) {
|
|
|
92
92
|
codePlugins: pluginsOrExtensions,
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
+
else {
|
|
96
|
+
extensions = pluginsOrExtensions;
|
|
97
|
+
}
|
|
95
98
|
return buildApplicationInternal(options, context, undefined, extensions);
|
|
96
99
|
}
|
|
97
100
|
exports.buildApplication = buildApplication;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache';
|
|
9
|
+
import { BundlerContext } from '../../tools/esbuild/bundler-context';
|
|
10
|
+
import { NormalizedApplicationBuildOptions } from './options';
|
|
11
|
+
/**
|
|
12
|
+
* Generates one or more BundlerContext instances based on the builder provided
|
|
13
|
+
* configuration.
|
|
14
|
+
* @param options The normalized application builder options to use.
|
|
15
|
+
* @param browsers An string array of browserslist browsers to support.
|
|
16
|
+
* @param codeBundleCache An instance of the TypeScript source file cache.
|
|
17
|
+
* @returns An array of BundlerContext objects.
|
|
18
|
+
*/
|
|
19
|
+
export declare function setupBundlerContexts(options: NormalizedApplicationBuildOptions, browsers: string[], codeBundleCache: SourceFileCache): BundlerContext[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.io/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.setupBundlerContexts = void 0;
|
|
11
|
+
const application_code_bundle_1 = require("../../tools/esbuild/application-code-bundle");
|
|
12
|
+
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
13
|
+
const global_scripts_1 = require("../../tools/esbuild/global-scripts");
|
|
14
|
+
const global_styles_1 = require("../../tools/esbuild/global-styles");
|
|
15
|
+
const utils_1 = require("../../tools/esbuild/utils");
|
|
16
|
+
/**
|
|
17
|
+
* Generates one or more BundlerContext instances based on the builder provided
|
|
18
|
+
* configuration.
|
|
19
|
+
* @param options The normalized application builder options to use.
|
|
20
|
+
* @param browsers An string array of browserslist browsers to support.
|
|
21
|
+
* @param codeBundleCache An instance of the TypeScript source file cache.
|
|
22
|
+
* @returns An array of BundlerContext objects.
|
|
23
|
+
*/
|
|
24
|
+
function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
25
|
+
const { appShellOptions, prerenderOptions, serverEntryPoint, ssrOptions, workspaceRoot } = options;
|
|
26
|
+
const target = (0, utils_1.transformSupportedBrowsersToTargets)(browsers);
|
|
27
|
+
const bundlerContexts = [];
|
|
28
|
+
// Browser application code
|
|
29
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, (0, application_code_bundle_1.createBrowserCodeBundleOptions)(options, target, codeBundleCache)));
|
|
30
|
+
// Browser polyfills code
|
|
31
|
+
const browserPolyfillBundleOptions = (0, application_code_bundle_1.createBrowserPolyfillBundleOptions)(options, target, codeBundleCache);
|
|
32
|
+
if (browserPolyfillBundleOptions) {
|
|
33
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, browserPolyfillBundleOptions));
|
|
34
|
+
}
|
|
35
|
+
// Global Stylesheets
|
|
36
|
+
if (options.globalStyles.length > 0) {
|
|
37
|
+
for (const initial of [true, false]) {
|
|
38
|
+
const bundleOptions = (0, global_styles_1.createGlobalStylesBundleOptions)(options, target, initial);
|
|
39
|
+
if (bundleOptions) {
|
|
40
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, bundleOptions, () => initial));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Global Scripts
|
|
45
|
+
if (options.globalScripts.length > 0) {
|
|
46
|
+
for (const initial of [true, false]) {
|
|
47
|
+
const bundleOptions = (0, global_scripts_1.createGlobalScriptsBundleOptions)(options, target, initial);
|
|
48
|
+
if (bundleOptions) {
|
|
49
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, bundleOptions, () => initial));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Skip server build when none of the features are enabled.
|
|
54
|
+
if (serverEntryPoint && (prerenderOptions || appShellOptions || ssrOptions)) {
|
|
55
|
+
const nodeTargets = [...target, ...(0, utils_1.getSupportedNodeTargets)()];
|
|
56
|
+
// Server application code
|
|
57
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, (0, application_code_bundle_1.createServerCodeBundleOptions)({
|
|
58
|
+
...options,
|
|
59
|
+
// Disable external deps for server bundles.
|
|
60
|
+
// This is because it breaks Vite 'optimizeDeps' for SSR.
|
|
61
|
+
externalPackages: false,
|
|
62
|
+
}, nodeTargets, codeBundleCache), () => false));
|
|
63
|
+
// Server polyfills code
|
|
64
|
+
const serverPolyfillBundleOptions = (0, application_code_bundle_1.createServerPolyfillBundleOptions)(options, nodeTargets, codeBundleCache);
|
|
65
|
+
if (serverPolyfillBundleOptions) {
|
|
66
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, !!options.watch, serverPolyfillBundleOptions, () => false));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return bundlerContexts;
|
|
70
|
+
}
|
|
71
|
+
exports.setupBundlerContexts = setupBundlerContexts;
|
|
@@ -38,4 +38,10 @@ export declare function execute(options: DevServerBuilderOptions, context: Build
|
|
|
38
38
|
}, extensions?: {
|
|
39
39
|
buildPlugins?: Plugin[];
|
|
40
40
|
middleware?: ((req: http.IncomingMessage, res: http.ServerResponse, next: (err?: unknown) => void) => void)[];
|
|
41
|
+
builderSelector?: (info: BuilderSelectorInfo, logger: BuilderContext['logger']) => string;
|
|
41
42
|
}): Observable<DevServerBuilderOutput>;
|
|
43
|
+
interface BuilderSelectorInfo {
|
|
44
|
+
builderName: string;
|
|
45
|
+
forceEsbuild: boolean;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
@@ -57,19 +57,12 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
57
57
|
context.logger.error(`The 'dev-server' builder requires a target to be specified.`);
|
|
58
58
|
return rxjs_1.EMPTY;
|
|
59
59
|
}
|
|
60
|
-
return (0, rxjs_1.defer)(() => initialize(options, projectName, context)).pipe((0, rxjs_1.switchMap)(({ builderName, normalizedOptions }) => {
|
|
60
|
+
return (0, rxjs_1.defer)(() => initialize(options, projectName, context, extensions?.builderSelector)).pipe((0, rxjs_1.switchMap)(({ builderName, normalizedOptions }) => {
|
|
61
61
|
// Use vite-based development server for esbuild-based builds
|
|
62
|
-
if (builderName
|
|
63
|
-
builderName === '@angular-devkit/build-angular:browser-esbuild' ||
|
|
64
|
-
normalizedOptions.forceEsbuild) {
|
|
62
|
+
if (isEsbuildBased(builderName)) {
|
|
65
63
|
if (transforms?.logging || transforms?.webpackConfiguration) {
|
|
66
64
|
throw new Error('The `application` and `browser-esbuild` builders do not support Webpack transforms.');
|
|
67
65
|
}
|
|
68
|
-
if (normalizedOptions.forceEsbuild &&
|
|
69
|
-
builderName === '@angular-devkit/build-angular:browser') {
|
|
70
|
-
// The compatibility builder should be used if esbuild is force enabled with the official Webpack-based builder.
|
|
71
|
-
builderName = '@angular-devkit/build-angular:browser-esbuild';
|
|
72
|
-
}
|
|
73
66
|
return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./vite-server')))).pipe((0, rxjs_1.switchMap)(({ serveWithVite }) => serveWithVite(normalizedOptions, builderName, context, transforms, extensions)));
|
|
74
67
|
}
|
|
75
68
|
if (extensions?.buildPlugins?.length) {
|
|
@@ -83,7 +76,7 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
83
76
|
}));
|
|
84
77
|
}
|
|
85
78
|
exports.execute = execute;
|
|
86
|
-
async function initialize(initialOptions, projectName, context) {
|
|
79
|
+
async function initialize(initialOptions, projectName, context, builderSelector = defaultBuilderSelector) {
|
|
87
80
|
// Purge old build disk cache.
|
|
88
81
|
await (0, purge_cache_1.purgeStaleBuildCache)(context);
|
|
89
82
|
const normalizedOptions = await (0, options_1.normalizeOptions)(context, projectName, initialOptions);
|
|
@@ -105,10 +98,30 @@ case.
|
|
|
105
98
|
context.logger.warn('Warning: Running a server with --disable-host-check is a security risk. ' +
|
|
106
99
|
'See https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a for more information.');
|
|
107
100
|
}
|
|
108
|
-
if (normalizedOptions.forceEsbuild && !builderName.startsWith('@angular-devkit/build-angular:')) {
|
|
109
|
-
context.logger.warn('Warning: Forcing the use of the esbuild-based build system with third-party builders' +
|
|
110
|
-
' may cause unexpected behavior and/or build failures.');
|
|
111
|
-
}
|
|
112
101
|
normalizedOptions.port = await (0, check_port_1.checkPort)(normalizedOptions.port, normalizedOptions.host);
|
|
113
|
-
return {
|
|
102
|
+
return {
|
|
103
|
+
builderName: builderSelector({ builderName, forceEsbuild: !!normalizedOptions.forceEsbuild }, context.logger),
|
|
104
|
+
normalizedOptions,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function isEsbuildBased(builderName) {
|
|
108
|
+
if (builderName === '@angular-devkit/build-angular:application' ||
|
|
109
|
+
builderName === '@angular-devkit/build-angular:browser-esbuild') {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
function defaultBuilderSelector(info, logger) {
|
|
115
|
+
if (isEsbuildBased(info.builderName)) {
|
|
116
|
+
return info.builderName;
|
|
117
|
+
}
|
|
118
|
+
if (info.forceEsbuild) {
|
|
119
|
+
if (!info.builderName.startsWith('@angular-devkit/build-angular:')) {
|
|
120
|
+
logger.warn('Warning: Forcing the use of the esbuild-based build system with third-party builders' +
|
|
121
|
+
' may cause unexpected behavior and/or build failures.');
|
|
122
|
+
}
|
|
123
|
+
// The compatibility builder should be used if esbuild is force enabled.
|
|
124
|
+
return '@angular-devkit/build-angular:browser-esbuild';
|
|
125
|
+
}
|
|
126
|
+
return info.builderName;
|
|
114
127
|
}
|
|
@@ -361,6 +361,10 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
361
361
|
open: serverOptions.open,
|
|
362
362
|
headers: serverOptions.headers,
|
|
363
363
|
proxy,
|
|
364
|
+
cors: {
|
|
365
|
+
// Allow preflight requests to be proxied.
|
|
366
|
+
preflightContinue: true,
|
|
367
|
+
},
|
|
364
368
|
// File watching is handled by the build directly. `null` disables file watching for Vite.
|
|
365
369
|
watch: null,
|
|
366
370
|
fs: {
|
|
@@ -41,7 +41,7 @@ exports.default = (0, architect_1.createBuilder)(async (schema, ctx) => {
|
|
|
41
41
|
// Parallelize startup work.
|
|
42
42
|
const [testFiles] = await Promise.all([
|
|
43
43
|
// Glob for files to test.
|
|
44
|
-
(0, test_files_1.findTestFiles)(options.include, options.exclude, ctx.workspaceRoot)
|
|
44
|
+
(0, test_files_1.findTestFiles)(options.include, options.exclude, ctx.workspaceRoot),
|
|
45
45
|
// Clean build output path.
|
|
46
46
|
node_fs_1.promises.rm(testDir, { recursive: true, force: true }),
|
|
47
47
|
]);
|
|
@@ -33,11 +33,15 @@ export declare class ExecutionResult {
|
|
|
33
33
|
outputFiles: BuildOutputFile[];
|
|
34
34
|
assetFiles: BuildOutputAsset[];
|
|
35
35
|
errors: (Message | PartialMessage)[];
|
|
36
|
+
warnings: (Message | PartialMessage)[];
|
|
36
37
|
externalMetadata?: ExternalResultMetadata;
|
|
37
38
|
constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
|
|
38
39
|
addOutputFile(path: string, content: string, type: BuildOutputFileType): void;
|
|
39
40
|
addAssets(assets: BuildOutputAsset[]): void;
|
|
40
|
-
|
|
41
|
+
addError(error: PartialMessage | string): void;
|
|
42
|
+
addErrors(errors: (PartialMessage | string)[]): void;
|
|
43
|
+
addWarning(error: PartialMessage | string): void;
|
|
44
|
+
addWarnings(errors: (PartialMessage | string)[]): void;
|
|
41
45
|
/**
|
|
42
46
|
* Add external JavaScript import metadata to the result. This is currently used
|
|
43
47
|
* by the development server to optimize the prebundling process.
|
|
@@ -19,6 +19,7 @@ class ExecutionResult {
|
|
|
19
19
|
outputFiles = [];
|
|
20
20
|
assetFiles = [];
|
|
21
21
|
errors = [];
|
|
22
|
+
warnings = [];
|
|
22
23
|
externalMetadata;
|
|
23
24
|
constructor(rebuildContexts, codeBundleCache) {
|
|
24
25
|
this.rebuildContexts = rebuildContexts;
|
|
@@ -30,8 +31,31 @@ class ExecutionResult {
|
|
|
30
31
|
addAssets(assets) {
|
|
31
32
|
this.assetFiles.push(...assets);
|
|
32
33
|
}
|
|
34
|
+
addError(error) {
|
|
35
|
+
if (typeof error === 'string') {
|
|
36
|
+
this.errors.push({ text: error, location: null });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.errors.push(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
33
42
|
addErrors(errors) {
|
|
34
|
-
|
|
43
|
+
for (const error of errors) {
|
|
44
|
+
this.addError(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
addWarning(error) {
|
|
48
|
+
if (typeof error === 'string') {
|
|
49
|
+
this.warnings.push({ text: error, location: null });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.warnings.push(error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
addWarnings(errors) {
|
|
56
|
+
for (const error of errors) {
|
|
57
|
+
this.addWarning(error);
|
|
58
|
+
}
|
|
35
59
|
}
|
|
36
60
|
/**
|
|
37
61
|
* Add external JavaScript import metadata to the result. This is currently used
|
|
@@ -5,17 +5,17 @@
|
|
|
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.io/license
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { logging } from '@angular-devkit/core';
|
|
9
9
|
import { BuildOptions, Metafile, OutputFile, PartialMessage } from 'esbuild';
|
|
10
10
|
import { NormalizedOutputOptions } from '../../builders/application/options';
|
|
11
11
|
import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
|
|
12
12
|
import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-context';
|
|
13
13
|
import { BuildOutputAsset } from './bundler-execution-result';
|
|
14
|
-
export declare function logBuildStats(
|
|
14
|
+
export declare function logBuildStats(logger: logging.LoggerApi, metafile: Metafile, initial: Map<string, InitialFileRecord>, budgetFailures: BudgetCalculatorResult[] | undefined, changedFiles?: Set<string>, estimatedTransferSizes?: Map<string, number>): void;
|
|
15
15
|
export declare function calculateEstimatedTransferSizes(outputFiles: OutputFile[]): Promise<Map<string, number>>;
|
|
16
16
|
export declare function withSpinner<T>(text: string, action: () => T | Promise<T>): Promise<T>;
|
|
17
17
|
export declare function withNoProgress<T>(text: string, action: () => T | Promise<T>): Promise<T>;
|
|
18
|
-
export declare function logMessages(
|
|
18
|
+
export declare function logMessages(logger: logging.LoggerApi, { errors, warnings }: {
|
|
19
19
|
errors?: PartialMessage[];
|
|
20
20
|
warnings?: PartialMessage[];
|
|
21
21
|
}): Promise<void>;
|
|
@@ -21,7 +21,7 @@ const semver_1 = require("semver");
|
|
|
21
21
|
const spinner_1 = require("../../utils/spinner");
|
|
22
22
|
const stats_1 = require("../webpack/utils/stats");
|
|
23
23
|
const bundler_context_1 = require("./bundler-context");
|
|
24
|
-
function logBuildStats(
|
|
24
|
+
function logBuildStats(logger, metafile, initial, budgetFailures, changedFiles, estimatedTransferSizes) {
|
|
25
25
|
const stats = [];
|
|
26
26
|
let unchangedCount = 0;
|
|
27
27
|
for (const [file, output] of Object.entries(metafile.outputs)) {
|
|
@@ -53,13 +53,13 @@ function logBuildStats(context, metafile, initial, budgetFailures, changedFiles,
|
|
|
53
53
|
}
|
|
54
54
|
if (stats.length > 0) {
|
|
55
55
|
const tableText = (0, stats_1.generateBuildStatsTable)(stats, true, unchangedCount === 0, !!estimatedTransferSizes, budgetFailures);
|
|
56
|
-
|
|
56
|
+
logger.info('\n' + tableText + '\n');
|
|
57
57
|
}
|
|
58
58
|
else if (changedFiles !== undefined) {
|
|
59
|
-
|
|
59
|
+
logger.info('\nNo output file changes.\n');
|
|
60
60
|
}
|
|
61
61
|
if (unchangedCount > 0) {
|
|
62
|
-
|
|
62
|
+
logger.info(`Unchanged output files: ${unchangedCount}`);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exports.logBuildStats = logBuildStats;
|
|
@@ -117,14 +117,14 @@ async function withNoProgress(text, action) {
|
|
|
117
117
|
return action();
|
|
118
118
|
}
|
|
119
119
|
exports.withNoProgress = withNoProgress;
|
|
120
|
-
async function logMessages(
|
|
120
|
+
async function logMessages(logger, { errors, warnings }) {
|
|
121
121
|
if (warnings?.length) {
|
|
122
122
|
const warningMessages = await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color: true });
|
|
123
|
-
|
|
123
|
+
logger.warn(warningMessages.join('\n'));
|
|
124
124
|
}
|
|
125
125
|
if (errors?.length) {
|
|
126
126
|
const errorMessages = await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color: true });
|
|
127
|
-
|
|
127
|
+
logger.error(errorMessages.join('\n'));
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
exports.logMessages = logMessages;
|