@angular-devkit/build-angular 13.1.0-next.0 → 13.1.0-rc.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 +35 -35
- package/src/babel/presets/application.d.ts +5 -2
- package/src/babel/presets/application.js +7 -14
- package/src/babel/webpack-loader.js +23 -14
- package/src/builders/browser/index.js +7 -5
- package/src/builders/dev-server/index.js +31 -2
- package/src/builders/extract-i18n/ivy-extract-loader.js +4 -1
- package/src/utils/build-options.d.ts +1 -0
- package/src/utils/bundle-calculator.d.ts +6 -7
- package/src/utils/bundle-calculator.js +3 -1
- package/src/utils/environment-options.d.ts +0 -1
- package/src/utils/environment-options.js +1 -4
- package/src/utils/i18n-options.d.ts +16 -10
- package/src/utils/i18n-options.js +46 -37
- package/src/utils/index-file/augment-index-html.d.ts +5 -1
- package/src/utils/index-file/augment-index-html.js +38 -5
- package/src/utils/index.d.ts +0 -1
- package/src/utils/index.js +0 -1
- package/src/utils/normalize-builder-schema.js +2 -0
- package/src/utils/read-tsconfig.js +1 -4
- package/src/utils/supported-browsers.d.ts +8 -0
- package/src/utils/supported-browsers.js +26 -0
- package/src/webpack/configs/common.js +27 -23
- package/src/webpack/configs/dev-server.js +78 -25
- package/src/webpack/configs/styles.js +23 -14
- package/src/webpack/plugins/hmr/hmr-accept.js +4 -1
- package/src/webpack/plugins/named-chunks-plugin.d.ts +17 -0
- package/src/webpack/plugins/named-chunks-plugin.js +49 -0
- package/src/webpack/plugins/transfer-size-plugin.d.ts +12 -0
- package/src/webpack/plugins/transfer-size-plugin.js +47 -0
- package/src/webpack/utils/helpers.d.ts +3 -1
- package/src/webpack/utils/helpers.js +18 -3
- package/src/webpack/utils/stats.d.ts +10 -3
- package/src/webpack/utils/stats.js +111 -33
- package/src/utils/build-browser-features.d.ts +0 -16
- package/src/utils/build-browser-features.js +0 -54
|
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.configureI18nBuild = exports.createI18nOptions = void 0;
|
|
13
|
+
exports.loadTranslations = exports.configureI18nBuild = exports.createI18nOptions = void 0;
|
|
14
14
|
const core_1 = require("@angular-devkit/core");
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const module_1 = __importDefault(require("module"));
|
|
@@ -158,42 +158,18 @@ async function configureI18nBuild(context, options) {
|
|
|
158
158
|
if (!desc.files.length) {
|
|
159
159
|
continue;
|
|
160
160
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
if (loadResult.locale !== undefined && loadResult.locale !== locale) {
|
|
175
|
-
context.logger.warn(`WARNING [${file.path}]: File target locale ('${loadResult.locale}') does not match configured locale ('${locale}')`);
|
|
176
|
-
}
|
|
177
|
-
usedFormats.add(loadResult.format);
|
|
178
|
-
if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
|
|
179
|
-
// This limitation is only for legacy message id support (defaults to true as of 9.0)
|
|
180
|
-
throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
|
|
181
|
-
}
|
|
182
|
-
file.format = loadResult.format;
|
|
183
|
-
file.integrity = loadResult.integrity;
|
|
184
|
-
if (desc.translation) {
|
|
185
|
-
// Merge translations
|
|
186
|
-
for (const [id, message] of Object.entries(loadResult.translations)) {
|
|
187
|
-
if (desc.translation[id] !== undefined) {
|
|
188
|
-
context.logger.warn(`WARNING [${file.path}]: Duplicate translations for message '${id}' when merging`);
|
|
189
|
-
}
|
|
190
|
-
desc.translation[id] = message;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
// First or only translation file
|
|
195
|
-
desc.translation = loadResult.translations;
|
|
196
|
-
}
|
|
161
|
+
loader !== null && loader !== void 0 ? loader : (loader = await (0, load_translations_1.createTranslationLoader)());
|
|
162
|
+
loadTranslations(locale, desc, context.workspaceRoot, loader, {
|
|
163
|
+
warn(message) {
|
|
164
|
+
context.logger.warn(message);
|
|
165
|
+
},
|
|
166
|
+
error(message) {
|
|
167
|
+
throw new Error(message);
|
|
168
|
+
},
|
|
169
|
+
}, usedFormats);
|
|
170
|
+
if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
|
|
171
|
+
// This limitation is only for legacy message id support (defaults to true as of 9.0)
|
|
172
|
+
throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
|
|
197
173
|
}
|
|
198
174
|
}
|
|
199
175
|
// If inlining store the output in a temporary location to facilitate post-processing
|
|
@@ -225,3 +201,36 @@ function findLocaleDataPath(locale, resolver) {
|
|
|
225
201
|
return null;
|
|
226
202
|
}
|
|
227
203
|
}
|
|
204
|
+
function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedFormats) {
|
|
205
|
+
for (const file of desc.files) {
|
|
206
|
+
const loadResult = loader(path_1.default.join(workspaceRoot, file.path));
|
|
207
|
+
for (const diagnostics of loadResult.diagnostics.messages) {
|
|
208
|
+
if (diagnostics.type === 'error') {
|
|
209
|
+
logger.error(`Error parsing translation file '${file.path}': ${diagnostics.message}`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
logger.warn(`WARNING [${file.path}]: ${diagnostics.message}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (loadResult.locale !== undefined && loadResult.locale !== locale) {
|
|
216
|
+
logger.warn(`WARNING [${file.path}]: File target locale ('${loadResult.locale}') does not match configured locale ('${locale}')`);
|
|
217
|
+
}
|
|
218
|
+
usedFormats === null || usedFormats === void 0 ? void 0 : usedFormats.add(loadResult.format);
|
|
219
|
+
file.format = loadResult.format;
|
|
220
|
+
file.integrity = loadResult.integrity;
|
|
221
|
+
if (desc.translation) {
|
|
222
|
+
// Merge translations
|
|
223
|
+
for (const [id, message] of Object.entries(loadResult.translations)) {
|
|
224
|
+
if (desc.translation[id] !== undefined) {
|
|
225
|
+
logger.warn(`WARNING [${file.path}]: Duplicate translations for message '${id}' when merging`);
|
|
226
|
+
}
|
|
227
|
+
desc.translation[id] = message;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
// First or only translation file
|
|
232
|
+
desc.translation = loadResult.translations;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exports.loadTranslations = loadTranslations;
|
|
@@ -27,4 +27,8 @@ export interface FileInfo {
|
|
|
27
27
|
name: string;
|
|
28
28
|
extension: string;
|
|
29
29
|
}
|
|
30
|
-
export declare function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise<
|
|
30
|
+
export declare function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise<{
|
|
31
|
+
content: string;
|
|
32
|
+
warnings: string[];
|
|
33
|
+
errors: string[];
|
|
34
|
+
}>;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.augmentIndexHtml = void 0;
|
|
11
11
|
const crypto_1 = require("crypto");
|
|
12
|
+
const load_esm_1 = require("../load-esm");
|
|
12
13
|
const html_rewriting_stream_1 = require("./html-rewriting-stream");
|
|
13
14
|
/*
|
|
14
15
|
* Helper function used by the IndexHtmlWebpackPlugin.
|
|
@@ -18,6 +19,8 @@ const html_rewriting_stream_1 = require("./html-rewriting-stream");
|
|
|
18
19
|
*/
|
|
19
20
|
async function augmentIndexHtml(params) {
|
|
20
21
|
const { loadOutputFile, files, entrypoints, sri, deployUrl = '', lang, baseHref, html } = params;
|
|
22
|
+
const warnings = [];
|
|
23
|
+
const errors = [];
|
|
21
24
|
let { crossOrigin = 'none' } = params;
|
|
22
25
|
if (sri && crossOrigin === 'none') {
|
|
23
26
|
crossOrigin = 'anonymous';
|
|
@@ -72,6 +75,7 @@ async function augmentIndexHtml(params) {
|
|
|
72
75
|
}
|
|
73
76
|
linkTags.push(`<link ${attrs.join(' ')}>`);
|
|
74
77
|
}
|
|
78
|
+
const dir = lang ? await getLanguageDirection(lang, warnings) : undefined;
|
|
75
79
|
const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(html);
|
|
76
80
|
const baseTagExists = html.includes('<base');
|
|
77
81
|
rewriter
|
|
@@ -82,6 +86,9 @@ async function augmentIndexHtml(params) {
|
|
|
82
86
|
if (isString(lang)) {
|
|
83
87
|
updateAttribute(tag, 'lang', lang);
|
|
84
88
|
}
|
|
89
|
+
if (dir) {
|
|
90
|
+
updateAttribute(tag, 'dir', dir);
|
|
91
|
+
}
|
|
85
92
|
break;
|
|
86
93
|
case 'head':
|
|
87
94
|
// Base href should be added before any link, meta tags
|
|
@@ -119,11 +126,14 @@ async function augmentIndexHtml(params) {
|
|
|
119
126
|
rewriter.emitEndTag(tag);
|
|
120
127
|
});
|
|
121
128
|
const content = await transformedContent;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
129
|
+
return {
|
|
130
|
+
content: linkTags.length || scriptTags.length
|
|
131
|
+
? // In case no body/head tags are not present (dotnet partial templates)
|
|
132
|
+
linkTags.join('') + scriptTags.join('') + content
|
|
133
|
+
: content,
|
|
134
|
+
warnings,
|
|
135
|
+
errors,
|
|
136
|
+
};
|
|
127
137
|
}
|
|
128
138
|
exports.augmentIndexHtml = augmentIndexHtml;
|
|
129
139
|
function generateSriAttributes(content) {
|
|
@@ -144,3 +154,26 @@ function updateAttribute(tag, name, value) {
|
|
|
144
154
|
function isString(value) {
|
|
145
155
|
return typeof value === 'string';
|
|
146
156
|
}
|
|
157
|
+
async function getLanguageDirection(locale, warnings) {
|
|
158
|
+
const dir = await getLanguageDirectionFromLocales(locale);
|
|
159
|
+
if (!dir) {
|
|
160
|
+
warnings.push(`Locale data for '${locale}' cannot be found. 'dir' attribute will not be set for this locale.`);
|
|
161
|
+
}
|
|
162
|
+
return dir;
|
|
163
|
+
}
|
|
164
|
+
async function getLanguageDirectionFromLocales(locale) {
|
|
165
|
+
try {
|
|
166
|
+
const localeData = (await (0, load_esm_1.loadEsmModule)(`@angular/common/locales/${locale}`)).default;
|
|
167
|
+
const dir = localeData[localeData.length - 2];
|
|
168
|
+
return isString(dir) ? dir : undefined;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// In some cases certain locales might map to files which are named only with language id.
|
|
172
|
+
// Example: `en-US` -> `en`.
|
|
173
|
+
const [languageId] = locale.split('-', 1);
|
|
174
|
+
if (languageId !== locale) {
|
|
175
|
+
return getLanguageDirectionFromLocales(languageId);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
package/src/utils/index.d.ts
CHANGED
|
@@ -5,7 +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 * from './build-browser-features';
|
|
9
8
|
export * from './default-progress';
|
|
10
9
|
export * from './delete-output-dir';
|
|
11
10
|
export * from './run-module-as-observable-fork';
|
package/src/utils/index.js
CHANGED
|
@@ -17,7 +17,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
17
17
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
__exportStar(require("./build-browser-features"), exports);
|
|
21
20
|
__exportStar(require("./default-progress"), exports);
|
|
22
21
|
__exportStar(require("./delete-output-dir"), exports);
|
|
23
22
|
__exportStar(require("./run-module-as-observable-fork"), exports);
|
|
@@ -14,6 +14,7 @@ const normalize_cache_1 = require("./normalize-cache");
|
|
|
14
14
|
const normalize_file_replacements_1 = require("./normalize-file-replacements");
|
|
15
15
|
const normalize_optimization_1 = require("./normalize-optimization");
|
|
16
16
|
const normalize_source_maps_1 = require("./normalize-source-maps");
|
|
17
|
+
const supported_browsers_1 = require("./supported-browsers");
|
|
17
18
|
function normalizeBrowserSchema(root, projectRoot, sourceRoot, options, metadata) {
|
|
18
19
|
const normalizedSourceMapOptions = (0, normalize_source_maps_1.normalizeSourceMaps)(options.sourceMap || false);
|
|
19
20
|
return {
|
|
@@ -37,6 +38,7 @@ function normalizeBrowserSchema(root, projectRoot, sourceRoot, options, metadata
|
|
|
37
38
|
// A value of 0 is falsy and will disable polling rather then enable
|
|
38
39
|
// 500 ms is a sensible default in this case
|
|
39
40
|
poll: options.poll === 0 ? 500 : options.poll,
|
|
41
|
+
supportedBrowsers: (0, supported_browsers_1.getSupportedBrowsers)((0, core_1.getSystemPath)(projectRoot)),
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
44
|
exports.normalizeBrowserSchema = normalizeBrowserSchema;
|
|
@@ -41,10 +41,7 @@ async function readTsconfig(tsconfigPath, workspaceRoot) {
|
|
|
41
41
|
// Load ESM `@angular/compiler-cli` using the TypeScript dynamic import workaround.
|
|
42
42
|
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
43
43
|
// changed to a direct dynamic import.
|
|
44
|
-
const
|
|
45
|
-
// If it is not ESM then the functions needed will be stored in the `default` property.
|
|
46
|
-
// TODO_ESM: This can be removed once `@angular/compiler-cli` is ESM only.
|
|
47
|
-
const { formatDiagnostics, readConfiguration } = (compilerCliModule.readConfiguration ? compilerCliModule : compilerCliModule.default);
|
|
44
|
+
const { formatDiagnostics, readConfiguration } = await (0, load_esm_1.loadEsmModule)('@angular/compiler-cli');
|
|
48
45
|
const configResult = readConfiguration(tsConfigFullPath);
|
|
49
46
|
if (configResult.errors && configResult.errors.length) {
|
|
50
47
|
throw new Error(formatDiagnostics(configResult.errors));
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export declare function getSupportedBrowsers(projectRoot: string): string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.io/license
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getSupportedBrowsers = void 0;
|
|
14
|
+
const browserslist_1 = __importDefault(require("browserslist"));
|
|
15
|
+
function getSupportedBrowsers(projectRoot) {
|
|
16
|
+
browserslist_1.default.defaults = [
|
|
17
|
+
'last 1 Chrome version',
|
|
18
|
+
'last 1 Firefox version',
|
|
19
|
+
'last 2 Edge major versions',
|
|
20
|
+
'last 2 Safari major versions',
|
|
21
|
+
'last 2 iOS major versions',
|
|
22
|
+
'Firefox ESR',
|
|
23
|
+
];
|
|
24
|
+
return (0, browserslist_1.default)(undefined, { path: projectRoot });
|
|
25
|
+
}
|
|
26
|
+
exports.getSupportedBrowsers = getSupportedBrowsers;
|
|
@@ -36,17 +36,18 @@ const path = __importStar(require("path"));
|
|
|
36
36
|
const typescript_1 = require("typescript");
|
|
37
37
|
const webpack_2 = require("webpack");
|
|
38
38
|
const webpack_subresource_integrity_1 = require("webpack-subresource-integrity");
|
|
39
|
-
const utils_1 = require("../../utils");
|
|
40
39
|
const environment_options_1 = require("../../utils/environment-options");
|
|
41
40
|
const load_esm_1 = require("../../utils/load-esm");
|
|
42
41
|
const plugins_1 = require("../plugins");
|
|
42
|
+
const named_chunks_plugin_1 = require("../plugins/named-chunks-plugin");
|
|
43
43
|
const progress_plugin_1 = require("../plugins/progress-plugin");
|
|
44
|
+
const transfer_size_plugin_1 = require("../plugins/transfer-size-plugin");
|
|
44
45
|
const typescript_2 = require("../plugins/typescript");
|
|
45
46
|
const helpers_1 = require("../utils/helpers");
|
|
46
47
|
// eslint-disable-next-line max-lines-per-function
|
|
47
48
|
async function getCommonConfig(wco) {
|
|
48
49
|
var _a, _b;
|
|
49
|
-
const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath } = wco;
|
|
50
|
+
const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath, scriptTarget, } = wco;
|
|
50
51
|
const { cache, codeCoverage, crossOrigin = 'none', platform = 'browser', aot = true, codeCoverageExclude = [], main, polyfills, sourceMap: { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap, hidden: hiddenSourceMap, }, optimization: { styles: stylesOptimization, scripts: scriptsOptimization }, commonChunk, vendorChunk, subresourceIntegrity, verbose, poll, webWorkerTsConfig, externalDependencies = [], allowedCommonJsDependencies, bundleDependencies, } = buildOptions;
|
|
51
52
|
const isPlatformServer = buildOptions.platform === 'server';
|
|
52
53
|
const extraPlugins = [];
|
|
@@ -55,13 +56,9 @@ async function getCommonConfig(wco) {
|
|
|
55
56
|
// Load ESM `@angular/compiler-cli` using the TypeScript dynamic import workaround.
|
|
56
57
|
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
57
58
|
// changed to a direct dynamic import.
|
|
58
|
-
const
|
|
59
|
-
// If it is not ESM then the values needed will be stored in the `default` property.
|
|
60
|
-
// TODO_ESM: This can be removed once `@angular/compiler-cli` is ESM only.
|
|
61
|
-
const { GLOBAL_DEFS_FOR_TERSER, GLOBAL_DEFS_FOR_TERSER_WITH_AOT, VERSION: NG_VERSION, } = (compilerCliModule.GLOBAL_DEFS_FOR_TERSER ? compilerCliModule : compilerCliModule.default);
|
|
59
|
+
const { GLOBAL_DEFS_FOR_TERSER, GLOBAL_DEFS_FOR_TERSER_WITH_AOT, VERSION: NG_VERSION, } = await (0, load_esm_1.loadEsmModule)('@angular/compiler-cli');
|
|
62
60
|
// determine hashing format
|
|
63
61
|
const hashFormat = (0, helpers_1.getOutputHashFormat)(buildOptions.outputHashing || 'none');
|
|
64
|
-
const buildBrowserFeatures = new utils_1.BuildBrowserFeatures(projectRoot);
|
|
65
62
|
if (buildOptions.progress) {
|
|
66
63
|
extraPlugins.push(new progress_plugin_1.ProgressPlugin(platform));
|
|
67
64
|
}
|
|
@@ -93,11 +90,6 @@ async function getCommonConfig(wco) {
|
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
|
-
if (environment_options_1.profilingEnabled) {
|
|
97
|
-
extraPlugins.push(new webpack_2.debug.ProfilingPlugin({
|
|
98
|
-
outputPath: path.resolve(root, 'chrome-profiler-events.json'),
|
|
99
|
-
}));
|
|
100
|
-
}
|
|
101
93
|
if (allowedCommonJsDependencies) {
|
|
102
94
|
// When this is not defined it means the builder doesn't support showing common js usages.
|
|
103
95
|
// When it does it will be an array.
|
|
@@ -190,8 +182,10 @@ async function getCommonConfig(wco) {
|
|
|
190
182
|
}
|
|
191
183
|
if (main || polyfills) {
|
|
192
184
|
extraRules.push({
|
|
193
|
-
test: /\.[cm]?[tj]sx?$/,
|
|
185
|
+
test: tsConfig.options.allowJs ? /\.[cm]?[tj]sx?$/ : /\.[cm]?tsx?$/,
|
|
194
186
|
loader: webpack_1.AngularWebpackLoaderPath,
|
|
187
|
+
// The below are known paths that are not part of the TypeScript compilation even when allowJs is enabled.
|
|
188
|
+
exclude: [/[/\\](?:css-loader|mini-css-extract-plugin|webpack-dev-server|webpack)[/\\]/],
|
|
195
189
|
});
|
|
196
190
|
extraPlugins.push((0, typescript_2.createIvyPlugin)(wco, aot, tsConfigPath));
|
|
197
191
|
}
|
|
@@ -203,12 +197,15 @@ async function getCommonConfig(wco) {
|
|
|
203
197
|
extraMinimizers.push(new plugins_1.JavaScriptOptimizerPlugin({
|
|
204
198
|
define: buildOptions.aot ? GLOBAL_DEFS_FOR_TERSER_WITH_AOT : GLOBAL_DEFS_FOR_TERSER,
|
|
205
199
|
sourcemap: scriptsSourceMap,
|
|
206
|
-
target:
|
|
200
|
+
target: scriptTarget,
|
|
207
201
|
keepNames: !environment_options_1.allowMangle || isPlatformServer,
|
|
208
202
|
removeLicenses: buildOptions.extractLicenses,
|
|
209
203
|
advanced: buildOptions.buildOptimizer,
|
|
210
204
|
}));
|
|
211
205
|
}
|
|
206
|
+
if (platform === 'browser' && (scriptsOptimization || stylesOptimization.minify)) {
|
|
207
|
+
extraMinimizers.push(new transfer_size_plugin_1.TransferSizePlugin());
|
|
208
|
+
}
|
|
212
209
|
const externals = [...externalDependencies];
|
|
213
210
|
if (isPlatformServer && !bundleDependencies) {
|
|
214
211
|
externals.push(({ context, request }, callback) => (0, helpers_1.externalizePackages)(context !== null && context !== void 0 ? context : wco.projectRoot, request, callback));
|
|
@@ -225,7 +222,7 @@ async function getCommonConfig(wco) {
|
|
|
225
222
|
devtool: false,
|
|
226
223
|
target: [
|
|
227
224
|
isPlatformServer ? 'node' : 'web',
|
|
228
|
-
|
|
225
|
+
scriptTarget === typescript_1.ScriptTarget.ES5 ? 'es5' : 'es2015',
|
|
229
226
|
],
|
|
230
227
|
profile: buildOptions.statsJson,
|
|
231
228
|
resolve: {
|
|
@@ -233,10 +230,7 @@ async function getCommonConfig(wco) {
|
|
|
233
230
|
extensions: ['.ts', '.tsx', '.mjs', '.js'],
|
|
234
231
|
symlinks: !buildOptions.preserveSymlinks,
|
|
235
232
|
modules: [tsConfig.options.baseUrl || projectRoot, 'node_modules'],
|
|
236
|
-
|
|
237
|
-
? ['es2015', 'module', 'main']
|
|
238
|
-
: ['es2020', 'es2015', 'browser', 'module', 'main'],
|
|
239
|
-
conditionNames: isPlatformServer ? ['es2015', '...'] : ['es2020', 'es2015', '...'],
|
|
233
|
+
...(0, helpers_1.getMainFieldsAndConditionNames)(scriptTarget, isPlatformServer),
|
|
240
234
|
},
|
|
241
235
|
resolveLoader: {
|
|
242
236
|
symlinks: !buildOptions.preserveSymlinks,
|
|
@@ -260,7 +254,7 @@ async function getCommonConfig(wco) {
|
|
|
260
254
|
watch: buildOptions.watch,
|
|
261
255
|
watchOptions: {
|
|
262
256
|
poll,
|
|
263
|
-
ignored: poll === undefined ? undefined : 'node_modules/**',
|
|
257
|
+
ignored: poll === undefined ? undefined : '**/node_modules/**',
|
|
264
258
|
},
|
|
265
259
|
performance: {
|
|
266
260
|
hints: false,
|
|
@@ -270,6 +264,9 @@ async function getCommonConfig(wco) {
|
|
|
270
264
|
/Failed to parse source map from/,
|
|
271
265
|
// https://github.com/webpack-contrib/postcss-loader/blob/bd261875fdf9c596af4ffb3a1a73fe3c549befda/src/index.js#L153-L158
|
|
272
266
|
/Add postcss as project dependency/,
|
|
267
|
+
// esbuild will issue a warning, while still hoists the @charset at the very top.
|
|
268
|
+
// This is caused by a bug in css-loader https://github.com/webpack-contrib/css-loader/issues/1212
|
|
269
|
+
/"@charset" must be the first rule in the file/,
|
|
273
270
|
],
|
|
274
271
|
module: {
|
|
275
272
|
// Show an error for missing exports instead of a warning.
|
|
@@ -283,6 +280,12 @@ async function getCommonConfig(wco) {
|
|
|
283
280
|
}
|
|
284
281
|
: undefined,
|
|
285
282
|
rules: [
|
|
283
|
+
{
|
|
284
|
+
test: /\.?(svg|html)$/,
|
|
285
|
+
// Only process HTML and SVG which are known Angular component resources.
|
|
286
|
+
resourceQuery: /\?ngResource/,
|
|
287
|
+
type: 'asset/source',
|
|
288
|
+
},
|
|
286
289
|
{
|
|
287
290
|
// Mark files inside `rxjs/add` as containing side effects.
|
|
288
291
|
// If this is fixed upstream and the fixed version becomes the minimum
|
|
@@ -300,7 +303,7 @@ async function getCommonConfig(wco) {
|
|
|
300
303
|
loader: require.resolve('../../babel/webpack-loader'),
|
|
301
304
|
options: {
|
|
302
305
|
cacheDirectory: (cache.enabled && path.join(cache.path, 'babel-webpack')) || false,
|
|
303
|
-
scriptTarget
|
|
306
|
+
scriptTarget,
|
|
304
307
|
aot: buildOptions.aot,
|
|
305
308
|
optimize: buildOptions.buildOptimizer,
|
|
306
309
|
instrumentCode: codeCoverage
|
|
@@ -317,6 +320,7 @@ async function getCommonConfig(wco) {
|
|
|
317
320
|
],
|
|
318
321
|
},
|
|
319
322
|
experiments: {
|
|
323
|
+
backCompat: false,
|
|
320
324
|
syncWebAssembly: true,
|
|
321
325
|
asyncWebAssembly: true,
|
|
322
326
|
},
|
|
@@ -324,7 +328,7 @@ async function getCommonConfig(wco) {
|
|
|
324
328
|
level: verbose ? 'verbose' : 'error',
|
|
325
329
|
},
|
|
326
330
|
stats: (0, helpers_1.getStatsOptions)(verbose),
|
|
327
|
-
cache: (0, helpers_1.getCacheSettings)(wco,
|
|
331
|
+
cache: (0, helpers_1.getCacheSettings)(wco, NG_VERSION.full),
|
|
328
332
|
optimization: {
|
|
329
333
|
minimizer: extraMinimizers,
|
|
330
334
|
moduleIds: 'deterministic',
|
|
@@ -356,7 +360,7 @@ async function getCommonConfig(wco) {
|
|
|
356
360
|
},
|
|
357
361
|
},
|
|
358
362
|
},
|
|
359
|
-
plugins: [new plugins_1.DedupeModuleResolvePlugin({ verbose }), ...extraPlugins],
|
|
363
|
+
plugins: [new named_chunks_plugin_1.NamedChunksPlugin(), new plugins_1.DedupeModuleResolvePlugin({ verbose }), ...extraPlugins],
|
|
360
364
|
node: false,
|
|
361
365
|
};
|
|
362
366
|
}
|
|
@@ -30,7 +30,7 @@ exports.buildServePath = exports.getDevServerConfig = void 0;
|
|
|
30
30
|
const core_1 = require("@angular-devkit/core");
|
|
31
31
|
const fs_1 = require("fs");
|
|
32
32
|
const path_1 = require("path");
|
|
33
|
-
const
|
|
33
|
+
const url_1 = require("url");
|
|
34
34
|
const load_esm_1 = require("../../utils/load-esm");
|
|
35
35
|
const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
|
|
36
36
|
const hmr_loader_1 = require("../plugins/hmr/hmr-loader");
|
|
@@ -78,7 +78,7 @@ async function getDevServerConfig(wco) {
|
|
|
78
78
|
rewrites: [
|
|
79
79
|
{
|
|
80
80
|
from: new RegExp(`^(?!${servePath})/.*`),
|
|
81
|
-
to: (context) =>
|
|
81
|
+
to: (context) => context.parsedUrl.href,
|
|
82
82
|
},
|
|
83
83
|
],
|
|
84
84
|
},
|
|
@@ -89,7 +89,7 @@ async function getDevServerConfig(wco) {
|
|
|
89
89
|
},
|
|
90
90
|
compress: false,
|
|
91
91
|
static: false,
|
|
92
|
-
|
|
92
|
+
server: getServerConfig(root, wco.buildOptions),
|
|
93
93
|
allowedHosts: getAllowedHostsConfig(wco.buildOptions),
|
|
94
94
|
devMiddleware: {
|
|
95
95
|
publicPath: servePath,
|
|
@@ -139,15 +139,20 @@ exports.buildServePath = buildServePath;
|
|
|
139
139
|
* Private method to enhance a webpack config with SSL configuration.
|
|
140
140
|
* @private
|
|
141
141
|
*/
|
|
142
|
-
function
|
|
142
|
+
function getServerConfig(root, options) {
|
|
143
143
|
const { ssl, sslCert, sslKey } = options;
|
|
144
|
-
if (ssl
|
|
145
|
-
return
|
|
146
|
-
key: (0, path_1.resolve)(root, sslKey),
|
|
147
|
-
cert: (0, path_1.resolve)(root, sslCert),
|
|
148
|
-
};
|
|
144
|
+
if (!ssl) {
|
|
145
|
+
return 'http';
|
|
149
146
|
}
|
|
150
|
-
return
|
|
147
|
+
return {
|
|
148
|
+
type: 'https',
|
|
149
|
+
options: sslCert && sslKey
|
|
150
|
+
? {
|
|
151
|
+
key: (0, path_1.resolve)(root, sslKey),
|
|
152
|
+
cert: (0, path_1.resolve)(root, sslCert),
|
|
153
|
+
}
|
|
154
|
+
: undefined,
|
|
155
|
+
};
|
|
151
156
|
}
|
|
152
157
|
/**
|
|
153
158
|
* Private method to enhance a webpack config with Proxy configuration.
|
|
@@ -158,21 +163,71 @@ async function addProxyConfig(root, proxyConfig) {
|
|
|
158
163
|
return undefined;
|
|
159
164
|
}
|
|
160
165
|
const proxyPath = (0, path_1.resolve)(root, proxyConfig);
|
|
161
|
-
if ((0, fs_1.existsSync)(proxyPath)) {
|
|
162
|
-
|
|
163
|
-
|
|
166
|
+
if (!(0, fs_1.existsSync)(proxyPath)) {
|
|
167
|
+
throw new Error(`Proxy configuration file ${proxyPath} does not exist.`);
|
|
168
|
+
}
|
|
169
|
+
switch ((0, path_1.extname)(proxyPath)) {
|
|
170
|
+
case '.json': {
|
|
171
|
+
const content = await fs_1.promises.readFile(proxyPath, 'utf-8');
|
|
172
|
+
const { parse, printParseErrorCode } = await Promise.resolve().then(() => __importStar(require('jsonc-parser')));
|
|
173
|
+
const parseErrors = [];
|
|
174
|
+
const proxyConfiguration = parse(content, parseErrors, { allowTrailingComma: true });
|
|
175
|
+
if (parseErrors.length > 0) {
|
|
176
|
+
let errorMessage = `Proxy configuration file ${proxyPath} contains parse errors:`;
|
|
177
|
+
for (const parseError of parseErrors) {
|
|
178
|
+
const { line, column } = getJsonErrorLineColumn(parseError.offset, content);
|
|
179
|
+
errorMessage += `\n[${line}, ${column}] ${printParseErrorCode(parseError.error)}`;
|
|
180
|
+
}
|
|
181
|
+
throw new Error(errorMessage);
|
|
182
|
+
}
|
|
183
|
+
return proxyConfiguration;
|
|
164
184
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
case '.mjs':
|
|
186
|
+
// Load the ESM configuration file using the TypeScript dynamic import workaround.
|
|
187
|
+
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
188
|
+
// changed to a direct dynamic import.
|
|
189
|
+
return (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
|
|
190
|
+
case '.cjs':
|
|
191
|
+
return require(proxyPath);
|
|
192
|
+
default:
|
|
193
|
+
// The file could be either CommonJS or ESM.
|
|
194
|
+
// CommonJS is tried first then ESM if loading fails.
|
|
195
|
+
try {
|
|
196
|
+
return require(proxyPath);
|
|
171
197
|
}
|
|
172
|
-
|
|
198
|
+
catch (e) {
|
|
199
|
+
if (e.code === 'ERR_REQUIRE_ESM') {
|
|
200
|
+
// Load the ESM configuration file using the TypeScript dynamic import workaround.
|
|
201
|
+
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
202
|
+
// changed to a direct dynamic import.
|
|
203
|
+
return (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
|
|
204
|
+
}
|
|
205
|
+
throw e;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Calculates the line and column for an error offset in the content of a JSON file.
|
|
211
|
+
* @param location The offset error location from the beginning of the content.
|
|
212
|
+
* @param content The full content of the file containing the error.
|
|
213
|
+
* @returns An object containing the line and column
|
|
214
|
+
*/
|
|
215
|
+
function getJsonErrorLineColumn(offset, content) {
|
|
216
|
+
if (offset === 0) {
|
|
217
|
+
return { line: 1, column: 1 };
|
|
218
|
+
}
|
|
219
|
+
let line = 0;
|
|
220
|
+
let position = 0;
|
|
221
|
+
// eslint-disable-next-line no-constant-condition
|
|
222
|
+
while (true) {
|
|
223
|
+
++line;
|
|
224
|
+
const nextNewline = content.indexOf('\n', position);
|
|
225
|
+
if (nextNewline === -1 || nextNewline > offset) {
|
|
226
|
+
break;
|
|
173
227
|
}
|
|
228
|
+
position = nextNewline + 1;
|
|
174
229
|
}
|
|
175
|
-
|
|
230
|
+
return { line, column: offset - position + 1 };
|
|
176
231
|
}
|
|
177
232
|
/**
|
|
178
233
|
* Find the default server path. We don't want to expose baseHref and deployUrl as arguments, only
|
|
@@ -219,10 +274,8 @@ function getAllowedHostsConfig(options) {
|
|
|
219
274
|
function getPublicHostOptions(options, webSocketPath) {
|
|
220
275
|
let publicHost = options.publicHost;
|
|
221
276
|
if (publicHost) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
publicHost = url.parse(publicHost).host;
|
|
277
|
+
const hostWithProtocol = !/^\w+:\/\//.test(publicHost) ? `https://${publicHost}` : publicHost;
|
|
278
|
+
publicHost = new url_1.URL(hostWithProtocol).host;
|
|
226
279
|
}
|
|
227
280
|
return `auto://${publicHost || '0.0.0.0:0'}${webSocketPath}`;
|
|
228
281
|
}
|