@angular-devkit/build-angular 17.0.3 → 17.0.5
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 +5 -5
- package/src/builders/application/build-action.js +1 -1
- package/src/builders/application/i18n.js +4 -1
- package/src/builders/application/options.js +12 -4
- package/src/builders/dev-server/vite-server.js +12 -14
- package/src/tools/esbuild/angular/compiler-plugin.js +22 -4
- package/src/tools/esbuild/application-code-bundle.js +7 -13
- package/src/tools/esbuild/i18n-inliner-worker.d.ts +7 -2
- package/src/tools/esbuild/i18n-inliner-worker.js +6 -7
- package/src/tools/esbuild/i18n-inliner.d.ts +5 -1
- package/src/tools/esbuild/i18n-inliner.js +26 -4
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +2 -1
- package/src/tools/esbuild/javascript-transformer-worker.js +3 -4
- package/src/tools/esbuild/javascript-transformer.d.ts +4 -2
- package/src/tools/esbuild/javascript-transformer.js +6 -2
- package/src/utils/environment-options.js +0 -1
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "17.0.
|
|
3
|
+
"version": "17.0.5",
|
|
4
4
|
"description": "Angular Webpack Build Facade",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
7
7
|
"builders": "builders.json",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@ampproject/remapping": "2.2.1",
|
|
10
|
-
"@angular-devkit/architect": "0.1700.
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1700.
|
|
12
|
-
"@angular-devkit/core": "17.0.
|
|
10
|
+
"@angular-devkit/architect": "0.1700.5",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1700.5",
|
|
12
|
+
"@angular-devkit/core": "17.0.5",
|
|
13
13
|
"@babel/core": "7.23.2",
|
|
14
14
|
"@babel/generator": "7.23.0",
|
|
15
15
|
"@babel/helper-annotate-as-pure": "7.22.5",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@babel/preset-env": "7.23.2",
|
|
21
21
|
"@babel/runtime": "7.23.2",
|
|
22
22
|
"@discoveryjs/json-ext": "0.5.7",
|
|
23
|
-
"@ngtools/webpack": "17.0.
|
|
23
|
+
"@ngtools/webpack": "17.0.5",
|
|
24
24
|
"@vitejs/plugin-basic-ssl": "1.0.1",
|
|
25
25
|
"ansi-colors": "4.1.3",
|
|
26
26
|
"autoprefixer": "10.4.16",
|
|
@@ -74,7 +74,7 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
74
74
|
// Ignore all node modules directories to avoid excessive file watchers.
|
|
75
75
|
// Package changes are handled below by watching manifest and lock files.
|
|
76
76
|
'**/node_modules/**',
|
|
77
|
-
'
|
|
77
|
+
`${workspaceRoot.replace(/\\/g, '/')}/**/.*/**`,
|
|
78
78
|
],
|
|
79
79
|
});
|
|
80
80
|
// Setup abort support
|
|
@@ -41,7 +41,10 @@ async function inlineI18n(options, executionResult, initialFiles) {
|
|
|
41
41
|
try {
|
|
42
42
|
for (const locale of options.i18nOptions.inlineLocales) {
|
|
43
43
|
// A locale specific set of files is returned from the inliner.
|
|
44
|
-
const
|
|
44
|
+
const localeInlineResult = await inliner.inlineForLocale(locale, options.i18nOptions.locales[locale].translation);
|
|
45
|
+
const localeOutputFiles = localeInlineResult.outputFiles;
|
|
46
|
+
inlineResult.errors.push(...localeInlineResult.errors);
|
|
47
|
+
inlineResult.warnings.push(...localeInlineResult.warnings);
|
|
45
48
|
const baseHref = getLocaleBaseHref(options.baseHref, options.i18nOptions, locale) ?? options.baseHref;
|
|
46
49
|
const { errors, warnings, additionalAssets, additionalOutputFiles, prerenderedRoutes: generatedRoutes, } = await (0, execute_post_bundle_1.executePostBundleSteps)({
|
|
47
50
|
...options,
|
|
@@ -11,6 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.normalizeOptions = void 0;
|
|
14
|
+
const node_fs_1 = require("node:fs");
|
|
14
15
|
const promises_1 = require("node:fs/promises");
|
|
15
16
|
const node_module_1 = require("node:module");
|
|
16
17
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -35,7 +36,15 @@ const schema_1 = require("./schema");
|
|
|
35
36
|
*/
|
|
36
37
|
// eslint-disable-next-line max-lines-per-function
|
|
37
38
|
async function normalizeOptions(context, projectName, options, plugins) {
|
|
38
|
-
|
|
39
|
+
// If not explicitly set, default to the Node.js process argument
|
|
40
|
+
const preserveSymlinks = options.preserveSymlinks ?? process.execArgv.includes('--preserve-symlinks');
|
|
41
|
+
// Setup base paths based on workspace root and project information
|
|
42
|
+
const workspaceRoot = preserveSymlinks
|
|
43
|
+
? context.workspaceRoot
|
|
44
|
+
: // NOTE: promises.realpath should not be used here since it uses realpath.native which
|
|
45
|
+
// can cause case conversion and other undesirable behavior on Windows systems.
|
|
46
|
+
// ref: https://github.com/nodejs/node/issues/7726
|
|
47
|
+
(0, node_fs_1.realpathSync)(context.workspaceRoot);
|
|
39
48
|
const projectMetadata = await context.getProjectMetadata(projectName);
|
|
40
49
|
const projectRoot = normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, projectMetadata.root ?? ''));
|
|
41
50
|
const projectSourceRoot = normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, projectMetadata.sourceRoot ?? 'src'));
|
|
@@ -156,7 +165,7 @@ async function normalizeOptions(context, projectName, options, plugins) {
|
|
|
156
165
|
};
|
|
157
166
|
}
|
|
158
167
|
// Initial options to keep
|
|
159
|
-
const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills,
|
|
168
|
+
const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, deleteOutputPath, namedChunks, budgets, deployUrl, } = options;
|
|
160
169
|
// Return all the normalized options
|
|
161
170
|
return {
|
|
162
171
|
advancedOptimizations: !!aot,
|
|
@@ -174,8 +183,7 @@ async function normalizeOptions(context, projectName, options, plugins) {
|
|
|
174
183
|
poll,
|
|
175
184
|
progress,
|
|
176
185
|
externalPackages,
|
|
177
|
-
|
|
178
|
-
preserveSymlinks: preserveSymlinks ?? process.execArgv.includes('--preserve-symlinks'),
|
|
186
|
+
preserveSymlinks,
|
|
179
187
|
stylePreprocessorOptions,
|
|
180
188
|
subresourceIntegrity,
|
|
181
189
|
serverEntryPoint,
|
|
@@ -246,17 +246,17 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
|
|
|
246
246
|
};
|
|
247
247
|
}),
|
|
248
248
|
});
|
|
249
|
-
logger.info('HMR update sent to client(s)
|
|
249
|
+
logger.info('HMR update sent to client(s).');
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
// Send reload command to clients
|
|
254
254
|
if (serverOptions.liveReload) {
|
|
255
|
-
logger.info('Reloading client(s)...');
|
|
256
255
|
server.ws.send({
|
|
257
256
|
type: 'full-reload',
|
|
258
257
|
path: '*',
|
|
259
258
|
});
|
|
259
|
+
logger.info('Page reload sent to client(s).');
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generatedFiles) {
|
|
@@ -329,6 +329,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
329
329
|
css: {
|
|
330
330
|
devSourcemap: true,
|
|
331
331
|
},
|
|
332
|
+
// Vite will normalize the `base` option by adding a leading and trailing forward slash.
|
|
332
333
|
base: serverOptions.servePath,
|
|
333
334
|
resolve: {
|
|
334
335
|
mainFields: ['es2020', 'browser', 'module', 'main'],
|
|
@@ -443,14 +444,14 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
443
444
|
}
|
|
444
445
|
// Parse the incoming request.
|
|
445
446
|
// The base of the URL is unused but required to parse the URL.
|
|
446
|
-
const pathname =
|
|
447
|
+
const pathname = pathnameWithoutBasePath(req.url, server.config.base);
|
|
447
448
|
const extension = (0, node_path_1.extname)(pathname);
|
|
448
449
|
// Rewrite all build assets to a vite raw fs URL
|
|
449
450
|
const assetSourcePath = assets.get(pathname);
|
|
450
451
|
if (assetSourcePath !== undefined) {
|
|
451
452
|
// The encoding needs to match what happens in the vite static middleware.
|
|
452
453
|
// ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
|
|
453
|
-
req.url =
|
|
454
|
+
req.url = `${server.config.base}@fs/${encodeURI(assetSourcePath)}`;
|
|
454
455
|
next();
|
|
455
456
|
return;
|
|
456
457
|
}
|
|
@@ -526,7 +527,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
526
527
|
}
|
|
527
528
|
// Parse the incoming request.
|
|
528
529
|
// The base of the URL is unused but required to parse the URL.
|
|
529
|
-
const pathname =
|
|
530
|
+
const pathname = pathnameWithoutBasePath(req.url, server.config.base);
|
|
530
531
|
if (pathname === '/' || pathname === `/index.html`) {
|
|
531
532
|
const rawHtml = outputFiles.get('/index.html')?.contents;
|
|
532
533
|
if (rawHtml) {
|
|
@@ -610,16 +611,13 @@ async function loadViteClientCode(file) {
|
|
|
610
611
|
(0, node_assert_1.default)(originalContents !== contents, 'Failed to update Vite client error overlay text.');
|
|
611
612
|
return contents;
|
|
612
613
|
}
|
|
613
|
-
function
|
|
614
|
+
function pathnameWithoutBasePath(url, basePath) {
|
|
614
615
|
const parsedUrl = new URL(url, 'http://localhost');
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
return pathname;
|
|
616
|
+
const pathname = decodeURIComponent(parsedUrl.pathname);
|
|
617
|
+
// slice(basePath.length - 1) to retain the trailing slash
|
|
618
|
+
return basePath !== '/' && pathname.startsWith(basePath)
|
|
619
|
+
? pathname.slice(basePath.length - 1)
|
|
620
|
+
: pathname;
|
|
623
621
|
}
|
|
624
622
|
function getDepOptimizationConfig({ disabled, exclude, include, target, prebundleTransformer, ssr, thirdPartySourcemaps, }) {
|
|
625
623
|
const plugins = [
|
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.createCompilerPlugin = void 0;
|
|
37
37
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
38
|
-
const
|
|
38
|
+
const node_fs_1 = require("node:fs");
|
|
39
39
|
const path = __importStar(require("node:path"));
|
|
40
40
|
const environment_options_1 = require("../../../utils/environment-options");
|
|
41
41
|
const javascript_transformer_1 = require("../javascript-transformer");
|
|
@@ -58,8 +58,11 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
58
58
|
if (!preserveSymlinks) {
|
|
59
59
|
// Use the real path of the tsconfig if not preserving symlinks.
|
|
60
60
|
// This ensures the TS source file paths are based on the real path of the configuration.
|
|
61
|
+
// NOTE: promises.realpath should not be used here since it uses realpath.native which
|
|
62
|
+
// can cause case conversion and other undesirable behavior on Windows systems.
|
|
63
|
+
// ref: https://github.com/nodejs/node/issues/7726
|
|
61
64
|
try {
|
|
62
|
-
tsconfigPath =
|
|
65
|
+
tsconfigPath = (0, node_fs_1.realpathSync)(tsconfigPath);
|
|
63
66
|
}
|
|
64
67
|
catch { }
|
|
65
68
|
}
|
|
@@ -283,7 +286,8 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
283
286
|
}
|
|
284
287
|
else if (typeof contents === 'string') {
|
|
285
288
|
// A string indicates untransformed output from the TS/NG compiler
|
|
286
|
-
|
|
289
|
+
const sideEffects = await hasSideEffects(request);
|
|
290
|
+
contents = await javascriptTransformer.transformData(request, contents, true /* skipLinker */, sideEffects);
|
|
287
291
|
// Store as the returned Uint8Array to allow caching the fully transformed code
|
|
288
292
|
typeScriptFileCache.set(request, contents);
|
|
289
293
|
}
|
|
@@ -294,7 +298,8 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
294
298
|
});
|
|
295
299
|
build.onLoad({ filter: /\.[cm]?js$/ }, (0, load_result_cache_1.createCachedLoad)(pluginOptions.loadResultCache, async (args) => {
|
|
296
300
|
return (0, profiling_1.profileAsync)('NG_EMIT_JS*', async () => {
|
|
297
|
-
const
|
|
301
|
+
const sideEffects = await hasSideEffects(args.path);
|
|
302
|
+
const contents = await javascriptTransformer.transformFile(args.path, pluginOptions.jit, sideEffects);
|
|
298
303
|
return {
|
|
299
304
|
contents,
|
|
300
305
|
loader: 'js',
|
|
@@ -326,6 +331,19 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
326
331
|
void stylesheetBundler.dispose();
|
|
327
332
|
void compilation.close?.();
|
|
328
333
|
});
|
|
334
|
+
/**
|
|
335
|
+
* Checks if the file has side-effects when `advancedOptimizations` is enabled.
|
|
336
|
+
*/
|
|
337
|
+
async function hasSideEffects(path) {
|
|
338
|
+
if (!pluginOptions.advancedOptimizations) {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
const { sideEffects } = await build.resolve(path, {
|
|
342
|
+
kind: 'import-statement',
|
|
343
|
+
resolveDir: build.initialOptions.absWorkingDir ?? '',
|
|
344
|
+
});
|
|
345
|
+
return sideEffects;
|
|
346
|
+
}
|
|
329
347
|
},
|
|
330
348
|
};
|
|
331
349
|
}
|
|
@@ -282,17 +282,6 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
|
|
|
282
282
|
// Locale data should go first so that project provided polyfill code can augment if needed.
|
|
283
283
|
let needLocaleDataPlugin = false;
|
|
284
284
|
if (i18nOptions.shouldInline) {
|
|
285
|
-
// When inlining, a placeholder is used to allow the post-processing step to inject the $localize locale identifier
|
|
286
|
-
polyfills.unshift('angular:locale/placeholder');
|
|
287
|
-
buildOptions.plugins?.push((0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
288
|
-
namespace: 'angular:locale/placeholder',
|
|
289
|
-
entryPointOnly: false,
|
|
290
|
-
loadContent: () => ({
|
|
291
|
-
contents: `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n`,
|
|
292
|
-
loader: 'js',
|
|
293
|
-
resolveDir: workspaceRoot,
|
|
294
|
-
}),
|
|
295
|
-
}));
|
|
296
285
|
// Add locale data for all active locales
|
|
297
286
|
// TODO: Inject each individually within the inlining process itself
|
|
298
287
|
for (const locale of i18nOptions.inlineLocales) {
|
|
@@ -347,8 +336,13 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
|
|
|
347
336
|
let contents = polyfillPaths
|
|
348
337
|
.map((file) => `import '${file.replace(/\\/g, '/')}';`)
|
|
349
338
|
.join('\n');
|
|
350
|
-
//
|
|
351
|
-
if (
|
|
339
|
+
// The below should be done after loading `$localize` as otherwise the locale will be overridden.
|
|
340
|
+
if (i18nOptions.shouldInline) {
|
|
341
|
+
// When inlining, a placeholder is used to allow the post-processing step to inject the $localize locale identifier.
|
|
342
|
+
contents += '(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n';
|
|
343
|
+
}
|
|
344
|
+
else if (i18nOptions.hasDefinedSourceLocale) {
|
|
345
|
+
// If not inlining translations and source locale is defined, inject the locale specifier.
|
|
352
346
|
contents += `(globalThis.$localize ??= {}).locale = "${i18nOptions.sourceLocale}";\n`;
|
|
353
347
|
}
|
|
354
348
|
return {
|
|
@@ -32,6 +32,11 @@ interface InlineRequest {
|
|
|
32
32
|
*/
|
|
33
33
|
export default function inlineLocale(request: InlineRequest): Promise<{
|
|
34
34
|
file: string;
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
code: string;
|
|
36
|
+
map: string | undefined;
|
|
37
|
+
messages: {
|
|
38
|
+
type: "error" | "warning";
|
|
39
|
+
message: string;
|
|
40
|
+
}[];
|
|
41
|
+
}>;
|
|
37
42
|
export {};
|
|
@@ -32,13 +32,12 @@ async function inlineLocale(request) {
|
|
|
32
32
|
const code = await data.text();
|
|
33
33
|
const map = await files.get(request.filename + '.map')?.text();
|
|
34
34
|
const result = await transformWithBabel(code, map && JSON.parse(map), request);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
return response;
|
|
35
|
+
return {
|
|
36
|
+
file: request.filename,
|
|
37
|
+
code: result.code,
|
|
38
|
+
map: result.map,
|
|
39
|
+
messages: result.diagnostics.messages,
|
|
40
|
+
};
|
|
42
41
|
}
|
|
43
42
|
exports.default = inlineLocale;
|
|
44
43
|
/**
|
|
@@ -31,7 +31,11 @@ export declare class I18nInliner {
|
|
|
31
31
|
* @param translation The translation messages to use when inlining.
|
|
32
32
|
* @returns A promise that resolves to an array of OutputFiles representing a translated result.
|
|
33
33
|
*/
|
|
34
|
-
inlineForLocale(locale: string, translation: Record<string, unknown> | undefined): Promise<
|
|
34
|
+
inlineForLocale(locale: string, translation: Record<string, unknown> | undefined): Promise<{
|
|
35
|
+
outputFiles: BuildOutputFile[];
|
|
36
|
+
errors: string[];
|
|
37
|
+
warnings: string[];
|
|
38
|
+
}>;
|
|
35
39
|
/**
|
|
36
40
|
* Stops all active transformation tasks and shuts down all workers.
|
|
37
41
|
* @returns A void promise that resolves when closing is complete.
|
|
@@ -11,6 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.I18nInliner = void 0;
|
|
14
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
14
15
|
const piscina_1 = __importDefault(require("piscina"));
|
|
15
16
|
const bundler_context_1 = require("./bundler-context");
|
|
16
17
|
const utils_1 = require("./utils");
|
|
@@ -109,12 +110,33 @@ class I18nInliner {
|
|
|
109
110
|
// Wait for all file requests to complete
|
|
110
111
|
const rawResults = await Promise.all(requests);
|
|
111
112
|
// Convert raw results to output file objects and include all unmodified files
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
(
|
|
113
|
+
const errors = [];
|
|
114
|
+
const warnings = [];
|
|
115
|
+
const outputFiles = [
|
|
116
|
+
...rawResults.flatMap(({ file, code, map, messages }) => {
|
|
117
|
+
const type = this.#fileToType.get(file);
|
|
118
|
+
(0, node_assert_1.default)(type !== undefined, 'localized file should always have a type' + file);
|
|
119
|
+
const resultFiles = [(0, utils_1.createOutputFileFromText)(file, code, type)];
|
|
120
|
+
if (map) {
|
|
121
|
+
resultFiles.push((0, utils_1.createOutputFileFromText)(file + '.map', map, type));
|
|
122
|
+
}
|
|
123
|
+
for (const message of messages) {
|
|
124
|
+
if (message.type === 'error') {
|
|
125
|
+
errors.push(message.message);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
warnings.push(message.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return resultFiles;
|
|
132
|
+
}),
|
|
116
133
|
...this.#unmodifiedFiles.map((file) => file.clone()),
|
|
117
134
|
];
|
|
135
|
+
return {
|
|
136
|
+
outputFiles,
|
|
137
|
+
errors,
|
|
138
|
+
warnings,
|
|
139
|
+
};
|
|
118
140
|
}
|
|
119
141
|
/**
|
|
120
142
|
* Stops all active transformation tasks and shuts down all workers.
|
|
@@ -11,7 +11,8 @@ interface JavaScriptTransformRequest {
|
|
|
11
11
|
sourcemap: boolean;
|
|
12
12
|
thirdPartySourcemaps: boolean;
|
|
13
13
|
advancedOptimizations: boolean;
|
|
14
|
-
skipLinker
|
|
14
|
+
skipLinker?: boolean;
|
|
15
|
+
sideEffects?: boolean;
|
|
15
16
|
jit: boolean;
|
|
16
17
|
}
|
|
17
18
|
export default function transformJavaScript(request: JavaScriptTransformRequest): Promise<Uint8Array>;
|
|
@@ -50,10 +50,8 @@ async function transformWithBabel({ filename, data, ...options }) {
|
|
|
50
50
|
// Strip sourcemaps if they should not be used
|
|
51
51
|
return useInputSourcemap ? data : data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, '');
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
const safeAngularPackage = /[\\/]node_modules[\\/]@angular[\\/]/.test(filename)
|
|
55
|
-
!/@angular[\\/]platform-server[\\/]f?esm2022[\\/]init/.test(filename) &&
|
|
56
|
-
!/@angular[\\/]common[\\/]locales[\\/]global/.test(filename);
|
|
53
|
+
const sideEffectFree = options.sideEffects === false;
|
|
54
|
+
const safeAngularPackage = sideEffectFree && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename);
|
|
57
55
|
// Lazy load the linker plugin only when linking is required
|
|
58
56
|
if (shouldLink) {
|
|
59
57
|
linkerPluginCreator ??= (await (0, load_esm_1.loadEsmModule)('@angular/compiler-cli/linker/babel')).createEs2015LinkerPlugin;
|
|
@@ -78,6 +76,7 @@ async function transformWithBabel({ filename, data, ...options }) {
|
|
|
78
76
|
},
|
|
79
77
|
optimize: options.advancedOptimizations && {
|
|
80
78
|
pureTopLevel: safeAngularPackage,
|
|
79
|
+
wrapDecorators: sideEffectFree,
|
|
81
80
|
},
|
|
82
81
|
},
|
|
83
82
|
],
|
|
@@ -30,18 +30,20 @@ export declare class JavaScriptTransformer {
|
|
|
30
30
|
* If no transformations are required, the data for the original file will be returned.
|
|
31
31
|
* @param filename The full path to the file.
|
|
32
32
|
* @param skipLinker If true, bypass all Angular linker processing; if false, attempt linking.
|
|
33
|
+
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
33
34
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
34
35
|
*/
|
|
35
|
-
transformFile(filename: string, skipLinker?: boolean): Promise<Uint8Array>;
|
|
36
|
+
transformFile(filename: string, skipLinker?: boolean, sideEffects?: boolean): Promise<Uint8Array>;
|
|
36
37
|
/**
|
|
37
38
|
* Performs JavaScript transformations on the provided data of a file. The file does not need
|
|
38
39
|
* to exist on the filesystem.
|
|
39
40
|
* @param filename The full path of the file represented by the data.
|
|
40
41
|
* @param data The data of the file that should be transformed.
|
|
41
42
|
* @param skipLinker If true, bypass all Angular linker processing; if false, attempt linking.
|
|
43
|
+
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
42
44
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
43
45
|
*/
|
|
44
|
-
transformData(filename: string, data: string, skipLinker: boolean): Promise<Uint8Array>;
|
|
46
|
+
transformData(filename: string, data: string, skipLinker: boolean, sideEffects?: boolean): Promise<Uint8Array>;
|
|
45
47
|
/**
|
|
46
48
|
* Stops all active transformation tasks and shuts down all workers.
|
|
47
49
|
* @returns A void promise that resolves when closing is complete.
|
|
@@ -54,9 +54,10 @@ class JavaScriptTransformer {
|
|
|
54
54
|
* If no transformations are required, the data for the original file will be returned.
|
|
55
55
|
* @param filename The full path to the file.
|
|
56
56
|
* @param skipLinker If true, bypass all Angular linker processing; if false, attempt linking.
|
|
57
|
+
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
57
58
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
58
59
|
*/
|
|
59
|
-
transformFile(filename, skipLinker) {
|
|
60
|
+
transformFile(filename, skipLinker, sideEffects) {
|
|
60
61
|
const pendingKey = `${!!skipLinker}--${filename}`;
|
|
61
62
|
let pending = this.#pendingfileResults?.get(pendingKey);
|
|
62
63
|
if (pending === undefined) {
|
|
@@ -65,6 +66,7 @@ class JavaScriptTransformer {
|
|
|
65
66
|
pending = this.#ensureWorkerPool().run({
|
|
66
67
|
filename,
|
|
67
68
|
skipLinker,
|
|
69
|
+
sideEffects,
|
|
68
70
|
...this.#commonOptions,
|
|
69
71
|
});
|
|
70
72
|
this.#pendingfileResults?.set(pendingKey, pending);
|
|
@@ -77,9 +79,10 @@ class JavaScriptTransformer {
|
|
|
77
79
|
* @param filename The full path of the file represented by the data.
|
|
78
80
|
* @param data The data of the file that should be transformed.
|
|
79
81
|
* @param skipLinker If true, bypass all Angular linker processing; if false, attempt linking.
|
|
82
|
+
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
80
83
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
81
84
|
*/
|
|
82
|
-
async transformData(filename, data, skipLinker) {
|
|
85
|
+
async transformData(filename, data, skipLinker, sideEffects) {
|
|
83
86
|
// Perform a quick test to determine if the data needs any transformations.
|
|
84
87
|
// This allows directly returning the data without the worker communication overhead.
|
|
85
88
|
if (skipLinker && !this.#commonOptions.advancedOptimizations) {
|
|
@@ -91,6 +94,7 @@ class JavaScriptTransformer {
|
|
|
91
94
|
filename,
|
|
92
95
|
data,
|
|
93
96
|
skipLinker,
|
|
97
|
+
sideEffects,
|
|
94
98
|
...this.#commonOptions,
|
|
95
99
|
});
|
|
96
100
|
}
|
|
@@ -81,7 +81,6 @@ exports.useLegacySass = (() => {
|
|
|
81
81
|
})();
|
|
82
82
|
const debugPerfVariable = process.env['NG_BUILD_DEBUG_PERF'];
|
|
83
83
|
exports.debugPerformance = isPresent(debugPerfVariable) && isEnabled(debugPerfVariable);
|
|
84
|
-
// Default to true on Windows to workaround Visual Studio atomic file saving watch issues
|
|
85
84
|
const watchRootVariable = process.env['NG_BUILD_WATCH_ROOT'];
|
|
86
85
|
exports.shouldWatchRoot = process.platform === 'win32'
|
|
87
86
|
? !isPresent(watchRootVariable) || !isDisabled(watchRootVariable)
|