angular: Localized bundle generation failed: Unexpected messageParts for `$localize` (expected an array of strings).

🐞 bug report

Affected Package

@angular/*

The issue is caused by package @angular/localized

Is this a regression?

No, we didn't have this fetaure in angular 89: ....

Description

When I run ng build --configuration=production --localize I get this error: Localized bundle generation failed: Unexpected messageParts for $localize(expected an array of strings).

🔬 Minimal Reproduction

https://stackblitz.com/edit/angular-issue-repro2-r8en56.

🔥 Exception or Error



 `Localized bundle generation failed: Unexpected messageParts for `$localize` (expected an array of strings).
`

🌍 Your Environment

Angular Version:




Angular 9

Anything else relevant?

If I set optimizer to false in configuration production everything works perfectly

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 7
  • Comments: 23 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve applied your fix and it works for our case, everything is compiled properly now, thanks again

So this can be written (slightly more readably) as:

$localize(
  cachedObj||
  (
    cookedParts=[
      ":\u241f999aec8f47d76b8e0bbd0dd4e13170bb1b687e93\u241f867601126266312330:The actual string that's inside the i18n tag"
    ],
    rawParts=[
      ":\u241f999aec8f47d76b8e0bbd0dd4e13170bb1b687e93\u241f867601126266312330:The actual string that's inside the i18n tag"
    ],
    Object.defineProperty?
      Object.defineProperty(cookedParts,"raw",{value:rawParts}):
      cookedParts.raw=rawParts,
    cachedObj=cookedParts
  )
)

which is obviously TypeScript/terser/build-optimizer’s latest incantation of how to transform:

$localize `:\u241f999aec8f47d76b8e0bbd0dd4e13170bb1b687e93\u241f867601126266312330:The actual string that's inside the i18n tag`

into ES5 code.

We have a test for a slightly similar arrangement in our codebase already:

    it('should handle cached helper calls', () => {
      const diagnostics = new Diagnostics();
      const input =
          `$localize(cachedObj||(cachedObj=__makeTemplateObject(['try', 'me'],['try', 'me'])),40 + 2)`;
      const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]}) !;
      expect(output.code).toEqual('"try" + (40 + 2) + "me";');
    });

But this has another level of complication… I’ll put together a PR.

It sounds to me that one of the more aggressive terser optimisations is modifying the $localize calls in a way that the @angular/localize tooling cannot understand. Is it possible to build the app without localization and then find where there are instances of $localize in the built JS files?

Can you provide a reproduction of the problem? Ideally a runnable project or at least steps in how to produce one. It is difficult to debug without this