We use NestJS at work and the backend project needs to perform date calculations and formatting in the services. Our team chose momentJS because it is the one of the most popular date-time open source project. After a while, we discovered that the library size is huge (~290kb) and it is not tree-shakable. If I want to use format function to display a date in YYYY-MM-DD format, I must import the entire library into the code.
In Angular Architect Training Course, Bonnie Brennan said moment is so huge that that we should import moment locale instead. I chose a different route and decided to get rid of moment once and for all.
After doing some research, our team decided to replace momentJS with date-fns library, a lightweight date-time library, that has all the functions our project needs.
We made the migration in five steps:
- Install and extend eslint-plugin-you-dont-need-momentjs plugin, run eslint on the files to find all momentJS errors
- Replace momentJS functions with native JS if possible
- Create DateFnsService service in CoreModule that encapsulates the functionality of date-fns/fp submodule
- Import CoreModule into other modules of the project
- Inject DateFnsService in constructors and replace the remaining momentJS functions with functions of DateFnsService
Step 1: Install and extend eslint-plugin-you-dont-need-momentjs plugin
npm install --save-dev eslint-plugin-you-dont-need-momentjs
"extends" : ["plugin:you-dont-need-momentjs/recommended"],
Executed npm run lint command on terminal, the plugin outputted errors and warnings.
Step 2: Convert momentJS functions to native JS
Follow the examples in https://github.com/you-dont-need/You-Dont-Need-Momentjs#parse to convert momentJS functions to native JS
For example, moment() is replaced with new Date() and isAfter is replaced with
// Before: in moment
moment('2010-10-20').isAfter('2010-10-19') => true
// After: in native JS
new Date(2010, 9, 20) > new Date(2010, 9, 19) => true
Step 3: Create DateFnsService service in CoreModule
The requirement of the service is to provide functionality to format date, and add days, months and years to a given date. It is feasible by using functions defined in date-fns/fp submodule
First, we install date-fns dependency in the project
npm install date-fns --save
Create DateFnsService service in CoreModule
import { format, addDays, addMonths, addYears } from 'date-fns/fp'
Injectable()
export class DateFnsService {
format(date: Date | number, format: string): string {
return format(format)(date)
}
addDays(date: Date | number, amount: number): Date {
return addDays(amount)(date)
}
addMonths(date: Date | number, amount: number): Date {
return addMonths(amount)(date)
}
addYears(date: Date | number, amount: number): Date {
return addYears(amount)(date)
}
}
Export DateFnsService from CoreModule such that it can be used outside of Core
@Module({
providers: [DateFnsService],
exports: [DateFnsService]
})
export class CoreModule {}
Step 4: Import CoreModule to other modules
import { CoreModule } from '@/core'
@Module({
imports: [CoreModule],
providers: [AppController, AppService],
exports: []
})
export class AppModule {}
Step 5: Use DateFnsService in place of momentJS
Inject DateFnsService in AppService’s constructor and call its functions to manipulate date inside the function
import { DateFnsService } from '@/core'
// import * as moment from 'moment'
@Inject()
export class AppService {
constructor (private datefnsService: DateFnsService) {}
someFunction(): string {
// Before:
// return = moment()
// .add(1, 'days')
// .add(1, 'months')
// .add(1, 'years')
// .format('YYYY-MM-DD')
// After:
let mydate = this.datefnsService.addDays(new Date(), 1)
mydate = this.datefnsService.addMonths(mydate, 1)
mydate = this.datefnsService.addYears(mydate, 1)
return this.datefnsService.format(mydate, 'yyyy-MM-dd'); <= '2022-06-19'
}
}
Step 5 is repeated in all services until npm run lint does not produce any momentJS error. Afterward, we remove moment dependency from package.json and the project saves around 260kb.
This is the end of the blog post! I hope you enjoy reading it and NestJS development.
Resources: