angular / angular-cli

CLI tool for Angular
https://cli.angular.dev
MIT License
26.79k stars 11.98k forks source link

Running ng serve with different locale throws runtime error "$localize is not a function" when $localize is used in a library (v18.0.4) #27878

Closed reifi closed 5 months ago

reifi commented 5 months ago

Command

serve

Is this a regression?

The previous version in which this bug was not present was

18.0.3

Description

After upgrading a working i18n app to v18.0.4, when running ng serve for a different locale then the base locale like ng serve -buildTarget=app:production,locale-de-AT, the runtime error "Uncaught TypeError: $localize is not a function" on a line from some .mjs that uses $localize `:@@some-id:translation` is thrown in dev console.

Running ng serve without special locale with its base locale works fine.

Also production build seems to work fine in both versions v18.0.3 and v18.0.4

ng serve in v18.0.4 seems to handle $localize in libraries different.

Minimal Reproduction

The content of $localize in debugger before throwing the error during ng serve in the affected app: image

Fresh installed app:

Running ng serve on a freshly generated app in v18.0.4 with a different locale works without runtime error, but it is not translated.

When using a library that uses $localize - for example importing a localized string - I get the string in base language

Example: An html containing <span i18n="@@hello">Hello</span> - {{library.value_hello}} would be shown in Italian as Ciao! - Hello instead of Ciao! - Ciao!

...and that's the point where I gave up for now.

Exception or Error

Uncaught TypeError: $localize is not a function

Your Environment

Angular CLI: 18.0.4
Node: 20.13.1
Package Manager: npm 10.5.2
OS: win32 x64

Angular: 18.0.3
... animations, cdk, common, compiler, compiler-cli, core, forms
... localize, material, platform-browser
... platform-browser-dynamic, router, upgrade

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1800.4
@angular-devkit/build-angular   18.0.4
@angular-devkit/core            18.0.4
@angular-devkit/schematics      18.0.4
@angular/cli                    18.0.4
@schematics/angular             18.0.4
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.7

Anything else relevant?

locales config:

"i18n": {
        "locales": {
          "en-150": {
            "translation": "src/locale/messages.en-150.xlf",
            "baseHref": "/non-virtual/en-150/"
          },
          "it": {
            "translation": "src/locale/messages.it.xlf",
            "baseHref": "/non-virtual/it/"
          }
        },
        "sourceLocale": {
          "code": "de-AT",
          "baseHref": "/non-virtual/de-AT/"
        }
      },
...

The build options contain


 "polyfills": [
     "zone.js",
    "@angular/localize/init"
],
'''
alan-agius4 commented 5 months ago

This seems like a bug but we'll need to look at a reproduction to find and fix the problem. Can you setup a minimal repro please?

You can read here why this is needed. A good way to make a minimal repro is to create a new app via ng new repro-app and adding the minimum possible code to show the problem. Then you can push this repository to github and link it here.

This might be related to your directory structure so its really important to get an accurate repro to diagnose this.

reifi commented 5 months ago

I have no minimal repo yet as I need to offer a public library to test too.

And my new angular app using the the library just did not translate the library strings at all (but had no runtime error).

Building all locales together with the library, and developing in base locale works correctly though

After the runtime error, when I restart ng serve it gives me following errors everyytime I start ng serve until i delete .angular directory (or do ng cache clean):

The file does not exist at "C:/app/.angular/cache/18.0.4/vite/deps/chunk-KI2M4SF2.js?v=c90bb1a8" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`.
The file does not exist at "C:/app/.angular/cache/18.0.4/vite/deps/chunk-NI2AAXXV.js?v=c90bb1a8" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`.
The file does not exist at "C:/app/.angular/cache/18.0.4/vite/deps/chunk-BUFAWFPU.js?v=c90bb1a8" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`.
alan-agius4 commented 5 months ago

@reifi, regarding the localization issue, since you are using the build-time translator, you need to exclude the library that requires localization by utilizing the prebundle option.

Here is an example:

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "options": {
    "prebundle": {
      "exclude": [
        "my-lib"
      ]
    }
  },
  "configurations": {
    "production": {
      "buildTarget": "test-app:build:production"
    },
    "development": {
      "buildTarget": "test-app:build:development"
    }
  },
  "defaultConfiguration": "development"
}
reifi commented 5 months ago

@alan-agius4 Thank you very much! This did a trick and it's served in a different locale agian. No clue why it's different to v18.0.3 though. I wouldn't have known until now why there is a reason to exclude from prebundling. Thanks a lot!

alan-agius4 commented 5 months ago

Before version 18, @angular/localize/init was automatically added when detected in node_modules. This led to a situation where, although no runtime errors occurred, translations in libraries were not applied during ng serve.

angular-automatic-lock-bot[bot] commented 4 months ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.