@angular-devkit/build-angular 19.0.0-next.9 → 19.0.0-rc.1
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/builders.json +6 -1
- package/package.json +23 -30
- package/src/builders/dev-server/builder.js +4 -0
- package/src/builders/dev-server/options.d.ts +1 -1
- package/src/builders/dev-server/options.js +1 -1
- package/src/builders/dev-server/schema.json +1 -2
- package/src/builders/extract-i18n/application-extraction.js +4 -2
- package/src/builders/karma/application_builder.js +138 -30
- package/src/builders/protractor-error/index.d.ts +10 -0
- package/src/builders/protractor-error/index.js +14 -0
- package/src/tools/babel/presets/application.js +0 -25
- package/src/tools/webpack/configs/common.js +4 -1
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/process-bundle.js +0 -5
- package/src/utils/tailwind.js +1 -1
package/builders.json
CHANGED
|
@@ -43,9 +43,14 @@
|
|
|
43
43
|
"description": "Run unit tests with Web Test Runner."
|
|
44
44
|
},
|
|
45
45
|
"protractor": {
|
|
46
|
+
"implementation": "./src/builders/protractor-error",
|
|
47
|
+
"schema": "./src/builders/protractor/schema.json",
|
|
48
|
+
"description": "Throw an error that Protractor is end-of-life and no longer supported."
|
|
49
|
+
},
|
|
50
|
+
"private-protractor": {
|
|
46
51
|
"implementation": "./src/builders/protractor",
|
|
47
52
|
"schema": "./src/builders/protractor/schema.json",
|
|
48
|
-
"description": "
|
|
53
|
+
"description": "PRIVATE API - Do not use."
|
|
49
54
|
},
|
|
50
55
|
"server": {
|
|
51
56
|
"implementation": "./src/builders/server",
|
package/package.json
CHANGED
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "19.0.0-
|
|
3
|
+
"version": "19.0.0-rc.1",
|
|
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.3.0",
|
|
10
|
-
"@angular-devkit/architect": "0.1900.0-
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1900.0-
|
|
12
|
-
"@angular-devkit/core": "19.0.0-
|
|
13
|
-
"@angular/build": "19.0.0-
|
|
14
|
-
"@babel/core": "7.
|
|
15
|
-
"@babel/generator": "7.
|
|
16
|
-
"@babel/helper-annotate-as-pure": "7.
|
|
10
|
+
"@angular-devkit/architect": "0.1900.0-rc.1",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1900.0-rc.1",
|
|
12
|
+
"@angular-devkit/core": "19.0.0-rc.1",
|
|
13
|
+
"@angular/build": "19.0.0-rc.1",
|
|
14
|
+
"@babel/core": "7.26.0",
|
|
15
|
+
"@babel/generator": "7.26.2",
|
|
16
|
+
"@babel/helper-annotate-as-pure": "7.25.9",
|
|
17
17
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
18
|
-
"@babel/plugin-transform-async-generator-functions": "7.25.
|
|
19
|
-
"@babel/plugin-transform-async-to-generator": "7.
|
|
20
|
-
"@babel/plugin-transform-runtime": "7.25.
|
|
21
|
-
"@babel/preset-env": "7.
|
|
22
|
-
"@babel/runtime": "7.
|
|
23
|
-
"@discoveryjs/json-ext": "0.6.
|
|
24
|
-
"@ngtools/webpack": "19.0.0-
|
|
18
|
+
"@babel/plugin-transform-async-generator-functions": "7.25.9",
|
|
19
|
+
"@babel/plugin-transform-async-to-generator": "7.25.9",
|
|
20
|
+
"@babel/plugin-transform-runtime": "7.25.9",
|
|
21
|
+
"@babel/preset-env": "7.26.0",
|
|
22
|
+
"@babel/runtime": "7.26.0",
|
|
23
|
+
"@discoveryjs/json-ext": "0.6.3",
|
|
24
|
+
"@ngtools/webpack": "19.0.0-rc.1",
|
|
25
25
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
26
26
|
"ansi-colors": "4.1.3",
|
|
27
27
|
"autoprefixer": "10.4.20",
|
|
28
28
|
"babel-loader": "9.2.1",
|
|
29
29
|
"browserslist": "^4.21.5",
|
|
30
30
|
"copy-webpack-plugin": "12.0.2",
|
|
31
|
-
"critters": "0.0.24",
|
|
32
31
|
"css-loader": "7.1.2",
|
|
33
32
|
"esbuild-wasm": "0.24.0",
|
|
34
33
|
"fast-glob": "3.3.2",
|
|
35
|
-
"http-proxy-middleware": "3.0.
|
|
36
|
-
"https-proxy-agent": "7.0.5",
|
|
34
|
+
"http-proxy-middleware": "3.0.3",
|
|
37
35
|
"istanbul-lib-instrument": "6.0.3",
|
|
38
36
|
"jsonc-parser": "3.3.1",
|
|
39
37
|
"karma-source-map-support": "1.4.0",
|
|
@@ -41,29 +39,24 @@
|
|
|
41
39
|
"less-loader": "12.2.0",
|
|
42
40
|
"license-webpack-plugin": "4.0.2",
|
|
43
41
|
"loader-utils": "3.3.1",
|
|
44
|
-
"
|
|
45
|
-
"mini-css-extract-plugin": "2.9.1",
|
|
46
|
-
"mrmime": "2.0.0",
|
|
42
|
+
"mini-css-extract-plugin": "2.9.2",
|
|
47
43
|
"open": "10.1.0",
|
|
48
44
|
"ora": "5.4.1",
|
|
49
|
-
"parse5-html-rewriting-stream": "7.0.0",
|
|
50
45
|
"picomatch": "4.0.2",
|
|
51
46
|
"piscina": "4.7.0",
|
|
52
47
|
"postcss": "8.4.47",
|
|
53
48
|
"postcss-loader": "8.1.1",
|
|
54
49
|
"resolve-url-loader": "5.0.0",
|
|
55
50
|
"rxjs": "7.8.1",
|
|
56
|
-
"sass": "1.
|
|
57
|
-
"sass-loader": "16.0.
|
|
51
|
+
"sass": "1.80.6",
|
|
52
|
+
"sass-loader": "16.0.3",
|
|
58
53
|
"semver": "7.6.3",
|
|
59
54
|
"source-map-loader": "5.0.0",
|
|
60
55
|
"source-map-support": "0.5.21",
|
|
61
|
-
"terser": "5.
|
|
56
|
+
"terser": "5.36.0",
|
|
62
57
|
"tree-kill": "1.2.2",
|
|
63
|
-
"tslib": "2.
|
|
64
|
-
"
|
|
65
|
-
"watchpack": "2.4.2",
|
|
66
|
-
"webpack": "5.95.0",
|
|
58
|
+
"tslib": "2.8.1",
|
|
59
|
+
"webpack": "5.96.1",
|
|
67
60
|
"webpack-dev-middleware": "7.4.2",
|
|
68
61
|
"webpack-dev-server": "5.1.0",
|
|
69
62
|
"webpack-merge": "6.0.1",
|
|
@@ -77,7 +70,7 @@
|
|
|
77
70
|
"@angular/localize": "^19.0.0-next.0",
|
|
78
71
|
"@angular/platform-server": "^19.0.0-next.0",
|
|
79
72
|
"@angular/service-worker": "^19.0.0-next.0",
|
|
80
|
-
"@angular/ssr": "^19.0.0-
|
|
73
|
+
"@angular/ssr": "^19.0.0-rc.1",
|
|
81
74
|
"@web/test-runner": "^0.19.0",
|
|
82
75
|
"browser-sync": "^3.0.2",
|
|
83
76
|
"jest": "^29.5.0",
|
|
@@ -72,6 +72,8 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
72
72
|
if (options.disableHostCheck) {
|
|
73
73
|
context.logger.warn(`The "disableHostCheck" option will not be used because it is not supported by the "${builderName}" builder.`);
|
|
74
74
|
}
|
|
75
|
+
// New build system defaults hmr option to the value of liveReload
|
|
76
|
+
normalizedOptions.hmr ??= normalizedOptions.liveReload;
|
|
75
77
|
return (0, rxjs_1.defer)(() => Promise.all([Promise.resolve().then(() => __importStar(require('@angular/build/private'))), Promise.resolve().then(() => __importStar(require('../browser-esbuild')))])).pipe((0, rxjs_1.switchMap)(([{ serveWithVite, buildApplicationInternal }, { convertBrowserOptions }]) => serveWithVite(normalizedOptions, builderName, (options, context, codePlugins) => {
|
|
76
78
|
return builderName === '@angular-devkit/build-angular:browser-esbuild'
|
|
77
79
|
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -91,6 +93,8 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
91
93
|
if (extensions?.middleware?.length) {
|
|
92
94
|
throw new Error('Only the "application" and "browser-esbuild" builders support middleware.');
|
|
93
95
|
}
|
|
96
|
+
// Webpack based build systems default to false for hmr option
|
|
97
|
+
normalizedOptions.hmr ??= false;
|
|
94
98
|
// Use Webpack for all other browser targets
|
|
95
99
|
return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./webpack-server')))).pipe((0, rxjs_1.switchMap)(({ serveWebpackBrowser }) => serveWebpackBrowser(normalizedOptions, builderName, context, transforms)));
|
|
96
100
|
}));
|
|
@@ -26,7 +26,7 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
26
26
|
open: boolean | undefined;
|
|
27
27
|
verbose: boolean | undefined;
|
|
28
28
|
watch: boolean | undefined;
|
|
29
|
-
liveReload: boolean
|
|
29
|
+
liveReload: boolean;
|
|
30
30
|
hmr: boolean | undefined;
|
|
31
31
|
headers: {
|
|
32
32
|
[key: string]: string;
|
|
@@ -31,9 +31,11 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
31
31
|
buildOptions.budgets = undefined;
|
|
32
32
|
buildOptions.index = false;
|
|
33
33
|
buildOptions.serviceWorker = false;
|
|
34
|
+
buildOptions.server = undefined;
|
|
34
35
|
buildOptions.ssr = false;
|
|
35
|
-
buildOptions.appShell =
|
|
36
|
-
buildOptions.prerender =
|
|
36
|
+
buildOptions.appShell = undefined;
|
|
37
|
+
buildOptions.prerender = undefined;
|
|
38
|
+
buildOptions.outputMode = undefined;
|
|
37
39
|
const builderResult = await first((0, private_1.buildApplicationInternal)(buildOptions, context));
|
|
38
40
|
let success = false;
|
|
39
41
|
if (!builderResult || builderResult.kind === private_1.ResultKind.Failure) {
|
|
@@ -50,26 +50,84 @@ class ApplicationBuildError extends Error {
|
|
|
50
50
|
this.name = 'ApplicationBuildError';
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
const LATEST_BUILD_FILES_TOKEN = 'angularLatestBuildFiles';
|
|
54
|
+
class AngularAssetsMiddleware {
|
|
55
|
+
serveFile;
|
|
56
|
+
latestBuildFiles;
|
|
57
|
+
static $inject = ['serveFile', LATEST_BUILD_FILES_TOKEN];
|
|
58
|
+
static NAME = 'angular-test-assets';
|
|
59
|
+
constructor(serveFile, latestBuildFiles) {
|
|
60
|
+
this.serveFile = serveFile;
|
|
61
|
+
this.latestBuildFiles = latestBuildFiles;
|
|
62
|
+
}
|
|
63
|
+
handle(req, res, next) {
|
|
64
|
+
let err = null;
|
|
65
|
+
try {
|
|
66
|
+
const url = new URL(`http://${req.headers['host']}${req.url}`);
|
|
67
|
+
const file = this.latestBuildFiles.files[url.pathname.slice(1)];
|
|
68
|
+
if (file?.origin === 'disk') {
|
|
69
|
+
this.serveFile(file.inputPath, undefined, res);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
else if (file?.origin === 'memory') {
|
|
73
|
+
// Include pathname to help with Content-Type headers.
|
|
74
|
+
this.serveFile(`/unused/${url.pathname}`, undefined, res, undefined, file.contents, true);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
err = e;
|
|
80
|
+
}
|
|
81
|
+
next(err);
|
|
82
|
+
}
|
|
83
|
+
static createPlugin(initialFiles) {
|
|
84
|
+
return {
|
|
85
|
+
[LATEST_BUILD_FILES_TOKEN]: ['value', { files: { ...initialFiles.files } }],
|
|
86
|
+
[`middleware:${AngularAssetsMiddleware.NAME}`]: [
|
|
87
|
+
'factory',
|
|
88
|
+
Object.assign((...args) => {
|
|
89
|
+
const inst = new AngularAssetsMiddleware(...args);
|
|
90
|
+
return inst.handle.bind(inst);
|
|
91
|
+
}, AngularAssetsMiddleware),
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function injectKarmaReporter(context, buildOptions, buildIterator, karmaConfig, subscriber) {
|
|
54
97
|
const reporterName = 'angular-progress-notifier';
|
|
55
98
|
class ProgressNotifierReporter {
|
|
56
99
|
emitter;
|
|
57
|
-
|
|
58
|
-
|
|
100
|
+
latestBuildFiles;
|
|
101
|
+
static $inject = ['emitter', LATEST_BUILD_FILES_TOKEN];
|
|
102
|
+
constructor(emitter, latestBuildFiles) {
|
|
59
103
|
this.emitter = emitter;
|
|
104
|
+
this.latestBuildFiles = latestBuildFiles;
|
|
60
105
|
this.startWatchingBuild();
|
|
61
106
|
}
|
|
62
107
|
startWatchingBuild() {
|
|
63
108
|
void (async () => {
|
|
64
|
-
for await
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
109
|
+
// This is effectively "for await of but skip what's already consumed".
|
|
110
|
+
let isDone = false; // to mark the loop condition as "not constant".
|
|
111
|
+
while (!isDone) {
|
|
112
|
+
const { done, value: buildOutput } = await buildIterator.next();
|
|
113
|
+
if (done) {
|
|
114
|
+
isDone = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
68
117
|
if (buildOutput.kind === private_1.ResultKind.Failure) {
|
|
69
118
|
subscriber.next({ success: false, message: 'Build failed' });
|
|
70
119
|
}
|
|
71
120
|
else if (buildOutput.kind === private_1.ResultKind.Incremental ||
|
|
72
121
|
buildOutput.kind === private_1.ResultKind.Full) {
|
|
122
|
+
if (buildOutput.kind === private_1.ResultKind.Full) {
|
|
123
|
+
this.latestBuildFiles.files = buildOutput.files;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.latestBuildFiles.files = {
|
|
127
|
+
...this.latestBuildFiles.files,
|
|
128
|
+
...buildOutput.files,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
73
131
|
await writeTestFiles(buildOutput.files, buildOptions.outputPath);
|
|
74
132
|
this.emitter.refreshFiles();
|
|
75
133
|
}
|
|
@@ -96,9 +154,11 @@ function injectKarmaReporter(context, buildOptions, karmaConfig, subscriber) {
|
|
|
96
154
|
});
|
|
97
155
|
}
|
|
98
156
|
function execute(options, context, karmaOptions, transforms = {}) {
|
|
99
|
-
return (0, rxjs_1.from)(initializeApplication(options, context, karmaOptions, transforms)).pipe((0, rxjs_1.switchMap)(([karma, karmaConfig, buildOptions]) => new rxjs_1.Observable((subscriber) => {
|
|
100
|
-
|
|
101
|
-
|
|
157
|
+
return (0, rxjs_1.from)(initializeApplication(options, context, karmaOptions, transforms)).pipe((0, rxjs_1.switchMap)(([karma, karmaConfig, buildOptions, buildIterator]) => new rxjs_1.Observable((subscriber) => {
|
|
158
|
+
// If `--watch` is explicitly enabled or if we are keeping the Karma
|
|
159
|
+
// process running, we should hook Karma into the build.
|
|
160
|
+
if (buildIterator) {
|
|
161
|
+
injectKarmaReporter(context, buildOptions, buildIterator, karmaConfig, subscriber);
|
|
102
162
|
}
|
|
103
163
|
// Complete the observable once the Karma server returns.
|
|
104
164
|
const karmaServer = new karma.Server(karmaConfig, (exitCode) => {
|
|
@@ -136,11 +196,21 @@ function normalizePolyfills(polyfills) {
|
|
|
136
196
|
async function collectEntrypoints(options, context, projectSourceRoot) {
|
|
137
197
|
// Glob for files to test.
|
|
138
198
|
const testFiles = await (0, find_tests_1.findTests)(options.include ?? [], options.exclude ?? [], context.workspaceRoot, projectSourceRoot);
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
199
|
+
const seen = new Set();
|
|
200
|
+
return new Map(Array.from(testFiles, (testFile) => {
|
|
201
|
+
const relativePath = path
|
|
202
|
+
.relative(testFile.startsWith(projectSourceRoot) ? projectSourceRoot : context.workspaceRoot, testFile)
|
|
203
|
+
.replace(/^[./]+/, '_')
|
|
204
|
+
.replace(/\//g, '-');
|
|
205
|
+
let uniqueName = `spec-${path.basename(relativePath, path.extname(relativePath))}`;
|
|
206
|
+
let suffix = 2;
|
|
207
|
+
while (seen.has(uniqueName)) {
|
|
208
|
+
uniqueName = `${relativePath}-${suffix}`;
|
|
209
|
+
++suffix;
|
|
210
|
+
}
|
|
211
|
+
seen.add(uniqueName);
|
|
212
|
+
return [uniqueName, testFile];
|
|
213
|
+
}));
|
|
144
214
|
}
|
|
145
215
|
async function initializeApplication(options, context, karmaOptions, transforms = {}) {
|
|
146
216
|
if (transforms.webpackConfiguration) {
|
|
@@ -153,10 +223,18 @@ async function initializeApplication(options, context, karmaOptions, transforms
|
|
|
153
223
|
collectEntrypoints(options, context, projectSourceRoot),
|
|
154
224
|
fs.rm(outputPath, { recursive: true, force: true }),
|
|
155
225
|
]);
|
|
226
|
+
const mainName = 'test_main';
|
|
227
|
+
if (options.main) {
|
|
228
|
+
entryPoints.set(mainName, options.main);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
entryPoints.set(mainName, '@angular-devkit/build-angular/src/builders/karma/init_test_bed.js');
|
|
232
|
+
}
|
|
156
233
|
const instrumentForCoverage = options.codeCoverage
|
|
157
234
|
? createInstrumentationFilter(projectSourceRoot, getInstrumentationExcludedPaths(context.workspaceRoot, options.codeCoverageExclude ?? []))
|
|
158
235
|
: undefined;
|
|
159
236
|
const buildOptions = {
|
|
237
|
+
assets: options.assets,
|
|
160
238
|
entryPoints,
|
|
161
239
|
tsConfig: options.tsConfig,
|
|
162
240
|
outputPath,
|
|
@@ -173,9 +251,10 @@ async function initializeApplication(options, context, karmaOptions, transforms
|
|
|
173
251
|
styles: options.styles,
|
|
174
252
|
polyfills: normalizePolyfills(options.polyfills),
|
|
175
253
|
webWorkerTsConfig: options.webWorkerTsConfig,
|
|
254
|
+
watch: options.watch ?? !karmaOptions.singleRun,
|
|
176
255
|
};
|
|
177
256
|
// Build tests with `application` builder, using test files as entry points.
|
|
178
|
-
const buildOutput = await first((0, private_1.buildApplicationInternal)(buildOptions, context));
|
|
257
|
+
const [buildOutput, buildIterator] = await first((0, private_1.buildApplicationInternal)(buildOptions, context), { cancel: !buildOptions.watch });
|
|
179
258
|
if (buildOutput.kind === private_1.ResultKind.Failure) {
|
|
180
259
|
throw new ApplicationBuildError('Build failed');
|
|
181
260
|
}
|
|
@@ -187,39 +266,60 @@ async function initializeApplication(options, context, karmaOptions, transforms
|
|
|
187
266
|
karmaOptions.files ??= [];
|
|
188
267
|
karmaOptions.files.push(
|
|
189
268
|
// Serve polyfills first.
|
|
190
|
-
{ pattern: `${outputPath}/polyfills.js`, type: 'module' },
|
|
191
|
-
//
|
|
192
|
-
{ pattern: `${outputPath}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
269
|
+
{ pattern: `${outputPath}/polyfills.js`, type: 'module', watched: false },
|
|
270
|
+
// Serve global setup script.
|
|
271
|
+
{ pattern: `${outputPath}/${mainName}.js`, type: 'module', watched: false },
|
|
272
|
+
// Serve all source maps.
|
|
273
|
+
{ pattern: `${outputPath}/*.map`, included: false, watched: false },
|
|
274
|
+
// These are the test entrypoints.
|
|
275
|
+
{ pattern: `${outputPath}/spec-*.js`, type: 'module', watched: false });
|
|
276
|
+
if (hasChunkOrWorkerFiles(buildOutput.files)) {
|
|
277
|
+
karmaOptions.files.push(
|
|
278
|
+
// Allow loading of chunk-* files but don't include them all on load.
|
|
279
|
+
{
|
|
280
|
+
pattern: `${outputPath}/{chunk,worker}-*.js`,
|
|
281
|
+
type: 'module',
|
|
282
|
+
included: false,
|
|
283
|
+
watched: false,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
196
286
|
if (options.styles?.length) {
|
|
197
287
|
// Serve CSS outputs on page load, these are the global styles.
|
|
198
|
-
karmaOptions.files.push({ pattern: `${outputPath}/*.css`, type: 'css' });
|
|
288
|
+
karmaOptions.files.push({ pattern: `${outputPath}/*.css`, type: 'css', watched: false });
|
|
199
289
|
}
|
|
200
290
|
const parsedKarmaConfig = await karma.config.parseConfig(options.karmaConfig && path.resolve(context.workspaceRoot, options.karmaConfig), transforms.karmaOptions ? transforms.karmaOptions(karmaOptions) : karmaOptions, { promiseConfig: true, throwErrors: true });
|
|
201
291
|
// Remove the webpack plugin/framework:
|
|
202
292
|
// Alternative would be to make the Karma plugin "smart" but that's a tall order
|
|
203
293
|
// with managing unneeded imports etc..
|
|
204
|
-
|
|
205
|
-
|
|
294
|
+
parsedKarmaConfig.plugins ??= [];
|
|
295
|
+
const pluginLengthBefore = parsedKarmaConfig.plugins.length;
|
|
296
|
+
parsedKarmaConfig.plugins = parsedKarmaConfig.plugins.filter((plugin) => {
|
|
206
297
|
if (typeof plugin === 'string') {
|
|
207
298
|
return plugin !== 'framework:@angular-devkit/build-angular';
|
|
208
299
|
}
|
|
209
300
|
return !plugin['framework:@angular-devkit/build-angular'];
|
|
210
301
|
});
|
|
211
|
-
parsedKarmaConfig.frameworks
|
|
212
|
-
|
|
302
|
+
parsedKarmaConfig.frameworks ??= [];
|
|
303
|
+
parsedKarmaConfig.frameworks = parsedKarmaConfig.frameworks.filter((framework) => framework !== '@angular-devkit/build-angular');
|
|
304
|
+
const pluginLengthAfter = parsedKarmaConfig.plugins.length;
|
|
213
305
|
if (pluginLengthBefore !== pluginLengthAfter) {
|
|
214
306
|
context.logger.warn(`Ignoring framework "@angular-devkit/build-angular" from karma config file because it's not compatible with the application builder.`);
|
|
215
307
|
}
|
|
308
|
+
parsedKarmaConfig.plugins.push(AngularAssetsMiddleware.createPlugin(buildOutput));
|
|
309
|
+
parsedKarmaConfig.middleware ??= [];
|
|
310
|
+
parsedKarmaConfig.middleware.push(AngularAssetsMiddleware.NAME);
|
|
216
311
|
// When using code-coverage, auto-add karma-coverage.
|
|
217
312
|
// This was done as part of the karma plugin for webpack.
|
|
218
313
|
if (options.codeCoverage &&
|
|
219
314
|
!parsedKarmaConfig.reporters?.some((r) => r === 'coverage' || r === 'coverage-istanbul')) {
|
|
220
315
|
parsedKarmaConfig.reporters = (parsedKarmaConfig.reporters ?? []).concat(['coverage']);
|
|
221
316
|
}
|
|
222
|
-
return [karma, parsedKarmaConfig, buildOptions];
|
|
317
|
+
return [karma, parsedKarmaConfig, buildOptions, buildIterator];
|
|
318
|
+
}
|
|
319
|
+
function hasChunkOrWorkerFiles(files) {
|
|
320
|
+
return Object.keys(files).some((filename) => {
|
|
321
|
+
return /(?:^|\/)(?:worker|chunk)[^/]+\.js$/.test(filename);
|
|
322
|
+
});
|
|
223
323
|
}
|
|
224
324
|
async function writeTestFiles(files, testDir) {
|
|
225
325
|
const directoryExists = new Set();
|
|
@@ -246,9 +346,17 @@ async function writeTestFiles(files, testDir) {
|
|
|
246
346
|
});
|
|
247
347
|
}
|
|
248
348
|
/** Returns the first item yielded by the given generator and cancels the execution. */
|
|
249
|
-
async function first(generator) {
|
|
349
|
+
async function first(generator, { cancel }) {
|
|
350
|
+
if (!cancel) {
|
|
351
|
+
const iterator = generator[Symbol.asyncIterator]();
|
|
352
|
+
const firstValue = await iterator.next();
|
|
353
|
+
if (firstValue.done) {
|
|
354
|
+
throw new Error('Expected generator to emit at least once.');
|
|
355
|
+
}
|
|
356
|
+
return [firstValue.value, iterator];
|
|
357
|
+
}
|
|
250
358
|
for await (const value of generator) {
|
|
251
|
-
return value;
|
|
359
|
+
return [value, null];
|
|
252
360
|
}
|
|
253
361
|
throw new Error('Expected generator to emit at least once.');
|
|
254
362
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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 { Schema as ProtractorBuilderOptions } from '../protractor/schema';
|
|
9
|
+
declare const _default: import("../../../../architect/src/internal").Builder<ProtractorBuilderOptions & import("../../../../core/src").JsonObject>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
const architect_1 = require("@angular-devkit/architect");
|
|
11
|
+
exports.default = (0, architect_1.createBuilder)((_options, context) => {
|
|
12
|
+
context.logger.error('Protractor has reached end-of-life and is no longer supported. For additional information and alternatives, please see https://blog.angular.dev/protractor-deprecation-update-august-2023-2beac7402ce0.');
|
|
13
|
+
return { success: false };
|
|
14
|
+
});
|
|
@@ -20,14 +20,6 @@ const load_esm_1 = require("../../../utils/load-esm");
|
|
|
20
20
|
* Cached instance of the compiler-cli linker's needsLinking function.
|
|
21
21
|
*/
|
|
22
22
|
let needsLinking;
|
|
23
|
-
/**
|
|
24
|
-
* List of browsers which are affected by a WebKit bug where class field
|
|
25
|
-
* initializers might have incorrect variable scopes.
|
|
26
|
-
*
|
|
27
|
-
* See: https://github.com/angular/angular-cli/issues/24355#issuecomment-1333477033
|
|
28
|
-
* See: https://github.com/WebKit/WebKit/commit/e8788a34b3d5f5b4edd7ff6450b80936bff396f2
|
|
29
|
-
*/
|
|
30
|
-
let safariClassFieldScopeBugBrowsers;
|
|
31
23
|
function createI18nDiagnostics(reporter) {
|
|
32
24
|
const diagnostics = new (class {
|
|
33
25
|
messages = [];
|
|
@@ -109,29 +101,12 @@ function default_1(api, options) {
|
|
|
109
101
|
// However, this doesn't effect libraries and hence we use preset-env to downlevel ES features
|
|
110
102
|
// based on the supported browsers in browserslist.
|
|
111
103
|
if (options.supportedBrowsers) {
|
|
112
|
-
const includePlugins = [];
|
|
113
|
-
if (safariClassFieldScopeBugBrowsers === undefined) {
|
|
114
|
-
const browserslist = require('browserslist');
|
|
115
|
-
safariClassFieldScopeBugBrowsers = new Set(browserslist([
|
|
116
|
-
// Safari <15 is technically not supported via https://angular.dev/reference/versions#browser-support
|
|
117
|
-
// but we apply the workaround if forcibly selected.
|
|
118
|
-
'Safari <=15',
|
|
119
|
-
'iOS <=15',
|
|
120
|
-
]));
|
|
121
|
-
}
|
|
122
|
-
// If a Safari browser affected by the class field scope bug is selected, we
|
|
123
|
-
// downlevel class properties by ensuring the class properties Babel plugin
|
|
124
|
-
// is always included- regardless of the preset-env targets.
|
|
125
|
-
if (options.supportedBrowsers.some((b) => safariClassFieldScopeBugBrowsers.has(b))) {
|
|
126
|
-
includePlugins.push('@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-private-methods');
|
|
127
|
-
}
|
|
128
104
|
presets.push([
|
|
129
105
|
require('@babel/preset-env').default,
|
|
130
106
|
{
|
|
131
107
|
bugfixes: true,
|
|
132
108
|
modules: false,
|
|
133
109
|
targets: options.supportedBrowsers,
|
|
134
|
-
include: includePlugins,
|
|
135
110
|
exclude: ['transform-typeof-symbol'],
|
|
136
111
|
},
|
|
137
112
|
]);
|
|
@@ -231,7 +231,10 @@ async function getCommonConfig(wco) {
|
|
|
231
231
|
const extraMinimizers = [];
|
|
232
232
|
if (scriptsOptimization) {
|
|
233
233
|
extraMinimizers.push(new plugins_1.JavaScriptOptimizerPlugin({
|
|
234
|
-
define:
|
|
234
|
+
define: {
|
|
235
|
+
...(buildOptions.aot ? GLOBAL_DEFS_FOR_TERSER_WITH_AOT : GLOBAL_DEFS_FOR_TERSER),
|
|
236
|
+
'ngServerMode': isPlatformServer,
|
|
237
|
+
},
|
|
235
238
|
sourcemap: scriptsSourceMap,
|
|
236
239
|
supportedBrowsers: buildOptions.supportedBrowsers,
|
|
237
240
|
keepIdentifierNames: !environment_options_1.allowMangle || isPlatformServer,
|
|
@@ -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 = '19.0.0-
|
|
13
|
+
const VERSION = '19.0.0-rc.1';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|
|
@@ -273,11 +273,6 @@ function unwrapTemplateLiteral(path, utils) {
|
|
|
273
273
|
const [expressions] = utils.unwrapExpressionsFromTemplateLiteral(path.get('quasi'));
|
|
274
274
|
return [messageParts, expressions];
|
|
275
275
|
}
|
|
276
|
-
function unwrapLocalizeCall(path, utils) {
|
|
277
|
-
const [messageParts] = utils.unwrapMessagePartsFromLocalizeCall(path);
|
|
278
|
-
const [expressions] = utils.unwrapSubstitutionsFromLocalizeCall(path);
|
|
279
|
-
return [messageParts, expressions];
|
|
280
|
-
}
|
|
281
276
|
async function loadLocaleData(path, optimize) {
|
|
282
277
|
// The path is validated during option processing before the build starts
|
|
283
278
|
const content = await fs.readFile(path, 'utf8');
|
package/src/utils/tailwind.js
CHANGED
|
@@ -22,7 +22,7 @@ async function findTailwindConfigurationFile(workspaceRoot, projectRoot) {
|
|
|
22
22
|
files: new Set(entries),
|
|
23
23
|
})));
|
|
24
24
|
// A configuration file can exist in the project or workspace root
|
|
25
|
-
for
|
|
25
|
+
for (const { root, files } of await Promise.all(dirEntries)) {
|
|
26
26
|
for (const potentialConfig of tailwindConfigFiles) {
|
|
27
27
|
if (files.has(potentialConfig)) {
|
|
28
28
|
return (0, node_path_1.join)(root, potentialConfig);
|