Angular momentjs and the optimization bailouts warning - Luxon

Updated: 2024-01-25

What 'CommonJS or AMD dependencies can cause optimization bailouts' mean?

To understand in detail the consequences of this warning during the build of your application you can read this article from the Angular Team:
How CommonJS is making your bundles larger.

In summary, with CommonJS it's much harder to analyze the dependencies and optimize the dependencies during the tree-shaking activity.

Angular will show a warning if your project depends on non-tree-shakeable modules.

How to remove the warning and optimize the bundle

If you encounter this issue with momentjs ... well it's maybe time to migrate to a new library. Momentjs is victim of its own success and will not be improved anymore to avoid the risk of breaking millions of projects.

ESM support won't be implemented.

The developer of momentjs recommend to switch to a new library: https://momentjs.com/docs/#/-project-status/

We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.

momentjs won't support esm and won't be optimized for your project. For my projects I migrated successfully to dayjs.

This library is between the recommended alternatives mentioned by momentjs and didn't require any change in my code.

If you use dayjs when you import the library in your code remember to use the esm version: import * as dayjs from 'dayjs/esm'; or Angular will complain again that 'CommonJS or AMD dependencies can cause optimization bailouts.

For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies'

Luxon, as an alternative to momentjs and dayjs

After multiple issues with dayjs (11.2023), I opted for (Luxon)[https://moment.github.io/luxon/#/].

Luxon use immutable values, for this reason it has a bigger impact on your code compared to dayjs.

For simple use cases dayjs seemed working perfectly out-of-the-box, but when I started to use the extensions the APIs had issues with Angular, with the fix promised for the future. The optimization issue shown by momentjs came back with the extensions of dayjs.

Even worse, the Angular Team don't plan to add an Adapter (https://github.com/angular/components/issues/20599).

Luxon requires some changes to your code for the migration.

import {LuxonDateAdapter, MAT_LUXON_DATE_ADAPTER_OPTIONS, MAT_LuXON_DATE_FORMATS, MAtLuxonDateModule} from '@angular/material-luxon-adapter' 
 
providers: [{provide: MAT_DATE_LOCALE, useValue: 'de-CH'}, 
{ 
  provide: DateAdapter, 
  useClass: LuxonDateAdapter, 
  deps: [MAT_DATE_LOCALE, MAT_LUXON_DATE_ADAPTER_OPTIONS] 
}, 
{provide: MAT_DATE_FORMATS, useValue: MAT_LUXON_DATE_FORMATS}]} 

Utilisation example:

import {DateTime as LuxonDateTime} from 'luxon'; 
LuxonDateTime.fromJSDate(new Date(...)).toLocaleString(LuxonDateTime.DATETIME_FULL_WITH_SECONDS) 
 
const momentDate = LuxonDateTime.fromJSDate(jsDate) 
LuxonDateTime.now().minus({years:1}).toJSDate(); 
 
this.luxonDate.hour.valueOf(); // moment(date).hour() 
this.selectedDate = luxonSelectedDate.toISO(); 

Example for a form

hourField: new FormControl<number>(this.currentDate.hour.valueOf(), {validators: [Validators.min(0), Validators.max(23)]}) 
 
dateField: new FormControl<Date>(this.currentDate.toJSDate()) 

You could be interested in

Right click context menu with Angular

Right click custom menu inside dynamic lists with Angular Material
2020-05-31

Enums in Angular templates

How to use enum in the html template
2019-01-21
WebApp built by Marco using SpringBoot 3.2.4 and Java 21, in a Server in Switzerland