Reputation: 499
I build an Angular app in french.
I use the native date pipe | date
and also a datepicker component (@danielmoncada/angular-datetime-picker
).
I'd like to display dates in french style and that the datepicker component is localized in french (months names, ...)
Code example:
<p>raw: {{today}}</p>
<p>date pipe: {{today | date}}</p>
<p>date pipe 'dd/MM/yyyy': {{today | date:'dd/MM/yyyy'}}</p>
<p>
date picker:
<input [owlDateTime]="dt1" [owlDateTimeTrigger]="dt1" placeholder="Date Time">
<owl-date-time [firstDayOfWeek]="1" [pickerType]="'calendar'" #dt1></owl-date-time>
</p>
This is in english, as expected.
Now I follow what I understood about localization in angular and I import in my AppModule the french locale with registerLocaleData
and set the LOCALE_ID
accordingly:
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
registerLocaleData(localeFr, 'fr');
@NgModule({
declarations: [],
imports : [],
providers : [
{ provide: LOCALE_ID, useValue: 'fr'}
]
})
This is in french, as expected.
OK, fine!
I have to say that here I'm launching the app in development using the classic ng serve
angular-cli command.
But when deploying the app to a test environment, these date-related things doesn't work and break the app because of a javascript error in the browser's console :
ERROR Error: InvalidPipeArgument: 'Missing locale data for the locale "fr".' for pipe 'e'
The dates and datepicker are not displayed because of the console error breaking the page generation...
We guess this is because we are using optimization=true
when building for production environment (parameter set in the angular.json
file)
This parameter is located at architect.build.configurations.production
in angular.json
:
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {...},
"configurations": {
"production": {
"fileReplacements": [...],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
...
Indeed, if we set it to false
, the problem goes!
But this is not accpetable to disable optimization in production.
I launched my app locally using the command ng serve --prod
, that will use the production build described above, with optimization set to true.
>> I reproduce the error!!
Then I tried to override with optimization: false
at the architect.serve.configurations.production
location in angular.json
:
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "dpe-front:build"
},
"configurations": {
"production": {
"browserTarget": "dpe-front:build:production",
"optimization": false
}
}
},
>> I DO NOT reproduce the error!!
The problem seems to deal with "optimization".
When set to true, my LOCALE definition doesn't works and it breaks the app...
Why locale configuration doesn't works in this case?? Am I missing something?
Upvotes: 0
Views: 1912
Reputation: 499
I found the problem origin!
It seems to be a bug in Angular 10.x caused by too agressive tree shaking during the build when in production mode and if your project is configured with angular strict mode.
or
sideEffects
to true
in app's package.json
file solved the problemWhen starting a new project in strict
mode, a package.json
file is created in project's src/app
directory.
{
"name": "myproject",
"private": true,
"description_1": "This is a special package.json file that is not used by package managers.",
"description_2": "It is used to tell the tools and bundlers whether the code under this directory is free of code with non-local side-effect. Any code that does have non-local side-effects can't be well optimized (tree-shaken) and will result in unnecessary increased payload size.",
"description_3": "It should be safe to set this option to 'false' for new applications, but existing code bases could be broken when built with the production config if the application code does contain non-local side-effects that the application depends on.",
"description_4": "To learn more about this file see: https://angular.io/config/app-package-json.",
"sideEffects": false
}
It has the sideEffects
option to tell to the webpack bundler that it can do more agressive tree shaking for all files under this directory, as they are "pure". The goal is to have smaller files at the end.
More details here: https://webpack.js.org/guides/tree-shaking/
So when sideEffects
is set to false
(the default), it tells that all files can be used for "more agressive tree shaking".
Setting it to true
or removing this package.json
file solved my problem.
However, doing the same thing in a brand new test project doesn't leads to the same problem...
The difference is that this new project is in angular v11, whereas my project was started using angular v10.
So this bug seems to have been solved with angular 11 release.
I had the problem using the DatePipe
, but apparently other pipes (like AsyncPipe
) can lead to same kind of "too agressive tree shaking problems", as in this example:
Tree shaking for Angular 10 shook out AsyncPipe when using sideEffects: false
I hope this will help other people!
Upvotes: 2