@angular-devkit/build-angular 15.0.1 → 15.1.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 +15 -15
- package/src/builders/browser/index.js +0 -9
- package/src/builders/browser-esbuild/angular-compilation.d.ts +26 -0
- package/src/builders/browser-esbuild/angular-compilation.js +172 -0
- package/src/builders/browser-esbuild/angular-host.d.ts +25 -0
- package/src/builders/browser-esbuild/angular-host.js +61 -0
- package/src/builders/browser-esbuild/compiler-plugin.js +56 -236
- package/src/builders/browser-esbuild/javascript-transformer-worker.d.ts +18 -0
- package/src/builders/browser-esbuild/javascript-transformer-worker.js +70 -0
- package/src/builders/browser-esbuild/javascript-transformer.d.ts +48 -0
- package/src/builders/browser-esbuild/javascript-transformer.js +95 -0
- package/src/builders/server/index.js +44 -10
- package/src/builders/server/schema.d.ts +28 -0
- package/src/builders/server/schema.json +46 -0
- package/src/sass/rebasing-importer.d.ts +12 -6
- package/src/sass/rebasing-importer.js +50 -29
- package/src/utils/normalize-asset-patterns.js +4 -5
|
@@ -37,9 +37,13 @@ const path = __importStar(require("path"));
|
|
|
37
37
|
const rxjs_1 = require("rxjs");
|
|
38
38
|
const operators_1 = require("rxjs/operators");
|
|
39
39
|
const utils_1 = require("../../utils");
|
|
40
|
+
const color_1 = require("../../utils/color");
|
|
41
|
+
const copy_assets_1 = require("../../utils/copy-assets");
|
|
42
|
+
const error_1 = require("../../utils/error");
|
|
40
43
|
const i18n_inlining_1 = require("../../utils/i18n-inlining");
|
|
41
44
|
const output_paths_1 = require("../../utils/output-paths");
|
|
42
45
|
const purge_cache_1 = require("../../utils/purge-cache");
|
|
46
|
+
const spinner_1 = require("../../utils/spinner");
|
|
43
47
|
const version_1 = require("../../utils/version");
|
|
44
48
|
const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
|
|
45
49
|
const configs_1 = require("../../webpack/configs");
|
|
@@ -54,7 +58,7 @@ function execute(options, context, transforms = {}) {
|
|
|
54
58
|
(0, version_1.assertCompatibleAngularVersion)(root);
|
|
55
59
|
const baseOutputPath = path.resolve(root, options.outputPath);
|
|
56
60
|
let outputPaths;
|
|
57
|
-
return (0, rxjs_1.from)(initialize(options, context, transforms.webpackConfiguration)).pipe((0, operators_1.concatMap)(({ config, i18n }) => {
|
|
61
|
+
return (0, rxjs_1.from)(initialize(options, context, transforms.webpackConfiguration)).pipe((0, operators_1.concatMap)(({ config, i18n, projectRoot, projectSourceRoot }) => {
|
|
58
62
|
return (0, build_webpack_1.runWebpack)(config, context, {
|
|
59
63
|
webpackFactory: require('webpack'),
|
|
60
64
|
logging: (stats, config) => {
|
|
@@ -63,19 +67,47 @@ function execute(options, context, transforms = {}) {
|
|
|
63
67
|
}
|
|
64
68
|
},
|
|
65
69
|
}).pipe((0, operators_1.concatMap)(async (output) => {
|
|
70
|
+
var _a;
|
|
66
71
|
const { emittedFiles = [], outputPath, webpackStats } = output;
|
|
67
72
|
if (!webpackStats) {
|
|
68
73
|
throw new Error('Webpack stats build result is required.');
|
|
69
74
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
if (!output.success) {
|
|
76
|
+
return output;
|
|
77
|
+
}
|
|
78
|
+
const spinner = new spinner_1.Spinner();
|
|
79
|
+
spinner.enabled = options.progress !== false;
|
|
80
|
+
outputPaths = (0, output_paths_1.ensureOutputPaths)(baseOutputPath, i18n);
|
|
81
|
+
// Copy assets
|
|
82
|
+
if (!options.watch && ((_a = options.assets) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
83
|
+
spinner.start('Copying assets...');
|
|
84
|
+
try {
|
|
85
|
+
await (0, copy_assets_1.copyAssets)((0, utils_1.normalizeAssetPatterns)(options.assets, context.workspaceRoot, projectRoot, projectSourceRoot), Array.from(outputPaths.values()), context.workspaceRoot);
|
|
86
|
+
spinner.succeed('Copying assets complete.');
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
spinner.fail(color_1.colors.redBright('Copying of assets failed.'));
|
|
90
|
+
(0, error_1.assertIsError)(err);
|
|
91
|
+
return {
|
|
92
|
+
...output,
|
|
93
|
+
success: false,
|
|
94
|
+
error: 'Unable to copy assets: ' + err.message,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (i18n.shouldInline) {
|
|
99
|
+
const success = await (0, i18n_inlining_1.i18nInlineEmittedFiles)(context, emittedFiles, i18n, baseOutputPath, Array.from(outputPaths.values()), [], outputPath, options.i18nMissingTranslation);
|
|
100
|
+
if (!success) {
|
|
101
|
+
return {
|
|
102
|
+
...output,
|
|
103
|
+
success: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
74
106
|
}
|
|
75
107
|
(0, stats_1.webpackStatsLogger)(context.logger, webpackStats, config);
|
|
76
|
-
return
|
|
108
|
+
return output;
|
|
77
109
|
}));
|
|
78
|
-
}), (0, operators_1.
|
|
110
|
+
}), (0, operators_1.concatMap)(async (output) => {
|
|
79
111
|
if (!output.success) {
|
|
80
112
|
return output;
|
|
81
113
|
}
|
|
@@ -102,8 +134,10 @@ async function initialize(options, context, webpackConfigurationTransform) {
|
|
|
102
134
|
await (0, purge_cache_1.purgeStaleBuildCache)(context);
|
|
103
135
|
const browserslist = (await Promise.resolve().then(() => __importStar(require('browserslist')))).default;
|
|
104
136
|
const originalOutputPath = options.outputPath;
|
|
105
|
-
|
|
106
|
-
|
|
137
|
+
// Assets are processed directly by the builder except when watching
|
|
138
|
+
const adjustedOptions = options.watch ? options : { ...options, assets: [] };
|
|
139
|
+
const { config, projectRoot, projectSourceRoot, i18n } = await (0, webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext)({
|
|
140
|
+
...adjustedOptions,
|
|
107
141
|
buildOptimizer: false,
|
|
108
142
|
aot: true,
|
|
109
143
|
platform: 'server',
|
|
@@ -119,7 +153,7 @@ async function initialize(options, context, webpackConfigurationTransform) {
|
|
|
119
153
|
(0, utils_1.deleteOutputDir)(context.workspaceRoot, originalOutputPath);
|
|
120
154
|
}
|
|
121
155
|
const transformedConfig = (_a = (await (webpackConfigurationTransform === null || webpackConfigurationTransform === void 0 ? void 0 : webpackConfigurationTransform(config)))) !== null && _a !== void 0 ? _a : config;
|
|
122
|
-
return { config: transformedConfig, i18n };
|
|
156
|
+
return { config: transformedConfig, i18n, projectRoot, projectSourceRoot };
|
|
123
157
|
}
|
|
124
158
|
/**
|
|
125
159
|
* Add `@angular/platform-server` exports.
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export interface Schema {
|
|
2
|
+
/**
|
|
3
|
+
* List of static application assets.
|
|
4
|
+
*/
|
|
5
|
+
assets?: AssetPattern[];
|
|
2
6
|
/**
|
|
3
7
|
* Delete the output path before building.
|
|
4
8
|
*/
|
|
@@ -110,6 +114,30 @@ export interface Schema {
|
|
|
110
114
|
*/
|
|
111
115
|
watch?: boolean;
|
|
112
116
|
}
|
|
117
|
+
export declare type AssetPattern = AssetPatternClass | string;
|
|
118
|
+
export interface AssetPatternClass {
|
|
119
|
+
/**
|
|
120
|
+
* Allow glob patterns to follow symlink directories. This allows subdirectories of the
|
|
121
|
+
* symlink to be searched.
|
|
122
|
+
*/
|
|
123
|
+
followSymlinks?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* The pattern to match.
|
|
126
|
+
*/
|
|
127
|
+
glob: string;
|
|
128
|
+
/**
|
|
129
|
+
* An array of globs to ignore.
|
|
130
|
+
*/
|
|
131
|
+
ignore?: string[];
|
|
132
|
+
/**
|
|
133
|
+
* The input directory path in which to apply 'glob'. Defaults to the project root.
|
|
134
|
+
*/
|
|
135
|
+
input: string;
|
|
136
|
+
/**
|
|
137
|
+
* Absolute path within the output.
|
|
138
|
+
*/
|
|
139
|
+
output: string;
|
|
140
|
+
}
|
|
113
141
|
export interface FileReplacement {
|
|
114
142
|
replace?: string;
|
|
115
143
|
replaceWith?: string;
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
"title": "Universal Target",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
+
"assets": {
|
|
8
|
+
"type": "array",
|
|
9
|
+
"description": "List of static application assets.",
|
|
10
|
+
"default": [],
|
|
11
|
+
"items": {
|
|
12
|
+
"$ref": "#/definitions/assetPattern"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
7
15
|
"main": {
|
|
8
16
|
"type": "string",
|
|
9
17
|
"description": "The name of the main entry-point file."
|
|
@@ -212,6 +220,44 @@
|
|
|
212
220
|
"additionalProperties": false,
|
|
213
221
|
"required": ["outputPath", "main", "tsConfig"],
|
|
214
222
|
"definitions": {
|
|
223
|
+
"assetPattern": {
|
|
224
|
+
"oneOf": [
|
|
225
|
+
{
|
|
226
|
+
"type": "object",
|
|
227
|
+
"properties": {
|
|
228
|
+
"followSymlinks": {
|
|
229
|
+
"type": "boolean",
|
|
230
|
+
"default": false,
|
|
231
|
+
"description": "Allow glob patterns to follow symlink directories. This allows subdirectories of the symlink to be searched."
|
|
232
|
+
},
|
|
233
|
+
"glob": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"description": "The pattern to match."
|
|
236
|
+
},
|
|
237
|
+
"input": {
|
|
238
|
+
"type": "string",
|
|
239
|
+
"description": "The input directory path in which to apply 'glob'. Defaults to the project root."
|
|
240
|
+
},
|
|
241
|
+
"ignore": {
|
|
242
|
+
"description": "An array of globs to ignore.",
|
|
243
|
+
"type": "array",
|
|
244
|
+
"items": {
|
|
245
|
+
"type": "string"
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
"output": {
|
|
249
|
+
"type": "string",
|
|
250
|
+
"description": "Absolute path within the output."
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"additionalProperties": false,
|
|
254
|
+
"required": ["glob", "input", "output"]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "string"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
},
|
|
215
261
|
"fileReplacement": {
|
|
216
262
|
"oneOf": [
|
|
217
263
|
{
|
|
@@ -6,10 +6,16 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
/// <reference types="node" />
|
|
9
|
-
/// <reference types="node" />
|
|
10
9
|
import { RawSourceMap } from '@ampproject/remapping';
|
|
11
|
-
import { Dirent } from 'node:fs';
|
|
12
10
|
import type { FileImporter, Importer, ImporterResult } from 'sass';
|
|
11
|
+
/**
|
|
12
|
+
* A preprocessed cache entry for the files and directories within a previously searched
|
|
13
|
+
* directory when performing Sass import resolution.
|
|
14
|
+
*/
|
|
15
|
+
export interface DirectoryEntry {
|
|
16
|
+
files: Set<string>;
|
|
17
|
+
directories: Set<string>;
|
|
18
|
+
}
|
|
13
19
|
/**
|
|
14
20
|
* A Sass Importer base class that provides the load logic to rebase all `url()` functions
|
|
15
21
|
* within a stylesheet. The rebasing will ensure that the URLs in the output of the Sass compiler
|
|
@@ -42,7 +48,7 @@ declare abstract class UrlRebasingImporter implements Importer<'sync'> {
|
|
|
42
48
|
*/
|
|
43
49
|
export declare class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
44
50
|
private directoryCache;
|
|
45
|
-
constructor(entryDirectory: string, directoryCache?: Map<string,
|
|
51
|
+
constructor(entryDirectory: string, directoryCache?: Map<string, DirectoryEntry>, rebaseSourceMaps?: Map<string, RawSourceMap>);
|
|
46
52
|
canonicalize(url: string, options: {
|
|
47
53
|
fromImport: boolean;
|
|
48
54
|
}): URL | null;
|
|
@@ -59,7 +65,7 @@ export declare class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
|
59
65
|
* Checks an array of potential stylesheet files to determine if there is a valid
|
|
60
66
|
* stylesheet file. More than one discovered file may indicate an error.
|
|
61
67
|
* @param found An array of discovered stylesheet files.
|
|
62
|
-
* @returns A fully resolved
|
|
68
|
+
* @returns A fully resolved path for a stylesheet file or `null` if not found.
|
|
63
69
|
* @throws If there are ambiguous files discovered.
|
|
64
70
|
*/
|
|
65
71
|
private checkFound;
|
|
@@ -71,7 +77,7 @@ export declare class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
|
71
77
|
*/
|
|
72
78
|
export declare class ModuleUrlRebasingImporter extends RelativeUrlRebasingImporter {
|
|
73
79
|
private finder;
|
|
74
|
-
constructor(entryDirectory: string, directoryCache: Map<string,
|
|
80
|
+
constructor(entryDirectory: string, directoryCache: Map<string, DirectoryEntry>, rebaseSourceMaps: Map<string, RawSourceMap> | undefined, finder: FileImporter<'sync'>['findFileUrl']);
|
|
75
81
|
canonicalize(url: string, options: {
|
|
76
82
|
fromImport: boolean;
|
|
77
83
|
}): URL | null;
|
|
@@ -83,7 +89,7 @@ export declare class ModuleUrlRebasingImporter extends RelativeUrlRebasingImport
|
|
|
83
89
|
*/
|
|
84
90
|
export declare class LoadPathsUrlRebasingImporter extends RelativeUrlRebasingImporter {
|
|
85
91
|
private loadPaths;
|
|
86
|
-
constructor(entryDirectory: string, directoryCache: Map<string,
|
|
92
|
+
constructor(entryDirectory: string, directoryCache: Map<string, DirectoryEntry>, rebaseSourceMaps: Map<string, RawSourceMap> | undefined, loadPaths: Iterable<string>);
|
|
87
93
|
canonicalize(url: string, options: {
|
|
88
94
|
fromImport: boolean;
|
|
89
95
|
}): URL | null;
|
|
@@ -275,17 +275,6 @@ class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
|
275
275
|
const hasStyleExtension = extension === '.scss' || extension === '.sass' || extension === '.css';
|
|
276
276
|
// Remove the style extension if present to allow adding the `.import` suffix
|
|
277
277
|
const filename = (0, node_path_1.basename)(stylesheetPath, hasStyleExtension ? extension : undefined);
|
|
278
|
-
let entries;
|
|
279
|
-
try {
|
|
280
|
-
entries = this.directoryCache.get(directory);
|
|
281
|
-
if (!entries) {
|
|
282
|
-
entries = (0, node_fs_1.readdirSync)(directory, { withFileTypes: true });
|
|
283
|
-
this.directoryCache.set(directory, entries);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
catch {
|
|
287
|
-
return null;
|
|
288
|
-
}
|
|
289
278
|
const importPotentials = new Set();
|
|
290
279
|
const defaultPotentials = new Set();
|
|
291
280
|
if (hasStyleExtension) {
|
|
@@ -312,37 +301,69 @@ class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
|
312
301
|
defaultPotentials.add('_' + filename + '.sass');
|
|
313
302
|
defaultPotentials.add('_' + filename + '.css');
|
|
314
303
|
}
|
|
315
|
-
|
|
316
|
-
|
|
304
|
+
let foundDefaults;
|
|
305
|
+
let foundImports;
|
|
317
306
|
let hasPotentialIndex = false;
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
307
|
+
let cachedEntries = this.directoryCache.get(directory);
|
|
308
|
+
if (cachedEntries) {
|
|
309
|
+
// If there is a preprocessed cache of the directory, perform an intersection of the potentials
|
|
310
|
+
// and the directory files.
|
|
311
|
+
const { files, directories } = cachedEntries;
|
|
312
|
+
foundDefaults = [...defaultPotentials].filter((potential) => files.has(potential));
|
|
313
|
+
foundImports = [...importPotentials].filter((potential) => files.has(potential));
|
|
314
|
+
hasPotentialIndex = checkDirectory && !hasStyleExtension && directories.has(filename);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// If no preprocessed cache exists, get the entries from the file system and, while searching,
|
|
318
|
+
// generate the cache for later requests.
|
|
319
|
+
let entries;
|
|
320
|
+
try {
|
|
321
|
+
entries = (0, node_fs_1.readdirSync)(directory, { withFileTypes: true });
|
|
325
322
|
}
|
|
326
|
-
|
|
327
|
-
|
|
323
|
+
catch {
|
|
324
|
+
return null;
|
|
328
325
|
}
|
|
329
|
-
|
|
330
|
-
|
|
326
|
+
foundDefaults = [];
|
|
327
|
+
foundImports = [];
|
|
328
|
+
cachedEntries = { files: new Set(), directories: new Set() };
|
|
329
|
+
for (const entry of entries) {
|
|
330
|
+
const isDirectory = entry.isDirectory();
|
|
331
|
+
if (isDirectory) {
|
|
332
|
+
cachedEntries.directories.add(entry.name);
|
|
333
|
+
}
|
|
334
|
+
// Record if the name should be checked as a directory with an index file
|
|
335
|
+
if (checkDirectory && !hasStyleExtension && entry.name === filename && isDirectory) {
|
|
336
|
+
hasPotentialIndex = true;
|
|
337
|
+
}
|
|
338
|
+
if (!entry.isFile()) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
cachedEntries.files.add(entry.name);
|
|
342
|
+
if (importPotentials.has(entry.name)) {
|
|
343
|
+
foundImports.push(entry.name);
|
|
344
|
+
}
|
|
345
|
+
if (defaultPotentials.has(entry.name)) {
|
|
346
|
+
foundDefaults.push(entry.name);
|
|
347
|
+
}
|
|
331
348
|
}
|
|
349
|
+
this.directoryCache.set(directory, cachedEntries);
|
|
332
350
|
}
|
|
333
351
|
// `foundImports` will only contain elements if `options.fromImport` is true
|
|
334
352
|
const result = (_a = this.checkFound(foundImports)) !== null && _a !== void 0 ? _a : this.checkFound(foundDefaults);
|
|
335
|
-
if (result
|
|
353
|
+
if (result !== null) {
|
|
354
|
+
return (0, node_url_1.pathToFileURL)((0, node_path_1.join)(directory, result));
|
|
355
|
+
}
|
|
356
|
+
if (hasPotentialIndex) {
|
|
336
357
|
// Check for index files using filename as a directory
|
|
337
358
|
return this.resolveImport(url + '/index', fromImport, false);
|
|
338
359
|
}
|
|
339
|
-
return
|
|
360
|
+
return null;
|
|
340
361
|
}
|
|
341
362
|
/**
|
|
342
363
|
* Checks an array of potential stylesheet files to determine if there is a valid
|
|
343
364
|
* stylesheet file. More than one discovered file may indicate an error.
|
|
344
365
|
* @param found An array of discovered stylesheet files.
|
|
345
|
-
* @returns A fully resolved
|
|
366
|
+
* @returns A fully resolved path for a stylesheet file or `null` if not found.
|
|
346
367
|
* @throws If there are ambiguous files discovered.
|
|
347
368
|
*/
|
|
348
369
|
checkFound(found) {
|
|
@@ -361,9 +382,9 @@ class RelativeUrlRebasingImporter extends UrlRebasingImporter {
|
|
|
361
382
|
}
|
|
362
383
|
// Return the non-CSS file (sass/scss files have priority)
|
|
363
384
|
// https://github.com/sass/dart-sass/blob/44d6bb6ac72fe6b93f5bfec371a1fffb18e6b76d/lib/src/importer/utils.dart#L44-L47
|
|
364
|
-
return
|
|
385
|
+
return foundWithoutCss[0];
|
|
365
386
|
}
|
|
366
|
-
return
|
|
387
|
+
return found[0];
|
|
367
388
|
}
|
|
368
389
|
}
|
|
369
390
|
exports.RelativeUrlRebasingImporter = RelativeUrlRebasingImporter;
|
|
@@ -78,13 +78,12 @@ function normalizeAssetPatterns(assetPatterns, workspaceRoot, projectRoot, proje
|
|
|
78
78
|
}
|
|
79
79
|
// Output directory for both is the relative path from source root to input.
|
|
80
80
|
const output = path.relative(resolvedSourceRoot, path.resolve(workspaceRoot, input));
|
|
81
|
-
|
|
82
|
-
return { glob, input, output };
|
|
81
|
+
assetPattern = { glob, input, output };
|
|
83
82
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return assetPattern;
|
|
83
|
+
if (assetPattern.output.startsWith('..')) {
|
|
84
|
+
throw new Error('An asset cannot be written to a location outside of the output path.');
|
|
87
85
|
}
|
|
86
|
+
return assetPattern;
|
|
88
87
|
});
|
|
89
88
|
}
|
|
90
89
|
exports.normalizeAssetPatterns = normalizeAssetPatterns;
|