angular-cli icon indicating copy to clipboard operation
angular-cli copied to clipboard

TypeError: $localize is not a function => library components not translated

Open my-jupiler opened this issue 3 years ago • 45 comments

Which @angular/* package(s) are the source of the bug?

localize

Is this a regression?

Yes

Description

Hello,

I just migrated from 11 to 14. (had difficulties to do intermediate migrations so I made a fresh install)

My localized production builds fail to start with this error stack : ERROR Error: Uncaught (in promise): TypeError: $localize is not a function consts@http://localhost/en/player/main.e48ad9d7ec515188.js:3:1262797

Build is done with: ng build application --conifguration=production --localize

generated main.js starts with : var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"en"});

If build without localize option, I'm getting a slightly different error : $localize is not defined and the main.js does not contain the same first line

main.js contains this for each label to translate : $localize:@@button.logOut␟bb694b49d408265c91c62799c2b3a7e3151c824d␟3797778920049399855:Logout

Clearly, translation is not done. I tried to recreate my messages files but I get errors with extract-i18n : _Error: Module build failed (from ./node_modules/@angular-devkit/build-angular/src/builders/extract-i18n/ivy-extract-loader.js): TypeError: Cannot create property 'message' on string 'dist\bg-common\fesm2020\bg-common.mjs: Unexpected messageParts for $localize (expected an array of strings).
4968 | i18n_0 = MSG_EXTERNAL_buttonYes$$LIB_BG_CORE_COMPONENTS_DIALOG_COMPONENT_TS__1; 4969 | } else {

4970 | i18n_0 = $localize(_t2 || (_t2 = :@@buttonYes␟4f20f2d5a6882190892e58b85f6ccbedfa737952␟2807800733729323332:Yes)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4971 | }

I was using $localize function in a few typescript componenst but I removed it and now I have only i18n attributes in HTML templates.

Development built works fine.

Regards

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

_ERROR Error: Uncaught (in promise): TypeError: $localize is not a function

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 14.0.2
Node: 16.15.1
Package Manager: npm 8.11.0
OS: win32 x64

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

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1400.2
@angular-devkit/build-angular   14.0.2
@angular-devkit/core            14.0.2
@angular-devkit/schematics      14.0.2
@schematics/angular             14.0.2
rxjs                            7.5.5
typescript                      4.7.3

package.json : 
"dependencies": {
    "@angular/animations": "^14.0.0",
    "@angular/cdk": "^14.0.2",
    "@angular/common": "^14.0.0",
    "@angular/compiler": "^14.0.0",
    "@angular/core": "^14.0.0",
    "@angular/forms": "^14.0.0",
    "@angular/material": "^14.0.2",
    "@angular/platform-browser": "^14.0.0",
    "@angular/platform-browser-dynamic": "^14.0.0",
    "@angular/router": "^14.0.0",
    "js-sha256": "^0.9.0",
    "ng-recaptcha": "^9.0.0",
    "ng2-charts": "^3.0.11",
    "ngx-image-cropper": "^6.1.0",
    "ngx-quill": "^17.0.0",
    "quill": "^1.3.7",
    "quill-better-table": "^1.2.10",
    "rxjs": "~7.5.0",
    "tslib": "^2.3.0",
    "uuid": "^8.3.2",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.0.2",
    "@angular/cli": "^14.0.2",
    "@angular/compiler-cli": "^14.0.0",
    "@angular/localize": "^14.0.2",
    "@types/jasmine": "~4.0.0",
    "jasmine-core": "~4.1.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.7.2"
  }

Anything else?

No response

my-jupiler avatar Jun 26 '22 09:06 my-jupiler

There was a fix for extract-i18n in CLI 14.0.3.

I don't know enough about the i18n pipeline to tell why the $localize calls are not translated during build time. A reproduction would help, as I suspect this is some issue with your configuration.

JoostK avatar Jun 26 '22 09:06 JoostK

My config was fine with Angular 11. There are probably adaptations to be done but I could not find which. I'm trying the fix on extract-i18n to check or any progress

my-jupiler avatar Jun 26 '22 09:06 my-jupiler

thanks for the tip on extract-i18n, 14.0.3 fixed it

my-jupiler avatar Jun 26 '22 10:06 my-jupiler

Recreating messages dit not help anyway

my-jupiler avatar Jun 26 '22 10:06 my-jupiler

I downloaded the sample i18n from https://angular.io/guide/i18n-example I aligned my project configuration (localize : true as default, false for development). Still getting the error.

I will try to run the sample app

my-jupiler avatar Jun 26 '22 10:06 my-jupiler

The sample app runs with translated versions

my-jupiler avatar Jun 26 '22 10:06 my-jupiler

Seems that only library messages are not translated, I can find my main app own messages properly translated in main.js.

(Though messages from library components were properly extracted)

Could be related to https://github.com/angular/angular/issues/34056

my-jupiler avatar Jun 26 '22 10:06 my-jupiler

Unfortunately without a reproduction we will not be able to look into this any further.

alan-agius4 avatar Jul 01 '22 12:07 alan-agius4

What do you need as reproduction ? An example project that you can run by yourself ?

my-jupiler avatar Jul 01 '22 13:07 my-jupiler

Correct.

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.

alan-agius4 avatar Jul 01 '22 13:07 alan-agius4

Right. I will start from the i18n sample app coming from Angular site and will add consumption of a home made library ;)

my-jupiler avatar Jul 01 '22 14:07 my-jupiler

Created an i18napp and i18nlib. So far I Cannot reproduce but I found out that output-path on extract-i18n is no longer project relative but root directory relative. And "sourceFile" context-type property in messages.xlf are therefore root related. Though it seems that this sourceFile is only .. informative. I can put any values in it, translation still works.

I'm analysing differences between the sample app and my main project...

my-jupiler avatar Jul 02 '22 08:07 my-jupiler

I have compared and aligned : dependencies in package.json, projects structures in angular.json, tsconfig, etc... between working project and not working one. No sucess so far.

Before I try to rebuild my app from fresh and clean install, are they any leads that I can follow regarding the translation of library i8n labels ? a compiler flag ?

my-jupiler avatar Jul 03 '22 09:07 my-jupiler

I find some differences in commands output : ng extract-i18n gives warning for duplicate label ids in my main project, not for the sample project in which I have added duplicates too. I therefore still have differences in my configuration

my-jupiler avatar Jul 03 '22 09:07 my-jupiler

Seems that compile-time inlining is not applied for library. Is there a specific parameter for that ?

my-jupiler avatar Jul 03 '22 10:07 my-jupiler

inlining of all $localize including those in libraries calls happens during the application build.

alan-agius4 avatar Jul 03 '22 10:07 alan-agius4

ok but seems not to go into some components

my-jupiler avatar Jul 03 '22 13:07 my-jupiler

Probably not related but my main.js bundle contains references to library components which module is not imported

my-jupiler avatar Jul 03 '22 13:07 my-jupiler

@my-jupiler I had the same issue - turns out this was caused by the library patching the $localize function. I'd suggest you reach out to the library that causes this.

daniel-sc avatar Jul 05 '22 09:07 daniel-sc

Hello Daniel, what do you mean patching ? overriding the method ? I have removed all references to the $localize function in typescript components in my own library, I now have only "i18n" attributes. Could it be that I'm including an external library that is messing with the localize ?

my-jupiler avatar Jul 05 '22 09:07 my-jupiler

@my-jupiler yes, I thought we were always talking about "external libraries" (such as ng-bootstrap etc.)

daniel-sc avatar Jul 05 '22 09:07 daniel-sc

my non angular libs are : "js-sha256": "^0.9.0", "ng2-charts": "^3.0.11", "ngx-image-cropper": "^6.1.0"

(removed quills)

Yes indeed I'm talking about my library package inside my projects in which I have 8 modules whose components are not translated in production build

my-jupiler avatar Jul 05 '22 09:07 my-jupiler

But your suggestion is interesting. compile-time inlining is not working but runtime translation should work as $localize function is referenced in the main.js bundle.

my-jupiler avatar Jul 05 '22 09:07 my-jupiler

@alan-agius4 @JoostK found how to reproduce this:

Add ios_saf 12.2-12.6 (note that this is contained e.g. in > 0.5%) to .browserslist. Then adding components from library that are localized and running the production build reproduce the issue.

(@my-jupiler This is of course as well a workaround: just remove older browsers..)

daniel-sc avatar Jul 11 '22 08:07 daniel-sc

@daniel-sc You are a winner ! Just reproduced it in my sample app.

https://github.com/my-jupiler/i18nExample.git

And my main app works now, thanks a lot !

my-jupiler avatar Jul 11 '22 08:07 my-jupiler

Workaround is fine for me, I consider it as part of version upgrade browserlist should be included in migration process , feature to add maybe ?

my-jupiler avatar Jul 11 '22 08:07 my-jupiler

the browserslist that makes the bug :

> 0.5% last 2 versions Firefox ESR not dead not IE 9-11 # For IE 9-11 support, remove 'not'.

my-jupiler avatar Jul 11 '22 08:07 my-jupiler

I have this same issue and browserlist with not ios_saf 12.2-12.6 fix it. Waiting for proper solution.

JanneHarju avatar Aug 11 '22 06:08 JanneHarju

@alan-agius4 There's a reproduction here. Can you take a look? WDYT?

jessicajaniuk avatar Aug 18 '22 23:08 jessicajaniuk

Hi @my-jupiler,

I tried to reproduce the issue using the reproduction provided above, however the build is not erroring.

~/cli-reproductions/i18nExample/i18nExample   main ± ng b --localize 
✔ Browser application bundle generation complete.
✔ Localized bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.

Initial Chunk Files           | Names         |  Raw Size | Estimated Transfer Size
main.eb9d52cf9adad779.js      | main          | 117.92 kB |                35.21 kB
polyfills.9f899a06b2dfdf4f.js | polyfills     |  33.11 kB |                10.70 kB
runtime.7e37e778064d7986.js   | runtime       |   1.05 kB |               599 bytes
styles.ef46db3751d8e999.css   | styles        |   0 bytes |                       -

                              | Initial Total | 152.08 kB |                46.50 kB

Build at: 2022-08-22T13:36:51.109Z - Hash: 4f67f49b836f3ffe - Time: 19437ms

alan-agius4 avatar Aug 22 '22 13:08 alan-agius4