Skip to content

[EsBuild] locale changed from "en" to "en-US" #26409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spock123 opened this issue Nov 17, 2023 · 24 comments · Fixed by #26479
Closed

[EsBuild] locale changed from "en" to "en-US" #26409

spock123 opened this issue Nov 17, 2023 · 24 comments · Fixed by #26479

Comments

@spock123
Copy link

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

localize, Don't known / other

Is this a regression?

Yes

Description

Before upgrading our product to Angular 17, our default LOCALE_ID was "en"

After upgrading and switching to Application builder, the LOCALE_ID value is now set to "en-US"

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

Before:
LOCALE_ID = en

After:
LOCALE_ID = en-US

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

Angular CLI: 17.0.1
Node: 18.18.2
Package Manager: pnpm 8.10.5
OS: darwin arm64

Angular: 17.0.3
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1700.1 (cli-only)
@angular-devkit/build-angular   17.0.1
@angular-devkit/core            17.0.1 (cli-only)
@angular-devkit/schematics      17.0.1 (cli-only)
@angular/cdk                    17.0.1
@angular/cli                    17.0.1
@angular/fire                   7.5.0
@angular/material               17.0.1
@schematics/angular             17.0.1 (cli-only)
rxjs                            7.5.7
typescript                      5.2.2
zone.js                         0.14.2

Anything else?

Angular.json:


{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "fastorder-shop": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "i18n": {
        "locales": {
          "da": "src/locale/messages.da.xlf",
          "en": "src/locale/messages.en.xlf",
          "it": "src/locale/messages.it.xlf",
          "es": "src/locale/messages.es.xlf",
          "de": "src/locale/messages.de.xlf",
          "pt": "src/locale/messages.pt.xlf",
          "fr": "src/locale/messages.fr.xlf"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser-esbuild",
          "options": {
            "outputPath": "dist/fastorder-shop",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": [
              "src/robots.txt",
              "src/favicon.ico",
              "src/manifest.json",
              "src/assets"
            ],
            "styles": [
              "src/app/styles/index.scss",
              {
                "input": "src/app/styles/theme-water-green.scss",
                "bundleName": "theme-water-green",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-dark-green.scss",
                "bundleName": "theme-dark-green",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-dark-blue.scss",
                "bundleName": "theme-dark-blue",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-petrol-blue.scss",
                "bundleName": "theme-petrol-blue",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-cyan.scss",
                "bundleName": "theme-cyan",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-black.scss",
                "bundleName": "theme-black",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-blue.scss",
                "bundleName": "theme-blue",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-green.scss",
                "bundleName": "theme-green",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-blue-gray.scss",
                "bundleName": "theme-blue-gray",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-teal.scss",
                "bundleName": "theme-teal",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-dark-orange.scss",
                "bundleName": "theme-dark-orange",
                "inject": false
              },
              {
                "input": "src/app/styles/theme-purple.scss",
                "bundleName": "theme-purple",
                "inject": false
              }
            ],
            "stylePreprocessorOptions": {
              "includePaths": [
                "src/app/styles"
              ]
            },
            "scripts": [],
            "vendorChunk": true,
            "extractLicenses": false,
            "buildOptimizer": false,
            "sourceMap": true,
            "optimization": false,
            "namedChunks": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                },
                {
                  "replace": "src/app/store/build-specifics/index.ts",
                  "with": "src/app/store/build-specifics/index.prod.ts"
                }

              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "localize": [
                "da",
                "en",
                "it",
                "es",
                "de",
                "pt",
                "fr"
              ],
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            },
            "localprod": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.localprod.ts"
                }
              ],
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": false,
              "localize": [
                "en"
              ],
              "baseHref": "/en",
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            },
            "localtest": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.localtest.ts"
                }
              ],
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": false,
              "localize": [
                "en"
              ],
              "baseHref": "/en",
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            },
            "dev": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ],
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": false,
              "localize": [
                "da",
                "en",
                "it",
                "es",
                "de",
                "pt",
                "fr"
              ],
              "styles": [
                "src/app/styles/index.scss",
                {
                  "input": "src/app/styles/theme-water-green.scss",
                  "bundleName": "theme-water-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-green.scss",
                  "bundleName": "theme-dark-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-blue.scss",
                  "bundleName": "theme-dark-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-petrol-blue.scss",
                  "bundleName": "theme-petrol-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-cyan.scss",
                  "bundleName": "theme-cyan",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-black.scss",
                  "bundleName": "theme-black",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-blue.scss",
                  "bundleName": "theme-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-green.scss",
                  "bundleName": "theme-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-blue-gray.scss",
                  "bundleName": "theme-blue-gray",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-teal.scss",
                  "bundleName": "theme-teal",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-orange.scss",
                  "bundleName": "theme-dark-orange",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-purple.scss",
                  "bundleName": "theme-purple",
                  "inject": false
                }
              ],
              "stylePreprocessorOptions": {
                "includePaths": [
                  "src/app/styles"
                ]
              },
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            },
            "test": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.test.ts"
                },
                {
                  "replace": "src/app/store/build-specifics/index.ts",
                  "with": "src/app/store/build-specifics/index.prod.ts"
                }
              ],
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": false,
              "localize": [
                "da",
                "en",
                "it",
                "es",
                "de",
                "pt",
                "fr"
              ],
              "styles": [
                "src/app/styles/index.scss",
                {
                  "input": "src/app/styles/theme-water-green.scss",
                  "bundleName": "theme-water-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-green.scss",
                  "bundleName": "theme-dark-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-blue.scss",
                  "bundleName": "theme-dark-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-petrol-blue.scss",
                  "bundleName": "theme-petrol-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-cyan.scss",
                  "bundleName": "theme-cyan",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-black.scss",
                  "bundleName": "theme-black",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-blue.scss",
                  "bundleName": "theme-blue",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-green.scss",
                  "bundleName": "theme-green",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-blue-gray.scss",
                  "bundleName": "theme-blue-gray",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-teal.scss",
                  "bundleName": "theme-teal",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-dark-orange.scss",
                  "bundleName": "theme-dark-orange",
                  "inject": false
                },
                {
                  "input": "src/app/styles/theme-purple.scss",
                  "bundleName": "theme-purple",
                  "inject": false
                }
              ],
              "stylePreprocessorOptions": {
                "includePaths": [
                  "src/app/styles"
                ]
              },
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            },
            "da": {
              "baseHref": "/da",
              "localize": [
                "da"
              ]
            },
            "en": {
              "baseHref": "/en",
              "localize": [
                "en"
              ]
            },
            "it": {
              "baseHref": "/it",
              "localize": [
                "it"
              ]
            },
            "es": {
              "localize": [
                "es"
              ]
            },
            "de": {
              "localize": [
                "de"
              ]
            },
            "pt": {
              "baseHref": "/pt",
              "localize": [
                "pt"
              ]
            },
            "fr": {
              "baseHref": "/fr",
              "localize": [
                "fr"
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "buildTarget": "fastorder-shop:build"
          },
          "configurations": {
            "production": {
              "buildTarget": "fastorder-shop:build:production"
            },
            "localprod": {
              "buildTarget": "fastorder-shop:build:localprod"
            },
            "localtest": {
              "buildTarget": "fastorder-shop:build:localtest"
            },
            "dev": {
              "buildTarget": "fastorder-shop:build:dev"
            },
            "da": {
              "buildTarget": "fastorder-shop:build:da"
            },
            "en": {
              "buildTarget": "fastorder-shop:build:en"
            },
            "it": {
              "buildTarget": "fastorder-shop:build:it"
            },
            "es": {
              "buildTarget": "fastorder-shop:build:es"
            },
            "de": {
              "buildTarget": "fastorder-shop:build:de"
            },
            "pt": {
              "buildTarget": "fastorder-shop:build:pt"
            },
            "fr": {
              "buildTarget": "fastorder-shop:build:fr"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "fastorder-shop:build"
          }
        },
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "src/**/*.ts",
              "src/**/*.html"
            ]
          }
        },
        "e2e": {
          "builder": "@briebug/cypress-schematic:cypress",
          "options": {
            "devServerTarget": "fastorder-shop:serve",
            "watch": true,
            "headless": false
          },
          "configurations": {
            "production": {
              "devServerTarget": "fastorder-shop:serve:production"
            }
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/fastorder-shop/server",
            "main": "server.ts",
            "tsConfig": "tsconfig.server.json",
            "sourceMap": true,
            "optimization": false,
            "buildOptimizer": false
          },
          "configurations": {
            "production": {
              "outputHashing": "media",
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "localize": [
                "da",
                "en",
                "it",
                "es",
                "de",
                "fr",
                "pt"
              ],
              "sourceMap": false,
              "optimization": true,
              "styles": [
                "src/app/styles/index.scss"
              ],
              "stylePreprocessorOptions": {
                "includePaths": [
                  "src/app/styles"
                ]
              },
              "buildOptimizer": true
            },
            "dev": {
              "outputHashing": "media",
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ],
              "localize": [
                "da",
                "en",
                "it",
                "es",
                "de",
                "pt",
                "fr"
              ],
              "sourceMap": false,
              "optimization": true,
              "stylePreprocessorOptions": {
                "includePaths": [
                  "src/app/styles"
                ]
              },
              "buildOptimizer": true
            },
            "da": {
              "localize": [
                "da"
              ]
            },
            "en": {
              "localize": [
                "en"
              ]
            },
            "it": {
              "localize": [
                "it"
              ]
            },
            "es": {
              "localize": [
                "es"
              ]
            },
            "de": {
              "localize": [
                "de"
              ]
            },
            "pt": {
              "localize": [
                "pt"
              ]
            },
            "fr": {
              "localize": [
                "fr"
              ]
            }
          }
        },
        "cypress-run": {
          "builder": "@briebug/cypress-schematic:cypress",
          "options": {
            "devServerTarget": "fastorder-shop:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "fastorder-shop:serve:production"
            }
          }
        },
        "cypress-open": {
          "builder": "@briebug/cypress-schematic:cypress",
          "options": {
            "devServerTarget": "fastorder-shop:serve",
            "watch": true,
            "headless": false
          },
          "configurations": {
            "production": {
              "devServerTarget": "fastorder-shop:serve:production"
            }
          }
        }
      }
    }
  },
  "cli": {
    "packageManager": "pnpm",
    "analytics": "73f81165-848c-4c25-9c1f-5d5e81bb6da0",
    "cache": {
      "enabled": true,
      "path": ".cache",
      "environment": "all"
    },
    "schematicCollections": [
      "@angular-eslint/schematics"
    ]
  },
  "schematics": {
    "@angular-eslint/schematics:application": {
      "setParserOptionsProject": true
    },
    "@angular-eslint/schematics:library": {
      "setParserOptionsProject": true
    }
  }
}

@JeanMeche
Copy link
Member

Are you sure about this ?

The default local id has been en-US for more than 4 years.
cf the source

I've just checked on stackblitz, v15 already returned en-US for LOCAL_ID

@spock123
Copy link
Author

spock123 commented Nov 18, 2023

Hi @JeanMeche , well it returns "en" with our setup, using the old builder. We are specifying the locale values in the angular.json setup.

I assume it should return the values in angular.json, where does it get "en-US" from I wonder?

Switching between the two builder gives us 2 different values for LOCALE_ID injection value.

Thank you for your quick reply.

@JoostK JoostK transferred this issue from angular/angular Nov 18, 2023
@JoostK
Copy link
Member

JoostK commented Nov 18, 2023

This looks similar to #26026

@alan-agius4
Copy link
Collaborator

Hi @spock123, I am unable to replicate this discrepancies reported between the application and browser builder. Can you please provide a reproduction?

en-US is Angular's default sourceLocale which can be changed by setting sourceLocale in the i18n configuration object.

@alan-agius4 alan-agius4 added the needs: repro steps We cannot reproduce the issue with the information given label Nov 21, 2023
@spock123
Copy link
Author

Hi @alan-agius4 I shall try to make a simple version, I'll have to simplify our application a lot but I'll give it a shot.

@alan-agius4
Copy link
Collaborator

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.

@spock123
Copy link
Author

I bet it works if I do that /s .. we shall see hehe

@vorlif
Copy link

vorlif commented Nov 24, 2023

Hi, just to clarify that this is not a unique case: we have the same problem as here and in #26026. The LOCALE_ID returns 'en-US' for each language. I have tried to reproduce the issue with a minimal project, but without success. (In the minimal project, everything works as it should).

I will have another look in the coming days to see if I can reproduce it.

@alan-agius4
Copy link
Collaborator

Can you check if you replace node_modules/@angular-devkit/build-angular/src/tools/esbuild/application-code-bundle.js with the contents of https://gist.github.com/alan-agius4/9e8ba93fb8a837b43f8d6931e8f2164f fixes the issue?

@vorlif
Copy link

vorlif commented Nov 24, 2023

Hi @alan-agius4, thanks for your work!

I have replaced it, but the error persists.

I have also tested the new build system (@angular-devkit/build-angular:application), but the issue is the same.

@alan-agius4
Copy link
Collaborator

@vorlif this issue is about the application builder, if you are experiment the problem with the webpack based builder. It’s different.

@vorlif
Copy link

vorlif commented Nov 24, 2023

@alan-agius4 Sorry, I should have written that in more detail. Here the builder and my the results when I open the created de app:

  • @angular-devkit/build-angular:browser - de ✔️
  • @angular-devkit/build-angular:browser-esbuild - en-US
  • @angular-devkit/build-angular:application - en-US

It works correctly with the old build system (Webpack), but not with the new build systems. I think this is the same issue as described here.

@spock123 Did you use the application builder (@angular-devkit/build-angular:application)? You write about the "old" builder and your angular.json contains @angular-devkit/build-angular:browser-esbuild.

So I think you have tested @angular-devkit/build-angular:browser-esbuild and @angular-devkit/build-angular:browser?

@spock123
Copy link
Author

@vorlif thanks, now I don't feel so alone :)
I was using the browser-esbuild builder. I have precisely the same issue - browser builder gives correct LOCALE_ID; while browser-esbuild gives me en-US

@alan-agius4
Copy link
Collaborator

@spock123, even for you #26409 (comment) doesn't fix your issue?

@spock123
Copy link
Author

spock123 commented Nov 24, 2023 via email

@vorlif
Copy link

vorlif commented Nov 24, 2023

Okay, I've found the problem for myself. My IDE has automatically added this import

import {$localize} from '@angular/localize/init';

Then I use in the code:

rarelyUsedFunction(): string {
    return $localize`Text`
}

If I remove the import, the problem is solved.

@spock123
Copy link
Author

@spock123, even for you #26409 (comment) doesn't fix your issue?

Hey!! that fixed it!!!! @alan-agius4

@spock123
Copy link
Author

@vorlif how did you get angular.json configured with the application builder btw? I use @angular-devkit/build-angular:browser-esbuild, and if I replace that with @angular-devkit/build-angular:application, I get this syntax error for angular.json:


{
      instancePath: '',
      schemaPath: '#/required',
      keyword: 'required',
      params: { missingProperty: 'browser' },
      message: "must have required property 'browser'"
    }

@vorlif
Copy link

vorlif commented Nov 24, 2023

@vorlif how did you get angular.json configured with the application builder btw? I use @angular-devkit/build-angular:browser-esbuild, and if I replace that with @angular-devkit/build-angular:application, I get this syntax error for angular.json:

You have to replace main with browser. Take a look at the documentation, it is explained in detail there. You may need to make additional modifications to your configuration.

@alan-agius4 alan-agius4 removed the needs: repro steps We cannot reproduce the issue with the information given label Nov 24, 2023
@alan-agius4 alan-agius4 self-assigned this Nov 24, 2023
@alan-agius4 alan-agius4 added freq1: low Only reported by a handful of users who observe it rarely severity3: broken labels Nov 24, 2023
@alan-agius4
Copy link
Collaborator

@spock123, thanks for confirming that the proposed change fixes your issue.

@imario42
Copy link

@alan-agius4 : Just to chime in here, your fix also fixed it for me. Thank you! Any idea when we will see that in production?

@spock123
Copy link
Author

My guess is within the next 2 days. Last release was about 8 days ago, so it's about this time a new bugfix release comes out.

@JeanMeche
Copy link
Member

Release happen mostly on wednesday. Last week was a bit particular because of Thanksgiving 👌

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Dec 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
7 participants