@angular-devkit/build-angular 13.1.0-next.1 → 13.1.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 +29 -28
- package/src/babel/presets/application.d.ts +4 -2
- package/src/babel/presets/application.js +2 -12
- package/src/babel/webpack-loader.js +21 -13
- package/src/builders/browser/index.js +3 -2
- package/src/builders/dev-server/index.js +31 -2
- package/src/builders/extract-i18n/ivy-extract-loader.js +4 -1
- 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/read-tsconfig.js +1 -4
- package/src/webpack/configs/common.js +23 -20
- package/src/webpack/configs/dev-server.js +78 -25
- package/src/webpack/configs/styles.js +21 -10
- 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 +2 -0
- package/src/webpack/utils/helpers.js +17 -1
- package/src/webpack/utils/stats.d.ts +10 -3
- package/src/webpack/utils/stats.js +111 -33
|
@@ -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
|
+
}
|
|
@@ -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));
|
|
@@ -39,13 +39,15 @@ const webpack_subresource_integrity_1 = require("webpack-subresource-integrity")
|
|
|
39
39
|
const environment_options_1 = require("../../utils/environment-options");
|
|
40
40
|
const load_esm_1 = require("../../utils/load-esm");
|
|
41
41
|
const plugins_1 = require("../plugins");
|
|
42
|
+
const named_chunks_plugin_1 = require("../plugins/named-chunks-plugin");
|
|
42
43
|
const progress_plugin_1 = require("../plugins/progress-plugin");
|
|
44
|
+
const transfer_size_plugin_1 = require("../plugins/transfer-size-plugin");
|
|
43
45
|
const typescript_2 = require("../plugins/typescript");
|
|
44
46
|
const helpers_1 = require("../utils/helpers");
|
|
45
47
|
// eslint-disable-next-line max-lines-per-function
|
|
46
48
|
async function getCommonConfig(wco) {
|
|
47
49
|
var _a, _b;
|
|
48
|
-
const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath } = wco;
|
|
50
|
+
const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath, scriptTarget, } = wco;
|
|
49
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;
|
|
50
52
|
const isPlatformServer = buildOptions.platform === 'server';
|
|
51
53
|
const extraPlugins = [];
|
|
@@ -54,10 +56,7 @@ async function getCommonConfig(wco) {
|
|
|
54
56
|
// Load ESM `@angular/compiler-cli` using the TypeScript dynamic import workaround.
|
|
55
57
|
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
56
58
|
// changed to a direct dynamic import.
|
|
57
|
-
const
|
|
58
|
-
// If it is not ESM then the values needed will be stored in the `default` property.
|
|
59
|
-
// TODO_ESM: This can be removed once `@angular/compiler-cli` is ESM only.
|
|
60
|
-
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');
|
|
61
60
|
// determine hashing format
|
|
62
61
|
const hashFormat = (0, helpers_1.getOutputHashFormat)(buildOptions.outputHashing || 'none');
|
|
63
62
|
if (buildOptions.progress) {
|
|
@@ -91,11 +90,6 @@ async function getCommonConfig(wco) {
|
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
|
-
if (environment_options_1.profilingEnabled) {
|
|
95
|
-
extraPlugins.push(new webpack_2.debug.ProfilingPlugin({
|
|
96
|
-
outputPath: path.resolve(root, 'chrome-profiler-events.json'),
|
|
97
|
-
}));
|
|
98
|
-
}
|
|
99
93
|
if (allowedCommonJsDependencies) {
|
|
100
94
|
// When this is not defined it means the builder doesn't support showing common js usages.
|
|
101
95
|
// When it does it will be an array.
|
|
@@ -188,8 +182,10 @@ async function getCommonConfig(wco) {
|
|
|
188
182
|
}
|
|
189
183
|
if (main || polyfills) {
|
|
190
184
|
extraRules.push({
|
|
191
|
-
test: /\.[cm]?[tj]sx?$/,
|
|
185
|
+
test: tsConfig.options.allowJs ? /\.[cm]?[tj]sx?$/ : /\.[cm]?tsx?$/,
|
|
192
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)[/\\]/],
|
|
193
189
|
});
|
|
194
190
|
extraPlugins.push((0, typescript_2.createIvyPlugin)(wco, aot, tsConfigPath));
|
|
195
191
|
}
|
|
@@ -201,12 +197,15 @@ async function getCommonConfig(wco) {
|
|
|
201
197
|
extraMinimizers.push(new plugins_1.JavaScriptOptimizerPlugin({
|
|
202
198
|
define: buildOptions.aot ? GLOBAL_DEFS_FOR_TERSER_WITH_AOT : GLOBAL_DEFS_FOR_TERSER,
|
|
203
199
|
sourcemap: scriptsSourceMap,
|
|
204
|
-
target:
|
|
200
|
+
target: scriptTarget,
|
|
205
201
|
keepNames: !environment_options_1.allowMangle || isPlatformServer,
|
|
206
202
|
removeLicenses: buildOptions.extractLicenses,
|
|
207
203
|
advanced: buildOptions.buildOptimizer,
|
|
208
204
|
}));
|
|
209
205
|
}
|
|
206
|
+
if (platform === 'browser' && (scriptsOptimization || stylesOptimization.minify)) {
|
|
207
|
+
extraMinimizers.push(new transfer_size_plugin_1.TransferSizePlugin());
|
|
208
|
+
}
|
|
210
209
|
const externals = [...externalDependencies];
|
|
211
210
|
if (isPlatformServer && !bundleDependencies) {
|
|
212
211
|
externals.push(({ context, request }, callback) => (0, helpers_1.externalizePackages)(context !== null && context !== void 0 ? context : wco.projectRoot, request, callback));
|
|
@@ -223,7 +222,7 @@ async function getCommonConfig(wco) {
|
|
|
223
222
|
devtool: false,
|
|
224
223
|
target: [
|
|
225
224
|
isPlatformServer ? 'node' : 'web',
|
|
226
|
-
|
|
225
|
+
scriptTarget === typescript_1.ScriptTarget.ES5 ? 'es5' : 'es2015',
|
|
227
226
|
],
|
|
228
227
|
profile: buildOptions.statsJson,
|
|
229
228
|
resolve: {
|
|
@@ -231,10 +230,7 @@ async function getCommonConfig(wco) {
|
|
|
231
230
|
extensions: ['.ts', '.tsx', '.mjs', '.js'],
|
|
232
231
|
symlinks: !buildOptions.preserveSymlinks,
|
|
233
232
|
modules: [tsConfig.options.baseUrl || projectRoot, 'node_modules'],
|
|
234
|
-
|
|
235
|
-
? ['es2015', 'module', 'main']
|
|
236
|
-
: ['es2020', 'es2015', 'browser', 'module', 'main'],
|
|
237
|
-
conditionNames: isPlatformServer ? ['es2015', '...'] : ['es2020', 'es2015', '...'],
|
|
233
|
+
...(0, helpers_1.getMainFieldsAndConditionNames)(scriptTarget, isPlatformServer),
|
|
238
234
|
},
|
|
239
235
|
resolveLoader: {
|
|
240
236
|
symlinks: !buildOptions.preserveSymlinks,
|
|
@@ -258,7 +254,7 @@ async function getCommonConfig(wco) {
|
|
|
258
254
|
watch: buildOptions.watch,
|
|
259
255
|
watchOptions: {
|
|
260
256
|
poll,
|
|
261
|
-
ignored: poll === undefined ? undefined : 'node_modules/**',
|
|
257
|
+
ignored: poll === undefined ? undefined : '**/node_modules/**',
|
|
262
258
|
},
|
|
263
259
|
performance: {
|
|
264
260
|
hints: false,
|
|
@@ -284,6 +280,12 @@ async function getCommonConfig(wco) {
|
|
|
284
280
|
}
|
|
285
281
|
: undefined,
|
|
286
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
|
+
},
|
|
287
289
|
{
|
|
288
290
|
// Mark files inside `rxjs/add` as containing side effects.
|
|
289
291
|
// If this is fixed upstream and the fixed version becomes the minimum
|
|
@@ -301,7 +303,7 @@ async function getCommonConfig(wco) {
|
|
|
301
303
|
loader: require.resolve('../../babel/webpack-loader'),
|
|
302
304
|
options: {
|
|
303
305
|
cacheDirectory: (cache.enabled && path.join(cache.path, 'babel-webpack')) || false,
|
|
304
|
-
scriptTarget
|
|
306
|
+
scriptTarget,
|
|
305
307
|
aot: buildOptions.aot,
|
|
306
308
|
optimize: buildOptions.buildOptimizer,
|
|
307
309
|
instrumentCode: codeCoverage
|
|
@@ -318,6 +320,7 @@ async function getCommonConfig(wco) {
|
|
|
318
320
|
],
|
|
319
321
|
},
|
|
320
322
|
experiments: {
|
|
323
|
+
backCompat: false,
|
|
321
324
|
syncWebAssembly: true,
|
|
322
325
|
asyncWebAssembly: true,
|
|
323
326
|
},
|
|
@@ -357,7 +360,7 @@ async function getCommonConfig(wco) {
|
|
|
357
360
|
},
|
|
358
361
|
},
|
|
359
362
|
},
|
|
360
|
-
plugins: [new plugins_1.DedupeModuleResolvePlugin({ verbose }), ...extraPlugins],
|
|
363
|
+
plugins: [new named_chunks_plugin_1.NamedChunksPlugin(), new plugins_1.DedupeModuleResolvePlugin({ verbose }), ...extraPlugins],
|
|
361
364
|
node: false,
|
|
362
365
|
};
|
|
363
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
|
}
|
|
@@ -91,14 +91,16 @@ function getStylesConfig(wco) {
|
|
|
91
91
|
wco.logger.warn('Stylus usage is deprecated and will be removed in a future major version. ' +
|
|
92
92
|
'To opt-out of the deprecated behaviour, please migrate to another stylesheet language.');
|
|
93
93
|
}
|
|
94
|
-
const sassImplementation =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
compiler
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
const sassImplementation = getSassImplementation();
|
|
95
|
+
if (sassImplementation instanceof sass_service_1.SassWorkerImplementation) {
|
|
96
|
+
extraPlugins.push({
|
|
97
|
+
apply(compiler) {
|
|
98
|
+
compiler.hooks.shutdown.tap('sass-worker', () => {
|
|
99
|
+
sassImplementation === null || sassImplementation === void 0 ? void 0 : sassImplementation.close();
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
102
104
|
const assetNameTemplate = (0, helpers_1.assetNameTemplateFactory)(hashFormat);
|
|
103
105
|
const extraPostcssPlugins = [];
|
|
104
106
|
// Attempt to setup Tailwind CSS
|
|
@@ -340,14 +342,14 @@ function getStylesConfig(wco) {
|
|
|
340
342
|
oneOf: [
|
|
341
343
|
// Component styles are all styles except defined global styles
|
|
342
344
|
{
|
|
343
|
-
exclude: globalStylePaths,
|
|
344
345
|
use: componentStyleLoaders,
|
|
346
|
+
resourceQuery: /\?ngResource/,
|
|
345
347
|
type: 'asset/source',
|
|
346
348
|
},
|
|
347
349
|
// Global styles are only defined global styles
|
|
348
350
|
{
|
|
349
|
-
include: globalStylePaths,
|
|
350
351
|
use: globalStyleLoaders,
|
|
352
|
+
resourceQuery: { not: [/\?ngResource/] },
|
|
351
353
|
},
|
|
352
354
|
],
|
|
353
355
|
},
|
|
@@ -368,3 +370,12 @@ function getStylesConfig(wco) {
|
|
|
368
370
|
};
|
|
369
371
|
}
|
|
370
372
|
exports.getStylesConfig = getStylesConfig;
|
|
373
|
+
function getSassImplementation() {
|
|
374
|
+
const { webcontainer } = process.versions;
|
|
375
|
+
// When `webcontainer` is a truthy it means that we are running in a StackBlitz webcontainer.
|
|
376
|
+
// `SassWorkerImplementation` uses `receiveMessageOnPort` Node.js `worker_thread` API to ensure sync behavior which is ~2x faster.
|
|
377
|
+
// However, it is non trivial to support this in a webcontainer and while slower we choose to use `dart-sass`
|
|
378
|
+
// which in Webpack uses the slower async path.
|
|
379
|
+
// We should periodically check with StackBlitz folks (Mark Whitfeld / Dominic Elm) to determine if this workaround is still needed.
|
|
380
|
+
return webcontainer ? require('sass') : new sass_service_1.SassWorkerImplementation();
|
|
381
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
import { Compiler } from 'webpack';
|
|
9
|
+
/**
|
|
10
|
+
* Webpack will not populate the chunk `name` property unless `webpackChunkName` magic comment is used.
|
|
11
|
+
* This however will also effect the filename which is not desired when using `deterministic` chunkIds.
|
|
12
|
+
* This plugin will populate the chunk `name` which is mainly used so that users can set bundle budgets on lazy chunks.
|
|
13
|
+
*/
|
|
14
|
+
export declare class NamedChunksPlugin {
|
|
15
|
+
apply(compiler: Compiler): void;
|
|
16
|
+
private generateName;
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.NamedChunksPlugin = void 0;
|
|
11
|
+
const webpack_1 = require("webpack");
|
|
12
|
+
// `ImportDependency` is not part of Webpack's depenencies typings.
|
|
13
|
+
const ImportDependency = require('webpack/lib/dependencies/ImportDependency');
|
|
14
|
+
const PLUGIN_NAME = 'named-chunks-plugin';
|
|
15
|
+
/**
|
|
16
|
+
* Webpack will not populate the chunk `name` property unless `webpackChunkName` magic comment is used.
|
|
17
|
+
* This however will also effect the filename which is not desired when using `deterministic` chunkIds.
|
|
18
|
+
* This plugin will populate the chunk `name` which is mainly used so that users can set bundle budgets on lazy chunks.
|
|
19
|
+
*/
|
|
20
|
+
class NamedChunksPlugin {
|
|
21
|
+
apply(compiler) {
|
|
22
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
23
|
+
compilation.hooks.chunkAsset.tap(PLUGIN_NAME, (chunk) => {
|
|
24
|
+
if (chunk.name) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const name = this.generateName(chunk);
|
|
28
|
+
if (name) {
|
|
29
|
+
chunk.name = name;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
generateName(chunk) {
|
|
35
|
+
for (const group of chunk.groupsIterable) {
|
|
36
|
+
const [block] = group.getBlocks();
|
|
37
|
+
if (!(block instanceof webpack_1.AsyncDependenciesBlock)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
for (const dependency of block.dependencies) {
|
|
41
|
+
if (dependency instanceof ImportDependency) {
|
|
42
|
+
return webpack_1.Template.toPath(dependency.request);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.NamedChunksPlugin = NamedChunksPlugin;
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
import { Compiler } from 'webpack';
|
|
9
|
+
export declare class TransferSizePlugin {
|
|
10
|
+
constructor();
|
|
11
|
+
apply(compiler: Compiler): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.TransferSizePlugin = void 0;
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const zlib_1 = require("zlib");
|
|
13
|
+
const brotliCompressAsync = (0, util_1.promisify)(zlib_1.brotliCompress);
|
|
14
|
+
const PLUGIN_NAME = 'angular-transfer-size-estimator';
|
|
15
|
+
class TransferSizePlugin {
|
|
16
|
+
constructor() { }
|
|
17
|
+
apply(compiler) {
|
|
18
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
19
|
+
compilation.hooks.processAssets.tapPromise({
|
|
20
|
+
name: PLUGIN_NAME,
|
|
21
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
|
|
22
|
+
}, async (compilationAssets) => {
|
|
23
|
+
const actions = [];
|
|
24
|
+
for (const assetName of Object.keys(compilationAssets)) {
|
|
25
|
+
if (!assetName.endsWith('.js') && !assetName.endsWith('.css')) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const scriptAsset = compilation.getAsset(assetName);
|
|
29
|
+
if (!scriptAsset || scriptAsset.source.size() <= 0) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
actions.push(brotliCompressAsync(scriptAsset.source.source())
|
|
33
|
+
.then((result) => {
|
|
34
|
+
compilation.updateAsset(assetName, (s) => s, {
|
|
35
|
+
estimatedTransferSize: result.length,
|
|
36
|
+
});
|
|
37
|
+
})
|
|
38
|
+
.catch((error) => {
|
|
39
|
+
compilation.warnings.push(new compilation.compiler.webpack.WebpackError(`Unable to calculate estimated transfer size for '${assetName}'. Reason: ${error.message}`));
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
await Promise.all(actions);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.TransferSizePlugin = TransferSizePlugin;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import type { ObjectPattern } from 'copy-webpack-plugin';
|
|
9
|
+
import { ScriptTarget } from 'typescript';
|
|
9
10
|
import type { Configuration, WebpackOptionsNormalized } from 'webpack';
|
|
10
11
|
import { AssetPatternClass, ExtraEntryPoint, ExtraEntryPointClass } from '../../builders/browser/schema';
|
|
11
12
|
import { WebpackConfigOptions } from '../../utils/build-options';
|
|
@@ -30,4 +31,5 @@ export declare function assetPatterns(root: string, assets: AssetPatternClass[])
|
|
|
30
31
|
export declare function externalizePackages(context: string, request: string | undefined, callback: (error?: Error, result?: string) => void): void;
|
|
31
32
|
declare type WebpackStatsOptions = Exclude<Configuration['stats'], string | boolean>;
|
|
32
33
|
export declare function getStatsOptions(verbose?: boolean): WebpackStatsOptions;
|
|
34
|
+
export declare function getMainFieldsAndConditionNames(target: ScriptTarget, platformServer: boolean): Pick<WebpackOptionsNormalized['resolve'], 'mainFields' | 'conditionNames'>;
|
|
33
35
|
export {};
|
|
@@ -29,11 +29,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.getStatsOptions = exports.externalizePackages = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
32
|
+
exports.getMainFieldsAndConditionNames = exports.getStatsOptions = exports.externalizePackages = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
33
33
|
const crypto_1 = require("crypto");
|
|
34
34
|
const fs_1 = require("fs");
|
|
35
35
|
const glob_1 = __importDefault(require("glob"));
|
|
36
36
|
const path = __importStar(require("path"));
|
|
37
|
+
const typescript_1 = require("typescript");
|
|
37
38
|
function getOutputHashFormat(option, length = 20) {
|
|
38
39
|
const hashFormats = {
|
|
39
40
|
none: { chunk: '', extract: '', file: '', script: '' },
|
|
@@ -265,3 +266,18 @@ function getStatsOptions(verbose = false) {
|
|
|
265
266
|
: webpackOutputOptions;
|
|
266
267
|
}
|
|
267
268
|
exports.getStatsOptions = getStatsOptions;
|
|
269
|
+
function getMainFieldsAndConditionNames(target, platformServer) {
|
|
270
|
+
const mainFields = platformServer
|
|
271
|
+
? ['es2015', 'module', 'main']
|
|
272
|
+
: ['es2015', 'browser', 'module', 'main'];
|
|
273
|
+
const conditionNames = ['es2015', '...'];
|
|
274
|
+
if (target >= typescript_1.ScriptTarget.ES2020) {
|
|
275
|
+
mainFields.unshift('es2020');
|
|
276
|
+
conditionNames.unshift('es2020');
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
mainFields,
|
|
280
|
+
conditionNames,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
exports.getMainFieldsAndConditionNames = getMainFieldsAndConditionNames;
|
|
@@ -9,14 +9,21 @@ import { WebpackLoggingCallback } from '@angular-devkit/build-webpack';
|
|
|
9
9
|
import { logging } from '@angular-devkit/core';
|
|
10
10
|
import { Configuration, StatsCompilation } from 'webpack';
|
|
11
11
|
import { Schema as BrowserBuilderOptions } from '../../builders/browser/schema';
|
|
12
|
+
import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
|
|
12
13
|
export declare function formatSize(size: number): string;
|
|
13
|
-
export declare type BundleStatsData = [
|
|
14
|
+
export declare type BundleStatsData = [
|
|
15
|
+
files: string,
|
|
16
|
+
names: string,
|
|
17
|
+
rawSize: number | string,
|
|
18
|
+
estimatedTransferSize: number | string
|
|
19
|
+
];
|
|
14
20
|
export interface BundleStats {
|
|
15
21
|
initial: boolean;
|
|
16
22
|
stats: BundleStatsData;
|
|
17
23
|
}
|
|
18
24
|
export declare function generateBundleStats(info: {
|
|
19
|
-
|
|
25
|
+
rawSize?: number;
|
|
26
|
+
estimatedTransferSize?: number;
|
|
20
27
|
files?: string[];
|
|
21
28
|
names?: string[];
|
|
22
29
|
initial?: boolean;
|
|
@@ -27,4 +34,4 @@ export declare function statsErrorsToString(json: StatsCompilation, statsConfig:
|
|
|
27
34
|
export declare function statsHasErrors(json: StatsCompilation): boolean;
|
|
28
35
|
export declare function statsHasWarnings(json: StatsCompilation): boolean;
|
|
29
36
|
export declare function createWebpackLoggingCallback(options: BrowserBuilderOptions, logger: logging.LoggerApi): WebpackLoggingCallback;
|
|
30
|
-
export declare function webpackStatsLogger(logger: logging.LoggerApi, json: StatsCompilation, config: Configuration,
|
|
37
|
+
export declare function webpackStatsLogger(logger: logging.LoggerApi, json: StatsCompilation, config: Configuration, budgetFailures?: BudgetCalculatorResult[]): void;
|