Skip to content

Commit c94f568

Browse files
committedJan 8, 2025·
fix(@angular/build): warn when @angular/localize/init is imported directly
Importing `@angular/localize/init` directly can cause unpredictable behavior, as highlighted in multiple reports: - angular/angular#59422 - angular/angular#48545 - angular/angular#59405 This update introduces a warning to alert developers of the potential risks associated with direct imports. (cherry picked from commit bfe9ee3)
1 parent 50611cd commit c94f568

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import type { Plugin } from 'esbuild';
10+
11+
const NG_LOCALIZE_RESOLUTION = Symbol('NG_LOCALIZE_RESOLUTION');
12+
13+
/**
14+
* This plugin addresses an issue where '@angular/localize/init' is directly imported,
15+
* potentially resulting in undefined behavior. By detecting such imports, the plugin
16+
* issues a warning and suggests including '@angular/localize/init' as a polyfill.
17+
*
18+
* @returns An esbuild plugin.
19+
*/
20+
export function createAngularLocalizeInitWarningPlugin(): Plugin {
21+
return {
22+
name: 'angular-localize-init-warning',
23+
setup(build) {
24+
build.onResolve({ filter: /^@angular\/localize\/init/ }, async (args) => {
25+
if (args.pluginData?.[NG_LOCALIZE_RESOLUTION]) {
26+
return null;
27+
}
28+
29+
const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
30+
pluginData[NG_LOCALIZE_RESOLUTION] = true;
31+
32+
const result = await build.resolve(args.path, {
33+
importer,
34+
kind,
35+
namespace,
36+
pluginData,
37+
resolveDir,
38+
});
39+
40+
return {
41+
...result,
42+
warnings: [
43+
...result.warnings,
44+
{
45+
text: `Direct import of '@angular/localize/init' detected. This may lead to undefined behavior.`,
46+
notes: [{ text: `Include '@angular/localize/init' as a polyfill instead.` }],
47+
},
48+
],
49+
};
50+
});
51+
},
52+
};
53+
}

‎packages/angular/build/src/tools/esbuild/application-code-bundle.ts

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import { createCompilerPlugin } from './angular/compiler-plugin';
2121
import { ComponentStylesheetBundler } from './angular/component-stylesheets';
2222
import { SourceFileCache } from './angular/source-file-cache';
23+
import { createAngularLocalizeInitWarningPlugin } from './angular-localize-init-warning-plugin';
2324
import { BundlerOptionsFactory } from './bundler-context';
2425
import { createCompilerPluginOptions } from './compiler-plugin-options';
2526
import { createExternalPackagesPlugin } from './external-packages-plugin';
@@ -68,6 +69,7 @@ export function createBrowserCodeBundleOptions(
6869
createLoaderImportAttributePlugin(),
6970
createWasmPlugin({ allowAsync: zoneless, cache: loadCache }),
7071
createSourcemapIgnorelistPlugin(),
72+
createAngularLocalizeInitWarningPlugin(),
7173
createCompilerPlugin(
7274
// JS/TS options
7375
pluginOptions,
@@ -288,6 +290,7 @@ export function createServerMainCodeBundleOptions(
288290
plugins: [
289291
createWasmPlugin({ allowAsync: zoneless, cache: loadResultCache }),
290292
createSourcemapIgnorelistPlugin(),
293+
createAngularLocalizeInitWarningPlugin(),
291294
createCompilerPlugin(
292295
// JS/TS options
293296
{ ...pluginOptions, noopTypeScriptCompilation: true },
@@ -424,6 +427,7 @@ export function createSsrEntryCodeBundleOptions(
424427
supported: getFeatureSupport(target, true),
425428
plugins: [
426429
createSourcemapIgnorelistPlugin(),
430+
createAngularLocalizeInitWarningPlugin(),
427431
createCompilerPlugin(
428432
// JS/TS options
429433
{ ...pluginOptions, noopTypeScriptCompilation: true },

0 commit comments

Comments
 (0)
Please sign in to comment.