Removing Moment.js locales from your Angular app JS bundles
What’s the matter with MomentJS?
Moment.js is a very popular & powerful library. It supports formatting and localization of dates/times, allowing to easily display dates / times appropriately for users all around the world.
Unfortunately, it hasn’t followed the trend of modern libraries taking advantage from ES modules (ESM) to provide better modularity. As soon as you import something from “moment” in your code, your JS bundles automatically include all the locales supported by Moment.js. In most cases, this is useless as applications generally only support a handful of locales.
Each Moment.js locale file “only” weights a few KB, but if you add them all together, then it starts to hurt pretty badly; especially for small to medium applications.
On the other hand, libraries such as RxJS, Lodash and many more, support importing specific functions/operations only when required, which drastically reduces the bundle size; limiting it to the strict necessary.
This has been a known problem for a while with Moment.js, but there’s hope; as some point this will probably be improved. For now though, we must implement a solution as this is really bad for user experience, performance… and the planet ;-)
Easiest solution for new projects
Fresh projects are probably better off using a library such as date-fns.
date-fns is also very powerful. I can’t compare it in detail with Moment.js, but I believe that both are roughly equivalent. If you’re looking for a comparison of both, then you can check out the following article.
Custom Webpack configuration to the rescue
In a recent article, I’ve explained how you can easily customize the Webpack configuration of your Angular applications.
Well the good news is that we can quickly fix the Moment.js bundling issue by customizing the Webpack configuration. What you need to do is to exclude all Moment.js locales by default and manually import those that you need.
Here’s how you can exclude Moment.js locales:
This solution uses the Ignore plugin of Webpack (a core plugin) to ignore Moment.js locale files.
Once this is added to your project, no Moment.js locale will be added to your JS bundles. But of course you’ll want at least one to be included!
To include a locale, you now have to import it explicitly in your application code. You can for instance do it in your “main.ts” file:
With this in place, the JS bundles will only contain what you really need.
Given how much weight it adds to the JS bundles, it is important to be aware of this issue and even more important to make sure to avoid it. Fortunately, as I’ve shown above, the fix is really easy to implement once you know how to customize the Webpack build of your Angular application.
Hopefully, this will help you improve your application and make it load fast for end users.
That’s it for today!