@angular/build 18.2.0-next.1 → 18.2.0-next.2
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 +5 -5
- package/src/builders/application/build-action.d.ts +3 -4
- package/src/builders/application/build-action.js +39 -5
- package/src/builders/application/execute-build.js +2 -0
- package/src/builders/application/index.d.ts +2 -1
- package/src/builders/application/index.js +12 -11
- package/src/builders/application/results.d.ts +67 -0
- package/src/builders/application/results.js +17 -0
- package/src/builders/dev-server/vite-server.d.ts +2 -2
- package/src/builders/dev-server/vite-server.js +61 -46
- package/src/builders/extract-i18n/application-extraction.d.ts +2 -2
- package/src/builders/extract-i18n/application-extraction.js +26 -32
- package/src/builders/extract-i18n/builder.js +2 -3
- package/src/private.d.ts +1 -0
- package/src/private.js +3 -1
- package/src/tools/esbuild/bundler-execution-result.d.ts +2 -0
- package/src/tools/esbuild/bundler-execution-result.js +2 -0
- package/src/tools/sass/lexer.js +1 -1
- package/src/tools/vite/id-prefix-plugin.js +2 -2
- package/src/tools/vite/middlewares/assets-middleware.js +2 -1
- package/src/tools/vite/middlewares/index-html-middleware.js +4 -2
- package/src/utils/normalize-cache.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "18.2.0-next.
|
|
3
|
+
"version": "18.2.0-next.2",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.1802.0-next.
|
|
26
|
+
"@angular-devkit/architect": "0.1802.0-next.2",
|
|
27
27
|
"@babel/core": "7.24.9",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.24.7",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
30
|
"@babel/plugin-syntax-import-attributes": "7.24.7",
|
|
31
|
-
"@inquirer/confirm": "3.1.
|
|
31
|
+
"@inquirer/confirm": "3.1.17",
|
|
32
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
34
|
"critters": "0.0.24",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
43
43
|
"picomatch": "4.0.2",
|
|
44
44
|
"piscina": "4.6.1",
|
|
45
|
-
"rollup": "4.
|
|
45
|
+
"rollup": "4.19.0",
|
|
46
46
|
"sass": "1.77.8",
|
|
47
47
|
"semver": "7.6.3",
|
|
48
48
|
"vite": "5.3.4",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"optional": true
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
"packageManager": "yarn@4.3.
|
|
81
|
+
"packageManager": "yarn@4.3.1",
|
|
82
82
|
"repository": {
|
|
83
83
|
"type": "git",
|
|
84
84
|
"url": "https://github.com/angular/angular-cli.git"
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
-
import { BuilderContext
|
|
8
|
+
import { BuilderContext } from '@angular-devkit/architect';
|
|
9
9
|
import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
|
|
10
10
|
import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result';
|
|
11
11
|
import { NormalizedCachedOptions } from '../../utils/normalize-cache';
|
|
12
12
|
import { NormalizedOutputOptions } from './options';
|
|
13
|
-
|
|
13
|
+
import { Result } from './results';
|
|
14
14
|
export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
|
|
15
15
|
workspaceRoot: string;
|
|
16
16
|
projectRoot: string;
|
|
@@ -29,5 +29,4 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
|
|
|
29
29
|
clearScreen?: boolean;
|
|
30
30
|
colors?: boolean;
|
|
31
31
|
jsonLogs?: boolean;
|
|
32
|
-
}): AsyncIterable<
|
|
33
|
-
export {};
|
|
32
|
+
}): AsyncIterable<Result>;
|
|
@@ -36,10 +36,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.runEsBuildBuildAction = runEsBuildBuildAction;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
38
|
const node_path_1 = __importDefault(require("node:path"));
|
|
39
|
+
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
39
40
|
const sass_language_1 = require("../../tools/esbuild/stylesheets/sass-language");
|
|
40
41
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
41
42
|
const delete_output_dir_1 = require("../../utils/delete-output-dir");
|
|
42
43
|
const environment_options_1 = require("../../utils/environment-options");
|
|
44
|
+
const results_1 = require("./results");
|
|
43
45
|
// Watch workspace for package manager changes
|
|
44
46
|
const packageWatchFiles = [
|
|
45
47
|
// manifest can affect module resolution
|
|
@@ -167,18 +169,50 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
167
169
|
(0, sass_language_1.shutdownSassWorkerPool)();
|
|
168
170
|
}
|
|
169
171
|
}
|
|
170
|
-
async function writeAndEmitOutput(writeToFileSystem, { outputFiles,
|
|
172
|
+
async function writeAndEmitOutput(writeToFileSystem, { outputFiles, outputWithFiles, assetFiles, externalMetadata, htmlIndexPath, htmlBaseHref, }, outputOptions, writeToFileSystemFilter) {
|
|
173
|
+
if (!outputWithFiles.success) {
|
|
174
|
+
return {
|
|
175
|
+
kind: results_1.ResultKind.Failure,
|
|
176
|
+
errors: outputWithFiles.errors,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
171
179
|
if (writeToFileSystem) {
|
|
172
180
|
// Write output files
|
|
173
181
|
const outputFilesToWrite = writeToFileSystemFilter
|
|
174
182
|
? outputFiles.filter(writeToFileSystemFilter)
|
|
175
183
|
: outputFiles;
|
|
176
184
|
await (0, utils_1.writeResultFiles)(outputFilesToWrite, assetFiles, outputOptions);
|
|
177
|
-
|
|
185
|
+
// Currently unused other than indicating success if writing to disk.
|
|
186
|
+
return {
|
|
187
|
+
kind: results_1.ResultKind.Full,
|
|
188
|
+
files: {},
|
|
189
|
+
};
|
|
178
190
|
}
|
|
179
191
|
else {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
192
|
+
const result = {
|
|
193
|
+
kind: results_1.ResultKind.Full,
|
|
194
|
+
files: {},
|
|
195
|
+
detail: {
|
|
196
|
+
externalMetadata,
|
|
197
|
+
htmlIndexPath,
|
|
198
|
+
htmlBaseHref,
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
for (const file of outputWithFiles.assetFiles) {
|
|
202
|
+
result.files[file.destination] = {
|
|
203
|
+
type: bundler_context_1.BuildOutputFileType.Browser,
|
|
204
|
+
inputPath: file.source,
|
|
205
|
+
origin: 'disk',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
for (const file of outputWithFiles.outputFiles) {
|
|
209
|
+
result.files[file.path] = {
|
|
210
|
+
type: file.type,
|
|
211
|
+
contents: file.contents,
|
|
212
|
+
origin: 'memory',
|
|
213
|
+
hash: file.hash,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
183
217
|
}
|
|
184
218
|
}
|
|
@@ -101,6 +101,8 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
101
101
|
// Watch input index HTML file if configured
|
|
102
102
|
if (options.indexHtmlOptions) {
|
|
103
103
|
executionResult.extraWatchFiles.push(options.indexHtmlOptions.input);
|
|
104
|
+
executionResult.htmlIndexPath = options.indexHtmlOptions.output;
|
|
105
|
+
executionResult.htmlBaseHref = options.baseHref;
|
|
104
106
|
}
|
|
105
107
|
// Perform i18n translation inlining if enabled
|
|
106
108
|
if (i18nOptions.shouldInline) {
|
|
@@ -9,13 +9,14 @@ import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
|
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
|
|
11
11
|
import { ApplicationBuilderExtensions, ApplicationBuilderInternalOptions } from './options';
|
|
12
|
+
import { Result } from './results';
|
|
12
13
|
import { Schema as ApplicationBuilderOptions } from './schema';
|
|
13
14
|
export type { ApplicationBuilderOptions };
|
|
14
15
|
export declare function buildApplicationInternal(options: ApplicationBuilderInternalOptions, context: BuilderContext & {
|
|
15
16
|
signal?: AbortSignal;
|
|
16
17
|
}, infrastructureSettings?: {
|
|
17
18
|
write?: boolean;
|
|
18
|
-
}, extensions?: ApplicationBuilderExtensions): AsyncIterable<
|
|
19
|
+
}, extensions?: ApplicationBuilderExtensions): AsyncIterable<Result>;
|
|
19
20
|
export interface ApplicationBuilderOutput extends BuilderOutput {
|
|
20
21
|
outputFiles?: BuildOutputFile[];
|
|
21
22
|
assetFiles?: {
|
|
@@ -18,6 +18,7 @@ const version_1 = require("../../utils/version");
|
|
|
18
18
|
const build_action_1 = require("./build-action");
|
|
19
19
|
const execute_build_1 = require("./execute-build");
|
|
20
20
|
const options_1 = require("./options");
|
|
21
|
+
const results_1 = require("./results");
|
|
21
22
|
async function* buildApplicationInternal(options,
|
|
22
23
|
// TODO: Integrate abort signal support into builder system
|
|
23
24
|
context, infrastructureSettings, extensions) {
|
|
@@ -29,7 +30,9 @@ context, infrastructureSettings, extensions) {
|
|
|
29
30
|
// Determine project name from builder context target
|
|
30
31
|
const projectName = target?.project;
|
|
31
32
|
if (!projectName) {
|
|
32
|
-
|
|
33
|
+
context.logger.error(`The 'application' builder requires a target to be specified.`);
|
|
34
|
+
// Only the vite-based dev server current uses the errors value
|
|
35
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
33
36
|
return;
|
|
34
37
|
}
|
|
35
38
|
const normalizedOptions = await (0, options_1.normalizeOptions)(context, projectName, options, extensions);
|
|
@@ -38,17 +41,13 @@ context, infrastructureSettings, extensions) {
|
|
|
38
41
|
if (writeServerBundles) {
|
|
39
42
|
const { browser, server } = normalizedOptions.outputOptions;
|
|
40
43
|
if (browser === '') {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
error: `'outputPath.browser' cannot be configured to an empty string when SSR is enabled.`,
|
|
44
|
-
};
|
|
44
|
+
context.logger.error(`'outputPath.browser' cannot be configured to an empty string when SSR is enabled.`);
|
|
45
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
if (browser === server) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
error: `'outputPath.browser' and 'outputPath.server' cannot be configured to the same value.`,
|
|
51
|
-
};
|
|
49
|
+
context.logger.error(`'outputPath.browser' and 'outputPath.server' cannot be configured to the same value.`);
|
|
50
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -105,7 +104,7 @@ context, infrastructureSettings, extensions) {
|
|
|
105
104
|
signal,
|
|
106
105
|
});
|
|
107
106
|
}
|
|
108
|
-
function buildApplication(options, context, pluginsOrExtensions) {
|
|
107
|
+
async function* buildApplication(options, context, pluginsOrExtensions) {
|
|
109
108
|
let extensions;
|
|
110
109
|
if (pluginsOrExtensions && Array.isArray(pluginsOrExtensions)) {
|
|
111
110
|
extensions = {
|
|
@@ -115,6 +114,8 @@ function buildApplication(options, context, pluginsOrExtensions) {
|
|
|
115
114
|
else {
|
|
116
115
|
extensions = pluginsOrExtensions;
|
|
117
116
|
}
|
|
118
|
-
|
|
117
|
+
for await (const result of buildApplicationInternal(options, context, undefined, extensions)) {
|
|
118
|
+
yield { success: result.kind !== results_1.ResultKind.Failure };
|
|
119
|
+
}
|
|
119
120
|
}
|
|
120
121
|
exports.default = (0, architect_1.createBuilder)(buildApplication);
|
|
@@ -0,0 +1,67 @@
|
|
|
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 { BuildOutputFileType } from '../../tools/esbuild/bundler-context';
|
|
9
|
+
export declare enum ResultKind {
|
|
10
|
+
Failure = 0,
|
|
11
|
+
Full = 1,
|
|
12
|
+
Incremental = 2,
|
|
13
|
+
ComponentUpdate = 3
|
|
14
|
+
}
|
|
15
|
+
export type Result = FailureResult | FullResult | IncrementalResult | ComponentUpdateResult;
|
|
16
|
+
export interface BaseResult {
|
|
17
|
+
kind: ResultKind;
|
|
18
|
+
warnings?: ResultMessage[];
|
|
19
|
+
duration?: number;
|
|
20
|
+
detail?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface FailureResult extends BaseResult {
|
|
23
|
+
kind: ResultKind.Failure;
|
|
24
|
+
errors: ResultMessage[];
|
|
25
|
+
}
|
|
26
|
+
export interface FullResult extends BaseResult {
|
|
27
|
+
kind: ResultKind.Full;
|
|
28
|
+
files: Record<string, ResultFile>;
|
|
29
|
+
}
|
|
30
|
+
export interface IncrementalResult extends BaseResult {
|
|
31
|
+
kind: ResultKind.Incremental;
|
|
32
|
+
added: string[];
|
|
33
|
+
removed: string[];
|
|
34
|
+
modified: string[];
|
|
35
|
+
files: Record<string, ResultFile>;
|
|
36
|
+
}
|
|
37
|
+
export type ResultFile = DiskFile | MemoryFile;
|
|
38
|
+
export interface BaseResultFile {
|
|
39
|
+
origin: 'memory' | 'disk';
|
|
40
|
+
type: BuildOutputFileType;
|
|
41
|
+
}
|
|
42
|
+
export interface DiskFile extends BaseResultFile {
|
|
43
|
+
origin: 'disk';
|
|
44
|
+
inputPath: string;
|
|
45
|
+
}
|
|
46
|
+
export interface MemoryFile extends BaseResultFile {
|
|
47
|
+
origin: 'memory';
|
|
48
|
+
hash: string;
|
|
49
|
+
contents: Uint8Array;
|
|
50
|
+
}
|
|
51
|
+
export interface ResultMessage {
|
|
52
|
+
text: string;
|
|
53
|
+
location?: {
|
|
54
|
+
file: string;
|
|
55
|
+
line: number;
|
|
56
|
+
column: number;
|
|
57
|
+
} | null;
|
|
58
|
+
notes?: {
|
|
59
|
+
text: string;
|
|
60
|
+
}[];
|
|
61
|
+
}
|
|
62
|
+
export interface ComponentUpdateResult extends BaseResult {
|
|
63
|
+
kind: ResultKind.ComponentUpdate;
|
|
64
|
+
id: string;
|
|
65
|
+
type: 'style' | 'template';
|
|
66
|
+
content: string;
|
|
67
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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.ResultKind = void 0;
|
|
11
|
+
var ResultKind;
|
|
12
|
+
(function (ResultKind) {
|
|
13
|
+
ResultKind[ResultKind["Failure"] = 0] = "Failure";
|
|
14
|
+
ResultKind[ResultKind["Full"] = 1] = "Full";
|
|
15
|
+
ResultKind[ResultKind["Incremental"] = 2] = "Incremental";
|
|
16
|
+
ResultKind[ResultKind["ComponentUpdate"] = 3] = "ComponentUpdate";
|
|
17
|
+
})(ResultKind || (exports.ResultKind = ResultKind = {}));
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { BuilderContext } from '@angular-devkit/architect';
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import type { Connect, DepOptimizationConfig, InlineConfig } from 'vite';
|
|
11
|
-
import {
|
|
11
|
+
import { Result } from '../application/results';
|
|
12
12
|
import { type ApplicationBuilderInternalOptions, type ExternalResultMetadata, JavaScriptTransformer } from './internal';
|
|
13
13
|
import type { NormalizedDevServerOptions } from './options';
|
|
14
14
|
import type { DevServerBuilderOutput } from './output';
|
|
@@ -19,7 +19,7 @@ interface OutputFileRecord {
|
|
|
19
19
|
updated: boolean;
|
|
20
20
|
servable: boolean;
|
|
21
21
|
}
|
|
22
|
-
export type BuilderAction = (options: ApplicationBuilderInternalOptions, context: BuilderContext, plugins?: Plugin[]) => AsyncIterable<
|
|
22
|
+
export type BuilderAction = (options: ApplicationBuilderInternalOptions, context: BuilderContext, plugins?: Plugin[]) => AsyncIterable<Result>;
|
|
23
23
|
export declare function serveWithVite(serverOptions: NormalizedDevServerOptions, builderName: string, builderAction: BuilderAction, context: BuilderContext, transformers?: {
|
|
24
24
|
indexHtml?: (content: string) => Promise<string>;
|
|
25
25
|
}, extensions?: {
|
|
@@ -45,6 +45,7 @@ const i18n_locale_plugin_1 = require("../../tools/vite/i18n-locale-plugin");
|
|
|
45
45
|
const id_prefix_plugin_1 = require("../../tools/vite/id-prefix-plugin");
|
|
46
46
|
const utils_1 = require("../../utils");
|
|
47
47
|
const load_esm_1 = require("../../utils/load-esm");
|
|
48
|
+
const results_1 = require("../application/results");
|
|
48
49
|
const internal_1 = require("./internal");
|
|
49
50
|
/**
|
|
50
51
|
* Build options that are also present on the dev server but are only passed
|
|
@@ -77,12 +78,6 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
77
78
|
}
|
|
78
79
|
// Set all packages as external to support Vite's prebundle caching
|
|
79
80
|
browserOptions.externalPackages = serverOptions.prebundle;
|
|
80
|
-
const baseHref = browserOptions.baseHref;
|
|
81
|
-
if (serverOptions.servePath === undefined && baseHref !== undefined) {
|
|
82
|
-
// Remove trailing slash
|
|
83
|
-
serverOptions.servePath =
|
|
84
|
-
baseHref !== './' && baseHref[baseHref.length - 1] === '/' ? baseHref.slice(0, -1) : baseHref;
|
|
85
|
-
}
|
|
86
81
|
// The development server currently only supports a single locale when localizing.
|
|
87
82
|
// This matches the behavior of the Webpack-based development server but could be expanded in the future.
|
|
88
83
|
if (browserOptions.localize === true ||
|
|
@@ -101,15 +96,8 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
101
96
|
// In a development environment the additional scope information does not
|
|
102
97
|
// have a negative effect unlike production where final output size is relevant.
|
|
103
98
|
{ sourcemap: true, jit: true, thirdPartySourcemaps }, 1);
|
|
104
|
-
//
|
|
105
|
-
// TODO: Provide this info from the build results
|
|
99
|
+
// The index HTML path will be updated from the build results if provided by the builder
|
|
106
100
|
let htmlIndexPath = 'index.html';
|
|
107
|
-
if (browserOptions.index && typeof browserOptions.index !== 'boolean') {
|
|
108
|
-
htmlIndexPath =
|
|
109
|
-
typeof browserOptions.index === 'string'
|
|
110
|
-
? (0, node_path_1.basename)(browserOptions.index)
|
|
111
|
-
: browserOptions.index.output || 'index.html';
|
|
112
|
-
}
|
|
113
101
|
// dynamically import Vite for ESM compatibility
|
|
114
102
|
const { createServer, normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
115
103
|
let server;
|
|
@@ -131,24 +119,55 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
131
119
|
});
|
|
132
120
|
// TODO: Switch this to an architect schedule call when infrastructure settings are supported
|
|
133
121
|
for await (const result of builderAction(browserOptions, context, extensions?.buildPlugins)) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
122
|
+
switch (result.kind) {
|
|
123
|
+
case results_1.ResultKind.Failure:
|
|
124
|
+
if (result.errors.length && server) {
|
|
125
|
+
hadError = true;
|
|
126
|
+
server.hot.send({
|
|
127
|
+
type: 'error',
|
|
128
|
+
err: {
|
|
129
|
+
message: result.errors[0].text,
|
|
130
|
+
stack: '',
|
|
131
|
+
loc: result.errors[0].location ?? undefined,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
case results_1.ResultKind.Full:
|
|
137
|
+
if (result.detail?.['htmlIndexPath']) {
|
|
138
|
+
htmlIndexPath = result.detail['htmlIndexPath'];
|
|
139
|
+
}
|
|
140
|
+
if (serverOptions.servePath === undefined && result.detail?.['htmlBaseHref']) {
|
|
141
|
+
const baseHref = result.detail['htmlBaseHref'];
|
|
142
|
+
// Remove trailing slash
|
|
143
|
+
serverOptions.servePath =
|
|
144
|
+
baseHref !== './' && baseHref[baseHref.length - 1] === '/'
|
|
145
|
+
? baseHref.slice(0, -1)
|
|
146
|
+
: baseHref;
|
|
147
|
+
}
|
|
148
|
+
assetFiles.clear();
|
|
149
|
+
for (const [outputPath, file] of Object.entries(result.files)) {
|
|
150
|
+
if (file.origin === 'disk') {
|
|
151
|
+
assetFiles.set('/' + normalizePath(outputPath), normalizePath(file.inputPath));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Analyze result files for changes
|
|
155
|
+
analyzeResultFiles(normalizePath, htmlIndexPath, result.files, generatedFiles);
|
|
156
|
+
break;
|
|
157
|
+
case results_1.ResultKind.Incremental:
|
|
158
|
+
(0, node_assert_1.default)(server, 'Builder must provide an initial full build before incremental results.');
|
|
159
|
+
// TODO: Implement support -- application builder currently does not use
|
|
160
|
+
break;
|
|
161
|
+
case results_1.ResultKind.ComponentUpdate:
|
|
162
|
+
(0, node_assert_1.default)(serverOptions.hmr, 'Component updates are only supported with HMR enabled.');
|
|
163
|
+
// TODO: Implement support -- application builder currently does not use
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
context.logger.warn(`Unknown result kind [${result.kind}] provided by build.`);
|
|
167
|
+
continue;
|
|
150
168
|
}
|
|
151
|
-
|
|
169
|
+
// Clear existing error overlay on successful result
|
|
170
|
+
if (hadError && server) {
|
|
152
171
|
hadError = false;
|
|
153
172
|
// Send an empty update to clear the error overlay
|
|
154
173
|
server.hot.send({
|
|
@@ -156,18 +175,10 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
156
175
|
updates: [],
|
|
157
176
|
});
|
|
158
177
|
}
|
|
159
|
-
// Analyze result files for changes
|
|
160
|
-
analyzeResultFiles(normalizePath, htmlIndexPath, result.outputFiles, generatedFiles);
|
|
161
|
-
assetFiles.clear();
|
|
162
|
-
if (result.assetFiles) {
|
|
163
|
-
for (const asset of result.assetFiles) {
|
|
164
|
-
assetFiles.set('/' + normalizePath(asset.destination), normalizePath(asset.source));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
178
|
// To avoid disconnecting the array objects from the option, these arrays need to be mutated instead of replaced.
|
|
168
179
|
let requiresServerRestart = false;
|
|
169
|
-
if (result.externalMetadata) {
|
|
170
|
-
const { implicitBrowser, implicitServer, explicit } = result.externalMetadata;
|
|
180
|
+
if (result.detail?.['externalMetadata']) {
|
|
181
|
+
const { implicitBrowser, implicitServer, explicit } = result.detail['externalMetadata'];
|
|
171
182
|
const implicitServerFiltered = implicitServer.filter((m) => removeNodeJsBuiltinModules(m) && removeAbsoluteUrls(m));
|
|
172
183
|
const implicitBrowserFiltered = implicitBrowser.filter(removeAbsoluteUrls);
|
|
173
184
|
if (browserOptions.ssr && serverOptions.prebundle !== false) {
|
|
@@ -302,22 +313,26 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
|
|
|
302
313
|
}
|
|
303
314
|
function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generatedFiles) {
|
|
304
315
|
const seen = new Set(['/index.html']);
|
|
305
|
-
for (const file of resultFiles) {
|
|
316
|
+
for (const [outputPath, file] of Object.entries(resultFiles)) {
|
|
317
|
+
if (file.origin === 'disk') {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
306
320
|
let filePath;
|
|
307
|
-
if (
|
|
321
|
+
if (outputPath === htmlIndexPath) {
|
|
308
322
|
// Convert custom index output path to standard index path for dev-server usage.
|
|
309
323
|
// This mimics the Webpack dev-server behavior.
|
|
310
324
|
filePath = '/index.html';
|
|
311
325
|
}
|
|
312
326
|
else {
|
|
313
|
-
filePath = '/' + normalizePath(
|
|
327
|
+
filePath = '/' + normalizePath(outputPath);
|
|
314
328
|
}
|
|
315
329
|
seen.add(filePath);
|
|
330
|
+
const servable = file.type === internal_1.BuildOutputFileType.Browser || file.type === internal_1.BuildOutputFileType.Media;
|
|
316
331
|
// Skip analysis of sourcemaps
|
|
317
332
|
if (filePath.endsWith('.map')) {
|
|
318
333
|
generatedFiles.set(filePath, {
|
|
319
334
|
contents: file.contents,
|
|
320
|
-
servable
|
|
335
|
+
servable,
|
|
321
336
|
size: file.contents.byteLength,
|
|
322
337
|
updated: false,
|
|
323
338
|
});
|
|
@@ -337,7 +352,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
337
352
|
size: file.contents.byteLength,
|
|
338
353
|
hash: file.hash,
|
|
339
354
|
updated: true,
|
|
340
|
-
servable
|
|
355
|
+
servable,
|
|
341
356
|
});
|
|
342
357
|
}
|
|
343
358
|
// Clear stale output files
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ɵParsedMessage as LocalizeMessage } from '@angular/localize';
|
|
9
9
|
import type { MessageExtractor } from '@angular/localize/tools';
|
|
10
|
-
import type { BuilderContext
|
|
10
|
+
import type { BuilderContext } from '@angular-devkit/architect';
|
|
11
11
|
import type { ApplicationBuilderExtensions } from '../application/options';
|
|
12
12
|
import type { NormalizedExtractI18nOptions } from './options';
|
|
13
13
|
export declare function extractMessages(options: NormalizedExtractI18nOptions, builderName: string, context: BuilderContext, extractorConstructor: typeof MessageExtractor, extensions?: ApplicationBuilderExtensions): Promise<{
|
|
14
|
-
|
|
14
|
+
success: boolean;
|
|
15
15
|
basePath: string;
|
|
16
16
|
messages: LocalizeMessage[];
|
|
17
17
|
useLegacyIds: boolean;
|
|
@@ -11,9 +11,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.extractMessages = extractMessages;
|
|
14
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
15
|
const application_1 = require("../application");
|
|
16
|
+
const results_1 = require("../application/results");
|
|
17
17
|
async function extractMessages(options, builderName, context, extractorConstructor, extensions) {
|
|
18
18
|
const messages = [];
|
|
19
19
|
// Setup the build options for the application based on the buildTarget option
|
|
@@ -28,46 +28,30 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
28
28
|
buildOptions.appShell = false;
|
|
29
29
|
buildOptions.prerender = false;
|
|
30
30
|
// Build the application with the build options
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
(0, node_assert_1.default)(builderResult !== undefined, 'Application builder did not provide a result.');
|
|
31
|
+
const builderResult = await first((0, application_1.buildApplicationInternal)(buildOptions, context, { write: false }, extensions));
|
|
32
|
+
let success = false;
|
|
33
|
+
if (!builderResult || builderResult.kind === results_1.ResultKind.Failure) {
|
|
34
|
+
context.logger.error('Application build failed.');
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
success: false,
|
|
42
|
-
error: err.message,
|
|
43
|
-
};
|
|
36
|
+
else if (builderResult.kind !== results_1.ResultKind.Full) {
|
|
37
|
+
context.logger.error('Application build did not provide a full output.');
|
|
44
38
|
}
|
|
45
|
-
|
|
46
|
-
// Output files are only present on a successful build.
|
|
47
|
-
if (builderResult.outputFiles) {
|
|
48
|
-
// Store the JS and JS map files for lookup during extraction
|
|
49
|
-
const files = new Map();
|
|
50
|
-
for (const outputFile of builderResult.outputFiles) {
|
|
51
|
-
if (outputFile.path.endsWith('.js')) {
|
|
52
|
-
files.set(outputFile.path, outputFile.text);
|
|
53
|
-
}
|
|
54
|
-
else if (outputFile.path.endsWith('.js.map')) {
|
|
55
|
-
files.set(outputFile.path, outputFile.text);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
39
|
+
else {
|
|
58
40
|
// Setup the localize message extractor based on the in-memory files
|
|
59
|
-
const extractor = setupLocalizeExtractor(extractorConstructor, files, context);
|
|
60
|
-
//
|
|
61
|
-
|
|
41
|
+
const extractor = setupLocalizeExtractor(extractorConstructor, builderResult.files, context);
|
|
42
|
+
// Extract messages from each output JavaScript file.
|
|
43
|
+
// Output files are only present on a successful build.
|
|
44
|
+
for (const filePath of Object.keys(builderResult.files)) {
|
|
62
45
|
if (!filePath.endsWith('.js')) {
|
|
63
46
|
continue;
|
|
64
47
|
}
|
|
65
48
|
const fileMessages = extractor.extractMessages(filePath);
|
|
66
49
|
messages.push(...fileMessages);
|
|
67
50
|
}
|
|
51
|
+
success = true;
|
|
68
52
|
}
|
|
69
53
|
return {
|
|
70
|
-
|
|
54
|
+
success,
|
|
71
55
|
basePath: context.workspaceRoot,
|
|
72
56
|
messages,
|
|
73
57
|
// Legacy i18n identifiers are not supported with the new application builder
|
|
@@ -75,6 +59,7 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
75
59
|
};
|
|
76
60
|
}
|
|
77
61
|
function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
62
|
+
const textDecoder = new TextDecoder();
|
|
78
63
|
// Setup a virtual file system instance for the extractor
|
|
79
64
|
// * MessageExtractor itself uses readFile, relative and resolve
|
|
80
65
|
// * Internal SourceFileLoader (sourcemap support) uses dirname, exists, readFile, and resolve
|
|
@@ -82,7 +67,11 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
82
67
|
readFile(path) {
|
|
83
68
|
// Output files are stored as relative to the workspace root
|
|
84
69
|
const requestedPath = node_path_1.default.relative(context.workspaceRoot, path);
|
|
85
|
-
const
|
|
70
|
+
const file = files[requestedPath];
|
|
71
|
+
let content;
|
|
72
|
+
if (file?.origin === 'memory') {
|
|
73
|
+
content = textDecoder.decode(file.contents);
|
|
74
|
+
}
|
|
86
75
|
if (content === undefined) {
|
|
87
76
|
throw new Error('Unknown file requested: ' + requestedPath);
|
|
88
77
|
}
|
|
@@ -97,7 +86,7 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
97
86
|
exists(path) {
|
|
98
87
|
// Output files are stored as relative to the workspace root
|
|
99
88
|
const requestedPath = node_path_1.default.relative(context.workspaceRoot, path);
|
|
100
|
-
return files
|
|
89
|
+
return files[requestedPath] !== undefined;
|
|
101
90
|
},
|
|
102
91
|
dirname(path) {
|
|
103
92
|
return node_path_1.default.dirname(path);
|
|
@@ -128,3 +117,8 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
128
117
|
});
|
|
129
118
|
return extractor;
|
|
130
119
|
}
|
|
120
|
+
async function first(iterable) {
|
|
121
|
+
for await (const value of iterable) {
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -72,9 +72,8 @@ async function execute(options, context, extensions) {
|
|
|
72
72
|
// Extract messages based on configured builder
|
|
73
73
|
const { extractMessages } = await Promise.resolve().then(() => __importStar(require('./application-extraction')));
|
|
74
74
|
const extractionResult = await extractMessages(normalizedOptions, builderName, context, localizeToolsModule.MessageExtractor, extensions);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return extractionResult.builderResult;
|
|
75
|
+
if (!extractionResult.success) {
|
|
76
|
+
return { success: false };
|
|
78
77
|
}
|
|
79
78
|
// Perform duplicate message checks
|
|
80
79
|
const { checkDuplicateMessages } = localizeToolsModule;
|
package/src/private.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export { buildApplicationInternal } from './builders/application';
|
|
15
15
|
export type { ApplicationBuilderInternalOptions } from './builders/application/options';
|
|
16
|
+
export { type Result, type ResultFile, ResultKind } from './builders/application/results';
|
|
16
17
|
export { serveWithVite } from './builders/dev-server/vite-server';
|
|
17
18
|
export * from './tools/babel/plugins';
|
|
18
19
|
export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result';
|
package/src/private.js
CHANGED
|
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.createCompilerPlugin = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.buildApplicationInternal = void 0;
|
|
24
|
+
exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.createCompilerPlugin = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.ResultKind = exports.buildApplicationInternal = void 0;
|
|
25
25
|
/**
|
|
26
26
|
* @fileoverview
|
|
27
27
|
* Private exports intended only for use with the @angular-devkit/build-angular package.
|
|
@@ -31,6 +31,8 @@ exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.
|
|
|
31
31
|
// Builders
|
|
32
32
|
var application_1 = require("./builders/application");
|
|
33
33
|
Object.defineProperty(exports, "buildApplicationInternal", { enumerable: true, get: function () { return application_1.buildApplicationInternal; } });
|
|
34
|
+
var results_1 = require("./builders/application/results");
|
|
35
|
+
Object.defineProperty(exports, "ResultKind", { enumerable: true, get: function () { return results_1.ResultKind; } });
|
|
34
36
|
var vite_server_1 = require("./builders/dev-server/vite-server");
|
|
35
37
|
Object.defineProperty(exports, "serveWithVite", { enumerable: true, get: function () { return vite_server_1.serveWithVite; } });
|
|
36
38
|
// Tools
|
|
@@ -38,6 +38,8 @@ export declare class ExecutionResult {
|
|
|
38
38
|
logs: string[];
|
|
39
39
|
externalMetadata?: ExternalResultMetadata;
|
|
40
40
|
extraWatchFiles: string[];
|
|
41
|
+
htmlIndexPath?: string;
|
|
42
|
+
htmlBaseHref?: string;
|
|
41
43
|
constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
|
|
42
44
|
addOutputFile(path: string, content: string | Uint8Array, type: BuildOutputFileType): void;
|
|
43
45
|
addAssets(assets: BuildOutputAsset[]): void;
|
package/src/tools/sass/lexer.js
CHANGED
|
@@ -50,7 +50,7 @@ function* findUrls(contents) {
|
|
|
50
50
|
if (pos > 0) {
|
|
51
51
|
pos -= 2;
|
|
52
52
|
next();
|
|
53
|
-
if (!isWhitespace(current) && current !==
|
|
53
|
+
if (!isWhitespace(current) && current !== 0x002c && current !== 0x003a) {
|
|
54
54
|
// Skip - not a url token
|
|
55
55
|
pos += 3;
|
|
56
56
|
continue;
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.createRemoveIdPrefixPlugin = createRemoveIdPrefixPlugin;
|
|
11
11
|
// NOTE: the implementation for this Vite plugin is roughly based on:
|
|
12
12
|
// https://github.com/MilanKovacic/vite-plugin-externalize-dependencies
|
|
13
|
-
const VITE_ID_PREFIX = '
|
|
13
|
+
const VITE_ID_PREFIX = '@id/';
|
|
14
14
|
const escapeRegexSpecialChars = (inputString) => {
|
|
15
15
|
return inputString.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
16
16
|
};
|
|
@@ -24,7 +24,7 @@ function createRemoveIdPrefixPlugin(externals) {
|
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
const escapedExternals = externals.map(escapeRegexSpecialChars);
|
|
27
|
-
const prefixedExternalRegex = new RegExp(`${VITE_ID_PREFIX}(${escapedExternals.join('|')})`, 'g');
|
|
27
|
+
const prefixedExternalRegex = new RegExp(`${resolvedConfig.base}${VITE_ID_PREFIX}(${escapedExternals.join('|')})`, 'g');
|
|
28
28
|
// @ts-expect-error: Property 'push' does not exist on type 'readonly Plugin<any>[]'
|
|
29
29
|
// Reasoning:
|
|
30
30
|
// since the /@id/ prefix is added by Vite's import-analysis plugin,
|
|
@@ -69,7 +69,8 @@ function createAngularAssetsMiddleware(server, assets, outputFiles) {
|
|
|
69
69
|
if (!pathnameHasTrailingSlash) {
|
|
70
70
|
for (const assetPath of assets.keys()) {
|
|
71
71
|
if (pathname === assetPath.substring(0, assetPath.lastIndexOf('/'))) {
|
|
72
|
-
const
|
|
72
|
+
const { pathname, search, hash } = new URL(req.url, 'http://localhost');
|
|
73
|
+
const location = [pathname, '/', search, hash].join('');
|
|
73
74
|
res.statusCode = 301;
|
|
74
75
|
res.setHeader('Content-Type', 'text/html');
|
|
75
76
|
res.setHeader('Location', location);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createAngularIndexHtmlMiddleware = createAngularIndexHtmlMiddleware;
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
11
12
|
const utils_1 = require("../utils");
|
|
12
13
|
function createAngularIndexHtmlMiddleware(server, outputFiles, indexHtmlTransformer) {
|
|
13
14
|
return function (req, res, next) {
|
|
@@ -18,11 +19,12 @@ function createAngularIndexHtmlMiddleware(server, outputFiles, indexHtmlTransfor
|
|
|
18
19
|
// Parse the incoming request.
|
|
19
20
|
// The base of the URL is unused but required to parse the URL.
|
|
20
21
|
const pathname = (0, utils_1.pathnameWithoutBasePath)(req.url, server.config.base);
|
|
21
|
-
|
|
22
|
+
const extension = (0, node_path_1.extname)(pathname);
|
|
23
|
+
if (extension !== '.html') {
|
|
22
24
|
next();
|
|
23
25
|
return;
|
|
24
26
|
}
|
|
25
|
-
const rawHtml = outputFiles.get(
|
|
27
|
+
const rawHtml = outputFiles.get(pathname)?.contents;
|
|
26
28
|
if (!rawHtml) {
|
|
27
29
|
next();
|
|
28
30
|
return;
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.normalizeCacheOptions = normalizeCacheOptions;
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
/** Version placeholder is replaced during the build process with actual package version */
|
|
13
|
-
const VERSION = '18.2.0-next.
|
|
13
|
+
const VERSION = '18.2.0-next.2';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|