date-fns : tree-shaking doesn't seem to work

Viewed 446

I use only a few of the functions and made sure I import them as recommended for tree-shaking in their documentation :

import { parseISO, formatDistanceToNow } from 'date-fns'
import { fr } from 'date-fns/locale';

The code itself works fine, but when I look at the resulting JS bundle, the entire libray (all functions) along with all of the locales are bundled, resulting in ~1,37mb > parsed 600kb > Gzipped 111kb. I use NuxtJS (bundling with webpack) and the latest date-fns (2.27.0).

Here is the bundle generated :

Here is the bundle generated

Based on the answer to this similar question : date-fns 2 - can't get tree-shaking to work I've double-checked the final webpack config generated by nuxt, and it contains as expected mode: production. I am not using TypeScript on this project.

Also went through several related github issues like this one : https://github.com/date-fns/date-fns/issues/2589

None of the answers worked in my situation... what can I do to make the tree-shaking happen properly ? Let me know if you think my question is missing some information :)

1 Answers

Here is a fix for tree-shaking the date-fns locales that worked for me, using a Webpack alias (found the solution in this Github issue).

  1. Create a file called for example date-fns-locales.js next to your webpack config where you will re-export the functions you use in your project like this :
export { default as enGB } from 'date-fns/locale/en-GB';
export { default as enUS } from 'date-fns/locale/en-US';

export { default as fr } from 'date-fns/locale/fr';
// ...etc
...
  1. Then, add an alias your Webpack config :
    resolve: {
        alias: {
            'date-fns/locale$': require.resolve('./date-fns-locales.js')
        }
    },

In my particular case, using Nuxt.js for Webpack bundling I added this in nuxt.config.js instead :

extend (config, ctx) {
   config.resolve.alias['date-fns/locale$'] = require.resolve('./date-fns-locales.js');
   ...
}

Every time you import something from date-fns/locale it will look up the import using the alias, avoiding the full import of all locales.

This solved the problem for me and greatly reduced the bundle size.

I still haven't worked out how to achieve the same result for the actual date-fns functions.

Related