@angular-devkit/build-angular 17.1.1 → 17.2.0-next.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 +26 -26
- package/src/builders/dev-server/options.js +3 -2
- package/src/builders/dev-server/schema.json +1 -1
- package/src/builders/dev-server/vite-server.js +1 -1
- package/src/builders/extract-i18n/options.js +3 -2
- package/src/builders/extract-i18n/schema.json +1 -1
- package/src/builders/jest/index.js +44 -5
- package/src/builders/jest/jest.config.mjs +11 -0
- package/src/tools/esbuild/angular/compilation/angular-compilation.d.ts +9 -2
- package/src/tools/esbuild/angular/compilation/angular-compilation.js +11 -3
- package/src/tools/esbuild/angular/compilation/aot-compilation.d.ts +2 -2
- package/src/tools/esbuild/angular/compilation/aot-compilation.js +19 -8
- package/src/tools/esbuild/angular/compilation/index.d.ts +1 -1
- package/src/tools/esbuild/angular/compilation/index.js +2 -1
- package/src/tools/esbuild/angular/compilation/jit-compilation.d.ts +2 -2
- package/src/tools/esbuild/angular/compilation/jit-compilation.js +12 -6
- package/src/tools/esbuild/angular/compilation/parallel-compilation.d.ts +2 -2
- package/src/tools/esbuild/angular/compilation/parallel-compilation.js +2 -2
- package/src/tools/esbuild/angular/compilation/parallel-worker.d.ts +2 -1
- package/src/tools/esbuild/angular/compilation/parallel-worker.js +2 -2
- package/src/tools/esbuild/angular/compiler-plugin.js +7 -7
- package/src/tools/vite/angular-memory-plugin.js +30 -7
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +3 -1
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.2.0-next.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.
|
|
11
|
-
"@angular-devkit/build-webpack": "0.
|
|
12
|
-
"@angular-devkit/core": "17.
|
|
10
|
+
"@angular-devkit/architect": "0.1702.0-next.0",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1702.0-next.0",
|
|
12
|
+
"@angular-devkit/core": "17.2.0-next.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",
|
|
@@ -17,52 +17,52 @@
|
|
|
17
17
|
"@babel/plugin-transform-async-generator-functions": "7.23.7",
|
|
18
18
|
"@babel/plugin-transform-async-to-generator": "7.23.3",
|
|
19
19
|
"@babel/plugin-transform-runtime": "7.23.7",
|
|
20
|
-
"@babel/preset-env": "7.23.
|
|
21
|
-
"@babel/runtime": "7.23.
|
|
20
|
+
"@babel/preset-env": "7.23.8",
|
|
21
|
+
"@babel/runtime": "7.23.8",
|
|
22
22
|
"@discoveryjs/json-ext": "0.5.7",
|
|
23
|
-
"@ngtools/webpack": "17.
|
|
24
|
-
"@vitejs/plugin-basic-ssl": "1.0
|
|
23
|
+
"@ngtools/webpack": "17.2.0-next.0",
|
|
24
|
+
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
25
25
|
"ansi-colors": "4.1.3",
|
|
26
|
-
"autoprefixer": "10.4.
|
|
26
|
+
"autoprefixer": "10.4.17",
|
|
27
27
|
"babel-loader": "9.1.3",
|
|
28
28
|
"babel-plugin-istanbul": "6.1.1",
|
|
29
29
|
"browserslist": "^4.21.5",
|
|
30
|
-
"copy-webpack-plugin": "
|
|
30
|
+
"copy-webpack-plugin": "12.0.2",
|
|
31
31
|
"critters": "0.0.20",
|
|
32
|
-
"css-loader": "6.
|
|
33
|
-
"esbuild-wasm": "0.19.
|
|
32
|
+
"css-loader": "6.9.1",
|
|
33
|
+
"esbuild-wasm": "0.19.12",
|
|
34
34
|
"fast-glob": "3.3.2",
|
|
35
35
|
"https-proxy-agent": "7.0.2",
|
|
36
36
|
"http-proxy-middleware": "2.0.6",
|
|
37
37
|
"inquirer": "9.2.12",
|
|
38
|
-
"jsonc-parser": "3.2.
|
|
38
|
+
"jsonc-parser": "3.2.1",
|
|
39
39
|
"karma-source-map-support": "1.4.0",
|
|
40
40
|
"less": "4.2.0",
|
|
41
41
|
"less-loader": "11.1.0",
|
|
42
42
|
"license-webpack-plugin": "4.0.2",
|
|
43
43
|
"loader-utils": "3.2.1",
|
|
44
44
|
"magic-string": "0.30.5",
|
|
45
|
-
"mini-css-extract-plugin": "2.7.
|
|
45
|
+
"mini-css-extract-plugin": "2.7.7",
|
|
46
46
|
"mrmime": "2.0.0",
|
|
47
47
|
"open": "8.4.2",
|
|
48
48
|
"ora": "5.4.1",
|
|
49
49
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
50
50
|
"picomatch": "3.0.1",
|
|
51
|
-
"piscina": "4.
|
|
51
|
+
"piscina": "4.3.0",
|
|
52
52
|
"postcss": "8.4.33",
|
|
53
|
-
"postcss-loader": "
|
|
53
|
+
"postcss-loader": "8.0.0",
|
|
54
54
|
"resolve-url-loader": "5.0.0",
|
|
55
55
|
"rxjs": "7.8.1",
|
|
56
|
-
"sass": "1.
|
|
57
|
-
"sass-loader": "
|
|
56
|
+
"sass": "1.70.0",
|
|
57
|
+
"sass-loader": "14.0.0",
|
|
58
58
|
"semver": "7.5.4",
|
|
59
59
|
"source-map-loader": "5.0.0",
|
|
60
60
|
"source-map-support": "0.5.21",
|
|
61
|
-
"terser": "5.
|
|
61
|
+
"terser": "5.27.0",
|
|
62
62
|
"text-table": "0.2.0",
|
|
63
63
|
"tree-kill": "1.2.2",
|
|
64
64
|
"tslib": "2.6.2",
|
|
65
|
-
"undici": "6.
|
|
65
|
+
"undici": "6.4.0",
|
|
66
66
|
"vite": "5.0.12",
|
|
67
67
|
"watchpack": "2.4.0",
|
|
68
68
|
"webpack": "5.89.0",
|
|
@@ -72,19 +72,19 @@
|
|
|
72
72
|
"webpack-subresource-integrity": "5.1.0"
|
|
73
73
|
},
|
|
74
74
|
"optionalDependencies": {
|
|
75
|
-
"esbuild": "0.19.
|
|
75
|
+
"esbuild": "0.19.12"
|
|
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",
|
|
78
|
+
"@angular/compiler-cli": "^17.0.0 || ^17.2.0-next.0",
|
|
79
|
+
"@angular/localize": "^17.0.0 || ^17.2.0-next.0",
|
|
80
|
+
"@angular/platform-server": "^17.0.0 || ^17.2.0-next.0",
|
|
81
|
+
"@angular/service-worker": "^17.0.0 || ^17.2.0-next.0",
|
|
82
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 || ^17.2.0-next.0",
|
|
88
88
|
"protractor": "^7.0.0",
|
|
89
89
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
90
90
|
"typescript": ">=5.2 <5.4"
|
|
@@ -29,8 +29,9 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
29
29
|
const projectMetadata = await context.getProjectMetadata(projectName);
|
|
30
30
|
const projectRoot = node_path_1.default.join(workspaceRoot, projectMetadata.root ?? '');
|
|
31
31
|
const cacheOptions = (0, normalize_cache_1.normalizeCacheOptions)(projectMetadata, workspaceRoot);
|
|
32
|
-
//
|
|
33
|
-
const
|
|
32
|
+
// Target specifier defaults to the current project's build target using a development configuration
|
|
33
|
+
const buildTargetSpecifier = options.buildTarget ?? options.browserTarget ?? `::development`;
|
|
34
|
+
const buildTarget = (0, architect_1.targetFromTargetString)(buildTargetSpecifier, projectName, 'build');
|
|
34
35
|
// Initial options to keep
|
|
35
36
|
const { host, port, poll, open, verbose, watch, allowedHosts, disableHostCheck, liveReload, hmr, headers, proxyConfig, servePath, publicHost, ssl, sslCert, sslKey, forceEsbuild, } = options;
|
|
36
37
|
// Return all the normalized options
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"buildTarget": {
|
|
14
14
|
"type": "string",
|
|
15
15
|
"description": "A build builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
|
|
16
|
-
"pattern": "^[^:\\s]
|
|
16
|
+
"pattern": "^[^:\\s]*:[^:\\s]*(:[^\\s]+)?$"
|
|
17
17
|
},
|
|
18
18
|
"port": {
|
|
19
19
|
"type": "number",
|
|
@@ -30,8 +30,9 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
30
30
|
const workspaceRoot = context.workspaceRoot;
|
|
31
31
|
const projectMetadata = await context.getProjectMetadata(projectName);
|
|
32
32
|
const projectRoot = node_path_1.default.join(workspaceRoot, projectMetadata.root ?? '');
|
|
33
|
-
//
|
|
34
|
-
const
|
|
33
|
+
// Target specifier defaults to the current project's build target with no specified configuration
|
|
34
|
+
const buildTargetSpecifier = options.buildTarget ?? options.browserTarget ?? ':';
|
|
35
|
+
const buildTarget = (0, architect_1.targetFromTargetString)(buildTargetSpecifier, projectName, 'build');
|
|
35
36
|
const i18nOptions = (0, i18n_options_1.createI18nOptions)(projectMetadata);
|
|
36
37
|
// Normalize xliff format extensions
|
|
37
38
|
let format = options.format;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"buildTarget": {
|
|
14
14
|
"type": "string",
|
|
15
15
|
"description": "A builder target to extract i18n messages in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
|
|
16
|
-
"pattern": "^[^:\\s]
|
|
16
|
+
"pattern": "^[^:\\s]*:[^:\\s]*(:[^\\s]+)?$"
|
|
17
17
|
},
|
|
18
18
|
"format": {
|
|
19
19
|
"type": "string",
|
|
@@ -31,15 +31,16 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
33
|
const architect_1 = require("@angular-devkit/architect");
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
34
|
+
const node_child_process_1 = require("node:child_process");
|
|
35
|
+
const fs = __importStar(require("node:fs/promises"));
|
|
36
|
+
const path = __importStar(require("node:path"));
|
|
37
|
+
const node_util_1 = require("node:util");
|
|
37
38
|
const color_1 = require("../../utils/color");
|
|
38
39
|
const test_files_1 = require("../../utils/test-files");
|
|
39
40
|
const application_1 = require("../application");
|
|
40
41
|
const schema_1 = require("../browser-esbuild/schema");
|
|
41
42
|
const options_1 = require("./options");
|
|
42
|
-
const execFile = (0,
|
|
43
|
+
const execFile = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
43
44
|
/** Main execution function for the Jest builder. */
|
|
44
45
|
exports.default = (0, architect_1.createBuilder)(async (schema, context) => {
|
|
45
46
|
context.logger.warn('NOTE: The Jest builder is currently EXPERIMENTAL and not ready for production use.');
|
|
@@ -65,8 +66,21 @@ exports.default = (0, architect_1.createBuilder)(async (schema, context) => {
|
|
|
65
66
|
error: '`jest-environment-jsdom` is not installed. Install it with `npm install jest-environment-jsdom --save-dev`.',
|
|
66
67
|
};
|
|
67
68
|
}
|
|
69
|
+
const [testFiles, customConfig] = await Promise.all([
|
|
70
|
+
(0, test_files_1.findTestFiles)(options.include, options.exclude, context.workspaceRoot),
|
|
71
|
+
findCustomJestConfig(context.workspaceRoot),
|
|
72
|
+
]);
|
|
73
|
+
// Warn if a custom Jest configuration is found. We won't use it, so if a developer is trying to use a custom config, this hopefully
|
|
74
|
+
// makes a better experience than silently ignoring the configuration.
|
|
75
|
+
// Ideally, this would be a hard error. However a Jest config could exist for testing other files in the workspace outside of Angular
|
|
76
|
+
// CLI, so we likely can't produce a hard error in this situation without an opt-out.
|
|
77
|
+
if (customConfig) {
|
|
78
|
+
context.logger.warn('A custom Jest config was found, but this is not supported by `@angular-devkit/build-angular:jest` and will be' +
|
|
79
|
+
` ignored: ${customConfig}. This is an experiment to see if completely abstracting away Jest's configuration is viable. Please` +
|
|
80
|
+
` consider if your use case can be met without directly modifying the Jest config. If this is a major obstacle for your use` +
|
|
81
|
+
` case, please post it in this issue so we can collect feedback and evaluate: https://github.com/angular/angular-cli/issues/25434.`);
|
|
82
|
+
}
|
|
68
83
|
// Build all the test files.
|
|
69
|
-
const testFiles = await (0, test_files_1.findTestFiles)(options.include, options.exclude, context.workspaceRoot);
|
|
70
84
|
const jestGlobal = path.join(__dirname, 'jest-global.mjs');
|
|
71
85
|
const initTestBed = path.join(__dirname, 'init-test-bed.mjs');
|
|
72
86
|
const buildResult = await build(context, {
|
|
@@ -94,6 +108,7 @@ exports.default = (0, architect_1.createBuilder)(async (schema, context) => {
|
|
|
94
108
|
'--experimental-vm-modules',
|
|
95
109
|
jest,
|
|
96
110
|
`--rootDir="${path.join(testOut, 'browser')}"`,
|
|
111
|
+
`--config=${path.join(__dirname, 'jest.config.mjs')}`,
|
|
97
112
|
'--testEnvironment=jsdom',
|
|
98
113
|
// TODO(dgp1130): Enable cache once we have a mechanism for properly clearing / disabling it.
|
|
99
114
|
'--no-cache',
|
|
@@ -158,3 +173,27 @@ function resolveModule(module) {
|
|
|
158
173
|
return undefined;
|
|
159
174
|
}
|
|
160
175
|
}
|
|
176
|
+
/** Returns whether or not the provided directory includes a Jest configuration file. */
|
|
177
|
+
async function findCustomJestConfig(dir) {
|
|
178
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
179
|
+
// Jest supports many file extensions (`js`, `ts`, `cjs`, `cts`, `json`, etc.) Just look
|
|
180
|
+
// for anything with that prefix.
|
|
181
|
+
const config = entries.find((entry) => entry.isFile() && entry.name.startsWith('jest.config.'));
|
|
182
|
+
if (config) {
|
|
183
|
+
return path.join(dir, config.name);
|
|
184
|
+
}
|
|
185
|
+
// Jest also supports a `jest` key in `package.json`, look for a config there.
|
|
186
|
+
const packageJsonPath = path.join(dir, 'package.json');
|
|
187
|
+
let packageJson;
|
|
188
|
+
try {
|
|
189
|
+
packageJson = await fs.readFile(packageJsonPath, 'utf8');
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return undefined; // No package.json, therefore no Jest configuration in it.
|
|
193
|
+
}
|
|
194
|
+
const json = JSON.parse(packageJson);
|
|
195
|
+
if ('jest' in json) {
|
|
196
|
+
return packageJsonPath;
|
|
197
|
+
}
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
|
|
9
|
+
// Empty config file, everything is specified via CLI options right now.
|
|
10
|
+
// This file is used just so Jest doesn't accidentally inherit a custom user-specified Jest config.
|
|
11
|
+
export default {};
|
|
@@ -14,6 +14,13 @@ export interface EmitFileResult {
|
|
|
14
14
|
contents: string;
|
|
15
15
|
dependencies?: readonly string[];
|
|
16
16
|
}
|
|
17
|
+
export declare enum DiagnosticModes {
|
|
18
|
+
None = 0,
|
|
19
|
+
Option = 1,
|
|
20
|
+
Syntactic = 2,
|
|
21
|
+
Semantic = 4,
|
|
22
|
+
All = 7
|
|
23
|
+
}
|
|
17
24
|
export declare abstract class AngularCompilation {
|
|
18
25
|
#private;
|
|
19
26
|
static loadCompilerCli(): Promise<typeof ng>;
|
|
@@ -25,8 +32,8 @@ export declare abstract class AngularCompilation {
|
|
|
25
32
|
referencedFiles: readonly string[];
|
|
26
33
|
}>;
|
|
27
34
|
abstract emitAffectedFiles(): Iterable<EmitFileResult> | Promise<Iterable<EmitFileResult>>;
|
|
28
|
-
protected abstract collectDiagnostics(): Iterable<ts.Diagnostic> | Promise<Iterable<ts.Diagnostic>>;
|
|
29
|
-
diagnoseFiles(): Promise<{
|
|
35
|
+
protected abstract collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic> | Promise<Iterable<ts.Diagnostic>>;
|
|
36
|
+
diagnoseFiles(modes?: DiagnosticModes): Promise<{
|
|
30
37
|
errors?: PartialMessage[];
|
|
31
38
|
warnings?: PartialMessage[];
|
|
32
39
|
}>;
|
|
@@ -30,10 +30,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.AngularCompilation = void 0;
|
|
33
|
+
exports.AngularCompilation = exports.DiagnosticModes = void 0;
|
|
34
34
|
const load_esm_1 = require("../../../../utils/load-esm");
|
|
35
35
|
const profiling_1 = require("../../profiling");
|
|
36
36
|
const diagnostics_1 = require("../diagnostics");
|
|
37
|
+
var DiagnosticModes;
|
|
38
|
+
(function (DiagnosticModes) {
|
|
39
|
+
DiagnosticModes[DiagnosticModes["None"] = 0] = "None";
|
|
40
|
+
DiagnosticModes[DiagnosticModes["Option"] = 1] = "Option";
|
|
41
|
+
DiagnosticModes[DiagnosticModes["Syntactic"] = 2] = "Syntactic";
|
|
42
|
+
DiagnosticModes[DiagnosticModes["Semantic"] = 4] = "Semantic";
|
|
43
|
+
DiagnosticModes[DiagnosticModes["All"] = 7] = "All";
|
|
44
|
+
})(DiagnosticModes || (exports.DiagnosticModes = DiagnosticModes = {}));
|
|
37
45
|
class AngularCompilation {
|
|
38
46
|
static #angularCompilerCliModule;
|
|
39
47
|
static #typescriptModule;
|
|
@@ -64,13 +72,13 @@ class AngularCompilation {
|
|
|
64
72
|
supportJitMode: false,
|
|
65
73
|
}));
|
|
66
74
|
}
|
|
67
|
-
async diagnoseFiles() {
|
|
75
|
+
async diagnoseFiles(modes = DiagnosticModes.All) {
|
|
68
76
|
const result = {};
|
|
69
77
|
// Avoid loading typescript until actually needed.
|
|
70
78
|
// This allows for avoiding the load of typescript in the main thread when using the parallel compilation.
|
|
71
79
|
const typescript = await AngularCompilation.loadTypescript();
|
|
72
80
|
await (0, profiling_1.profileAsync)('NG_DIAGNOSTICS_TOTAL', async () => {
|
|
73
|
-
for (const diagnostic of await this.collectDiagnostics()) {
|
|
81
|
+
for (const diagnostic of await this.collectDiagnostics(modes)) {
|
|
74
82
|
const message = (0, diagnostics_1.convertTypeScriptDiagnostic)(typescript, diagnostic);
|
|
75
83
|
if (diagnostic.category === typescript.DiagnosticCategory.Error) {
|
|
76
84
|
(result.errors ??= []).push(message);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type ng from '@angular/compiler-cli';
|
|
9
9
|
import ts from 'typescript';
|
|
10
10
|
import { AngularHostOptions } from '../angular-host';
|
|
11
|
-
import { AngularCompilation, EmitFileResult } from './angular-compilation';
|
|
11
|
+
import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation';
|
|
12
12
|
export declare class AotCompilation extends AngularCompilation {
|
|
13
13
|
#private;
|
|
14
14
|
initialize(tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions): Promise<{
|
|
@@ -16,6 +16,6 @@ export declare class AotCompilation extends AngularCompilation {
|
|
|
16
16
|
compilerOptions: ng.CompilerOptions;
|
|
17
17
|
referencedFiles: readonly string[];
|
|
18
18
|
}>;
|
|
19
|
-
collectDiagnostics(): Iterable<ts.Diagnostic>;
|
|
19
|
+
collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic>;
|
|
20
20
|
emitAffectedFiles(): Iterable<EmitFileResult>;
|
|
21
21
|
}
|
|
@@ -86,22 +86,33 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
86
86
|
this.#state = new AngularCompilationState(angularProgram, host, typeScriptProgram, affectedFiles, affectedFiles.size === 1 ? OptimizeFor.SingleFile : OptimizeFor.WholeProgram, (0, web_worker_transformer_1.createWorkerTransformer)(hostOptions.processWebWorker.bind(hostOptions)), this.#state?.diagnosticCache);
|
|
87
87
|
return { affectedFiles, compilerOptions, referencedFiles };
|
|
88
88
|
}
|
|
89
|
-
*collectDiagnostics() {
|
|
89
|
+
*collectDiagnostics(modes) {
|
|
90
90
|
(0, node_assert_1.default)(this.#state, 'Angular compilation must be initialized prior to collecting diagnostics.');
|
|
91
91
|
const { affectedFiles, angularCompiler, diagnosticCache, templateDiagnosticsOptimization, typeScriptProgram, } = this.#state;
|
|
92
|
+
const syntactic = modes & angular_compilation_1.DiagnosticModes.Syntactic;
|
|
93
|
+
const semantic = modes & angular_compilation_1.DiagnosticModes.Semantic;
|
|
92
94
|
// Collect program level diagnostics
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
if (modes & angular_compilation_1.DiagnosticModes.Option) {
|
|
96
|
+
yield* typeScriptProgram.getConfigFileParsingDiagnostics();
|
|
97
|
+
yield* angularCompiler.getOptionDiagnostics();
|
|
98
|
+
yield* typeScriptProgram.getOptionsDiagnostics();
|
|
99
|
+
}
|
|
100
|
+
if (syntactic) {
|
|
101
|
+
yield* typeScriptProgram.getGlobalDiagnostics();
|
|
102
|
+
}
|
|
97
103
|
// Collect source file specific diagnostics
|
|
98
104
|
for (const sourceFile of typeScriptProgram.getSourceFiles()) {
|
|
99
105
|
if (angularCompiler.ignoreForDiagnostics.has(sourceFile)) {
|
|
100
106
|
continue;
|
|
101
107
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
if (syntactic) {
|
|
109
|
+
// TypeScript will use cached diagnostics for files that have not been
|
|
110
|
+
// changed or affected for this build when using incremental building.
|
|
111
|
+
yield* (0, profiling_1.profileSync)('NG_DIAGNOSTICS_SYNTACTIC', () => typeScriptProgram.getSyntacticDiagnostics(sourceFile), true);
|
|
112
|
+
}
|
|
113
|
+
if (!semantic) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
105
116
|
yield* (0, profiling_1.profileSync)('NG_DIAGNOSTICS_SEMANTIC', () => typeScriptProgram.getSemanticDiagnostics(sourceFile), true);
|
|
106
117
|
// Declaration files cannot have template diagnostics
|
|
107
118
|
if (sourceFile.isDeclarationFile) {
|
|
@@ -5,6 +5,6 @@
|
|
|
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
|
-
export { AngularCompilation } from './angular-compilation';
|
|
8
|
+
export { AngularCompilation, DiagnosticModes } from './angular-compilation';
|
|
9
9
|
export { createAngularCompilation } from './factory';
|
|
10
10
|
export { NoopCompilation } from './noop-compilation';
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.NoopCompilation = exports.createAngularCompilation = exports.AngularCompilation = void 0;
|
|
10
|
+
exports.NoopCompilation = exports.createAngularCompilation = exports.DiagnosticModes = exports.AngularCompilation = void 0;
|
|
11
11
|
var angular_compilation_1 = require("./angular-compilation");
|
|
12
12
|
Object.defineProperty(exports, "AngularCompilation", { enumerable: true, get: function () { return angular_compilation_1.AngularCompilation; } });
|
|
13
|
+
Object.defineProperty(exports, "DiagnosticModes", { enumerable: true, get: function () { return angular_compilation_1.DiagnosticModes; } });
|
|
13
14
|
var factory_1 = require("./factory");
|
|
14
15
|
Object.defineProperty(exports, "createAngularCompilation", { enumerable: true, get: function () { return factory_1.createAngularCompilation; } });
|
|
15
16
|
var noop_compilation_1 = require("./noop-compilation");
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type ng from '@angular/compiler-cli';
|
|
9
9
|
import ts from 'typescript';
|
|
10
10
|
import { AngularHostOptions } from '../angular-host';
|
|
11
|
-
import { AngularCompilation, EmitFileResult } from './angular-compilation';
|
|
11
|
+
import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation';
|
|
12
12
|
export declare class JitCompilation extends AngularCompilation {
|
|
13
13
|
#private;
|
|
14
14
|
initialize(tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions): Promise<{
|
|
@@ -16,6 +16,6 @@ export declare class JitCompilation extends AngularCompilation {
|
|
|
16
16
|
compilerOptions: ng.CompilerOptions;
|
|
17
17
|
referencedFiles: readonly string[];
|
|
18
18
|
}>;
|
|
19
|
-
collectDiagnostics(): Iterable<ts.Diagnostic>;
|
|
19
|
+
collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic>;
|
|
20
20
|
emitAffectedFiles(): Iterable<EmitFileResult>;
|
|
21
21
|
}
|
|
@@ -51,15 +51,21 @@ class JitCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
51
51
|
.map((sourceFile) => sourceFile.fileName);
|
|
52
52
|
return { affectedFiles, compilerOptions, referencedFiles };
|
|
53
53
|
}
|
|
54
|
-
*collectDiagnostics() {
|
|
54
|
+
*collectDiagnostics(modes) {
|
|
55
55
|
(0, node_assert_1.default)(this.#state, 'Compilation must be initialized prior to collecting diagnostics.');
|
|
56
56
|
const { typeScriptProgram } = this.#state;
|
|
57
57
|
// Collect program level diagnostics
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
if (modes & angular_compilation_1.DiagnosticModes.Option) {
|
|
59
|
+
yield* typeScriptProgram.getConfigFileParsingDiagnostics();
|
|
60
|
+
yield* typeScriptProgram.getOptionsDiagnostics();
|
|
61
|
+
}
|
|
62
|
+
if (modes & angular_compilation_1.DiagnosticModes.Syntactic) {
|
|
63
|
+
yield* typeScriptProgram.getGlobalDiagnostics();
|
|
64
|
+
yield* (0, profiling_1.profileSync)('NG_DIAGNOSTICS_SYNTACTIC', () => typeScriptProgram.getSyntacticDiagnostics());
|
|
65
|
+
}
|
|
66
|
+
if (modes & angular_compilation_1.DiagnosticModes.Semantic) {
|
|
67
|
+
yield* (0, profiling_1.profileSync)('NG_DIAGNOSTICS_SEMANTIC', () => typeScriptProgram.getSemanticDiagnostics());
|
|
68
|
+
}
|
|
63
69
|
}
|
|
64
70
|
emitAffectedFiles() {
|
|
65
71
|
(0, node_assert_1.default)(this.#state, 'Compilation must be initialized prior to emitting files.');
|
|
@@ -9,7 +9,7 @@ import type { CompilerOptions } from '@angular/compiler-cli';
|
|
|
9
9
|
import type { PartialMessage } from 'esbuild';
|
|
10
10
|
import type { SourceFile } from 'typescript';
|
|
11
11
|
import type { AngularHostOptions } from '../angular-host';
|
|
12
|
-
import { AngularCompilation, EmitFileResult } from './angular-compilation';
|
|
12
|
+
import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation';
|
|
13
13
|
/**
|
|
14
14
|
* An Angular compilation which uses a Node.js Worker thread to load and execute
|
|
15
15
|
* the TypeScript and Angular compilers. This allows for longer synchronous actions
|
|
@@ -32,7 +32,7 @@ export declare class ParallelCompilation extends AngularCompilation {
|
|
|
32
32
|
* with the serializable esbuild compatible diagnostics.
|
|
33
33
|
*/
|
|
34
34
|
protected collectDiagnostics(): never;
|
|
35
|
-
diagnoseFiles(): Promise<{
|
|
35
|
+
diagnoseFiles(modes?: DiagnosticModes): Promise<{
|
|
36
36
|
errors?: PartialMessage[];
|
|
37
37
|
warnings?: PartialMessage[];
|
|
38
38
|
}>;
|
|
@@ -106,8 +106,8 @@ class ParallelCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
106
106
|
collectDiagnostics() {
|
|
107
107
|
throw new Error('Not implemented in ParallelCompilation.');
|
|
108
108
|
}
|
|
109
|
-
diagnoseFiles() {
|
|
110
|
-
return this.#worker.run(
|
|
109
|
+
diagnoseFiles(modes = angular_compilation_1.DiagnosticModes.All) {
|
|
110
|
+
return this.#worker.run(modes, { name: 'diagnose' });
|
|
111
111
|
}
|
|
112
112
|
emitAffectedFiles() {
|
|
113
113
|
return this.#worker.run(undefined, { name: 'emit' });
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
/// <reference types="@types/node/ts4.8/worker_threads" />
|
|
11
11
|
import type { PartialMessage } from 'esbuild';
|
|
12
12
|
import { type MessagePort } from 'node:worker_threads';
|
|
13
|
+
import type { DiagnosticModes } from './angular-compilation';
|
|
13
14
|
export interface InitRequest {
|
|
14
15
|
jit: boolean;
|
|
15
16
|
tsconfig: string;
|
|
@@ -26,7 +27,7 @@ export declare function initialize(request: InitRequest): Promise<{
|
|
|
26
27
|
allowJs: boolean | undefined;
|
|
27
28
|
};
|
|
28
29
|
}>;
|
|
29
|
-
export declare function diagnose(): Promise<{
|
|
30
|
+
export declare function diagnose(modes: DiagnosticModes): Promise<{
|
|
30
31
|
errors?: PartialMessage[];
|
|
31
32
|
warnings?: PartialMessage[];
|
|
32
33
|
}>;
|
|
@@ -72,9 +72,9 @@ async function initialize(request) {
|
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
exports.initialize = initialize;
|
|
75
|
-
async function diagnose() {
|
|
75
|
+
async function diagnose(modes) {
|
|
76
76
|
(0, node_assert_1.default)(compilation);
|
|
77
|
-
const diagnostics = await compilation.diagnoseFiles();
|
|
77
|
+
const diagnostics = await compilation.diagnoseFiles(modes);
|
|
78
78
|
return diagnostics;
|
|
79
79
|
}
|
|
80
80
|
exports.diagnose = diagnose;
|
|
@@ -195,13 +195,6 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
195
195
|
hasCompilationErrors = await sharedTSCompilationState.waitUntilReady;
|
|
196
196
|
return result;
|
|
197
197
|
}
|
|
198
|
-
const diagnostics = await compilation.diagnoseFiles();
|
|
199
|
-
if (diagnostics.errors?.length) {
|
|
200
|
-
(result.errors ??= []).push(...diagnostics.errors);
|
|
201
|
-
}
|
|
202
|
-
if (diagnostics.warnings?.length) {
|
|
203
|
-
(result.warnings ??= []).push(...diagnostics.warnings);
|
|
204
|
-
}
|
|
205
198
|
// Update TypeScript file output cache for all affected files
|
|
206
199
|
try {
|
|
207
200
|
await (0, profiling_1.profileAsync)('NG_EMIT_TS', async () => {
|
|
@@ -222,6 +215,13 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
222
215
|
],
|
|
223
216
|
});
|
|
224
217
|
}
|
|
218
|
+
const diagnostics = await compilation.diagnoseFiles(environment_options_1.useTypeChecking ? compilation_1.DiagnosticModes.All : compilation_1.DiagnosticModes.All & ~compilation_1.DiagnosticModes.Semantic);
|
|
219
|
+
if (diagnostics.errors?.length) {
|
|
220
|
+
(result.errors ??= []).push(...diagnostics.errors);
|
|
221
|
+
}
|
|
222
|
+
if (diagnostics.warnings?.length) {
|
|
223
|
+
(result.warnings ??= []).push(...diagnostics.warnings);
|
|
224
|
+
}
|
|
225
225
|
// Add errors from failed additional results.
|
|
226
226
|
// This must be done after emit to capture latest web worker results.
|
|
227
227
|
for (const { errors } of additionalResults.values()) {
|
|
@@ -61,6 +61,7 @@ function createAngularMemoryPlugin(options) {
|
|
|
61
61
|
map: mapContents && Buffer.from(mapContents).toString('utf-8'),
|
|
62
62
|
};
|
|
63
63
|
},
|
|
64
|
+
// eslint-disable-next-line max-lines-per-function
|
|
64
65
|
configureServer(server) {
|
|
65
66
|
const originalssrTransform = server.ssrTransform;
|
|
66
67
|
server.ssrTransform = async (code, map, url, originalCode) => {
|
|
@@ -124,14 +125,15 @@ function createAngularMemoryPlugin(options) {
|
|
|
124
125
|
// Returning a function, installs middleware after the main transform middleware but
|
|
125
126
|
// before the built-in HTML middleware
|
|
126
127
|
return () => {
|
|
128
|
+
server.middlewares.use(angularHtmlFallbackMiddleware);
|
|
127
129
|
function angularSSRMiddleware(req, res, next) {
|
|
128
130
|
const url = req.originalUrl;
|
|
129
131
|
if (!req.url ||
|
|
130
132
|
// Skip if path is not defined.
|
|
131
133
|
!url ||
|
|
132
134
|
// Skip if path is like a file.
|
|
133
|
-
// NOTE: We use a
|
|
134
|
-
|
|
135
|
+
// NOTE: We use a mime type lookup to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
|
|
136
|
+
lookupMimeTypeFromRequest(url)) {
|
|
135
137
|
next();
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
@@ -212,12 +214,13 @@ exports.createAngularMemoryPlugin = createAngularMemoryPlugin;
|
|
|
212
214
|
*/
|
|
213
215
|
async function loadViteClientCode(file) {
|
|
214
216
|
const originalContents = await (0, promises_1.readFile)(file, 'utf-8');
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
const firstUpdate = originalContents.replace('You can also disable this overlay by setting', '');
|
|
218
|
+
(0, node_assert_1.default)(originalContents !== firstUpdate, 'Failed to update Vite client error overlay text. (1)');
|
|
219
|
+
const secondUpdate = firstUpdate.replace(
|
|
217
220
|
// eslint-disable-next-line max-len
|
|
218
|
-
'<code part="config-option-name">server.hmr.overlay</code> to <code part="config-option-value">false</code> in <code part="config-file-name"
|
|
219
|
-
(0, node_assert_1.default)(
|
|
220
|
-
return
|
|
221
|
+
'<code part="config-option-name">server.hmr.overlay</code> to <code part="config-option-value">false</code> in <code part="config-file-name">${hmrConfigName}.</code>', '');
|
|
222
|
+
(0, node_assert_1.default)(firstUpdate !== secondUpdate, 'Failed to update Vite client error overlay text. (2)');
|
|
223
|
+
return secondUpdate;
|
|
221
224
|
}
|
|
222
225
|
function pathnameWithoutBasePath(url, basePath) {
|
|
223
226
|
const parsedUrl = new URL(url, 'http://localhost');
|
|
@@ -227,3 +230,23 @@ function pathnameWithoutBasePath(url, basePath) {
|
|
|
227
230
|
? pathname.slice(basePath.length - 1)
|
|
228
231
|
: pathname;
|
|
229
232
|
}
|
|
233
|
+
function angularHtmlFallbackMiddleware(req, res, next) {
|
|
234
|
+
// Similar to how it is handled in vite
|
|
235
|
+
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L15C19-L15C45
|
|
236
|
+
if ((req.method === 'GET' || req.method === 'HEAD') &&
|
|
237
|
+
(!req.url || !lookupMimeTypeFromRequest(req.url)) &&
|
|
238
|
+
(!req.headers.accept ||
|
|
239
|
+
req.headers.accept.includes('text/html') ||
|
|
240
|
+
req.headers.accept.includes('text/*') ||
|
|
241
|
+
req.headers.accept.includes('*/*'))) {
|
|
242
|
+
req.url = '/index.html';
|
|
243
|
+
}
|
|
244
|
+
next();
|
|
245
|
+
}
|
|
246
|
+
function lookupMimeTypeFromRequest(url) {
|
|
247
|
+
const extension = (0, node_path_1.extname)(url.split('?')[0]);
|
|
248
|
+
if (extension === '.ico') {
|
|
249
|
+
return 'image/x-icon';
|
|
250
|
+
}
|
|
251
|
+
return extension && (0, mrmime_1.lookup)(extension);
|
|
252
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.shouldWatchRoot = exports.debugPerformance = exports.useLegacySass = exports.useParallelTs = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
10
|
+
exports.useTypeChecking = exports.shouldWatchRoot = exports.debugPerformance = exports.useLegacySass = exports.useParallelTs = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
11
11
|
const color_1 = require("./color");
|
|
12
12
|
function isDisabled(variable) {
|
|
13
13
|
return variable === '0' || variable.toLowerCase() === 'false';
|
|
@@ -83,3 +83,5 @@ const debugPerfVariable = process.env['NG_BUILD_DEBUG_PERF'];
|
|
|
83
83
|
exports.debugPerformance = isPresent(debugPerfVariable) && isEnabled(debugPerfVariable);
|
|
84
84
|
const watchRootVariable = process.env['NG_BUILD_WATCH_ROOT'];
|
|
85
85
|
exports.shouldWatchRoot = isPresent(watchRootVariable) && isEnabled(watchRootVariable);
|
|
86
|
+
const typeCheckingVariable = process.env['NG_BUILD_TYPE_CHECK'];
|
|
87
|
+
exports.useTypeChecking = !isPresent(typeCheckingVariable) || !isDisabled(typeCheckingVariable);
|