picker
picker copied to clipboard
generatePicker imports all locales, with huge impact on bundle size
When swapping out moment.js with either day.js or date-fns, the generatePicker function imports all of the locales.
This results in a huge bundle and totally not needed in a lot of use cases. dateFns.ts#L26
Is there a way to get around this? It seems a little silly to have pre-loaded all locales when you only need one :)

I'm having the same issue, is there any recommend solution to avoid increase bundle size ?
I've just noticed this as well, sadly have no easy solution.
From the code it seems impossible to improve with just a configuration tweak. I guess the most straightforward "fix" would be to re-create the src/generate/dateFns.ts file in your project and tweak the imported locales. This will then also require changes in the places where the Locale object is used to make sure you have a fallback.
Would love to have an official solution though as https://ant.design/docs/react/replace-moment says You might want to replace Moment.js with another date library (now support dayjs and date-fns) to reduce bundle size. which might be a bit misleading if there is no way to also tweak locale imports.
wow we just found out this issue, does anyone found a good solution yet? Or the only thing is to go with tschanz-pvc solution?
EDIT: My colleague cooked up this file which fixes the issue, however we hard coded enGB locale which is the one we need. Hope it helps https://gist.github.com/petrvecera/3daaab83c4a1efa0182ced135af717cf
Same issue here.

Webpack alias to the rescue!
Create ./date-fns-locale.js next to your Webpack config. Here you re-export all the locales you need:
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
Here is the full list.
Add an alias to your webpack.config.js:
resolve: {
alias: {
'date-fns/locale$': require.resolve('./date-fns-locales.js')
}
},
Mind the $ in the name! As explained in the Webpack alias documentation: this will only match imports ending in "date-fns/locale" and ensures that we can still import from "date-fns/locale/en-GB". Beware that other places you import x from "date-fns/locale" will also be aliased to date-fns-locales.js.
The resulting bundle:

Edit: if you try to use a locale that is not exported from your date-fns-locales.js, you will get the error Cannot read property 'localize' of undefined.
To use en-GB you also need to include en-US as it extends from the US locale! (I fixed this in the code above)
Thank you @ekeijl - I will test this out to see how it works!
The webpack workaround sounds great...if I weren't using Create React App. I could probably hack something together using CRACO, but hopefully a proper solution can be found ASAP.
Thanks for this workaround @ekeijl ! It worked in my case for the locales :)
It's still too bad that tree-shaking doesn't work out of the box, as this is one of the main points highlighted by date-fns ...
For those using closed configurations like CRA and don't want to deal with CRACO or something like that, I was able to address this issue using patch-package. This is the diff it generated for me, and you can add other languages inside the new Locale object:
diff --git a/node_modules/rc-picker/lib/generate/dateFns.js b/node_modules/rc-picker/lib/generate/dateFns.js
index c8c7121..00de00d 100644
--- a/node_modules/rc-picker/lib/generate/dateFns.js
+++ b/node_modules/rc-picker/lib/generate/dateFns.js
@@ -1,7 +1,5 @@
"use strict";
-var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
-
Object.defineProperty(exports, "__esModule", {
value: true
});
@@ -9,7 +7,7 @@ exports.default = void 0;
var _dateFns = require("date-fns");
-var Locale = _interopRequireWildcard(require("date-fns/locale"));
+var Locale = { enUS: require("date-fns/locale/en-US") };
var dealLocal = function dealLocal(str) {
return str.replace(/_/g, '');
@matheusgrieger ,
That's amazing!
But it made me realize that even though I'm using Antd/rc-picker, the locales seem to be getting loaded by date-fns itself.
Any thoughts on what could be causing this? I'm hoping I can use a similar hack to fix that, but I'm not sure where to look.
EDIT No, I'm wrong. I forgot to do a build before analyzing. Applying your patch reduces my bundle size by almost 1 MB! Thanks for this solution!
@matheusgrieger,
Follow-up: this seems to work in development, but in production, I'm getting all kinds of errors from dateFns.js for pages that have a Calendar or DatePicker on them, so I'm having to roll back the patch for now.
Still glad to know about patch-package, though!
@devuxer that's weird, I'm using this patch in production and it seems to work just fine. Are you sure you added all locales your app needs?
@matheusgrieger, My app only uses en-US as far as I know. Perhaps there's something about the server (Azure App Service, in my case) that's causing the issue (e.g., maybe the server locale is different than my development machine's locale, though it's a U.S. server, so it shouldn't be).
Edit:
More details:
If I attempt to open a page with an Antd Calendar component on it, I get this error in the console:
TypeError: Cannot read properties of undefined (reading 'weekStartsOn')
at Object.getWeekFirstDay (dateFns.js:93:28)
at dateUtil.js:96:44
at me (DateBody.js:22:18)
at ui (react-dom.production.min.js:157:137)
at Yu (react-dom.production.min.js:267:460)
at Tc (react-dom.production.min.js:250:347)
at Oc (react-dom.production.min.js:250:278)
at Sc (react-dom.production.min.js:250:138)
at bc (react-dom.production.min.js:243:163)
at react-dom.production.min.js:123:115
If I attempt to open a page with an Antd DatePicker components, I get this error in the console:
RangeError: locale must contain localize property
at R (index.js:363:11)
at Object.format (dateFns.js:130:27)
at J (dateUtil.js:126:79)
at useValueTexts.js:19:23
at o (useMemo.js:6:30)
at Ae (useValueTexts.js:8:10)
at _e (RangePicker.js:409:24)
at ui (react-dom.production.min.js:157:137)
at Yu (react-dom.production.min.js:267:460)
at Tc (react-dom.production.min.js:250:347)
Coming up on three years of this bug being open. I just ran into it myself!
For anyone using Vite/Rollup instead of Webpack, the same workaround posted above works in your vite.config.js file, but for whatever reason I couldn't get the $ to work in the regex, despite it being supported according to Rollup documentation.
I have a central file where I manage all language imports anyway, so I just used the regular string to resolve, since I won't be importing anything directly from date-fns/locale/en-US for example.
// vite.config.js
resolve: {
alias: [
{ find: "date-fns/locale", replacement: "date-fns-locale-config.js" },
],
},
// date-fns-locale.config.js
export { default as enCA } from "date-fns/esm/locale/en-CA";
export { default as enUS } from "date-fns/esm/locale/en-US";
export { default as es } from "date-fns/esm/locale/es";
export { default as ptBR } from "date-fns/esm/locale/pt-BR";
Then just import from date-fns/locale as needed.
import { enCA } from "date-fns/locale";
With Vite:
// vite.config.mts
resolve: {
alias: {
// fix DatePicker's date-fns bundle size
'date-fns/locale': fileURLToPath(new URL('date-fns-locale', import.meta.url)),
}
}
// date-fns-locale.mjs
export { enGB } from './node_modules/date-fns/locale.mjs';