picker icon indicating copy to clipboard operation
picker copied to clipboard

Huge bundle size when using with date-fns

Open jperelli opened this issue 5 years ago • 4 comments

This line https://github.com/react-component/picker/blob/master/src/generate/dateFns.ts#L24 is importing all the locales from date-fns. I'm not sure how to do it to import only the default one so that the final bundle is not so big image

If I find a solution I'll make a Pull Request. Thanks for this awesome library!

jperelli avatar Aug 10 '20 17:08 jperelli

same + 1

q1998763 avatar Aug 14 '20 03:08 q1998763

My solution is write your custom config file instead of the official "dateFnsGenerateConfig".

Here is a config.ts example for zhCN:

import {
  getDay,
  getYear,
  getMonth,
  getDate,
  getHours,
  getMinutes,
  getSeconds,
  addYears,
  addMonths,
  addDays,
  setYear,
  setMonth,
  setDate,
  setHours,
  setMinutes,
  setSeconds,
  isAfter,
  isValid,
  getWeek,
  format as formatDate,
  parse as parseDate,
} from 'date-fns';
import zhCN from 'date-fns/locale/zh-CN';
import { GenerateConfig } from 'rc-picker/lib/generate';

const localeParse = (format: string) => {
  return format
    .replace(/Y/g, 'y')
    .replace(/D/g, 'd')
    .replace(/gggg/, 'yyyy')
    .replace(/g/g, 'G')
    .replace(/([Ww])o/g, 'wo');
};

const generateConfig: GenerateConfig<Date> = {
  // get
  getNow: () => new Date(),
  getWeekDay(date) { return getDay(date)},
  getYear(date) { return getYear(date)},
  getMonth (date) { return getMonth(date) },
  getDate(date) { return getDate(date)},
  getHour(date) { return getHours(date)},
  getMinute(date) { return getMinutes(date)},
  getSecond(date) { return getSeconds(date)},

  // set
  addYear (date, diff)  {return addYears(date, diff)},
  addMonth (date, diff) {return  addMonths(date, diff)},
  addDate (date, diff)  {return  addDays(date, diff)},
  setYear (date, year)  {return  setYear(date, year)},
  setMonth (date, month) {return  setMonth(date, month)},
  setDate (date, num)   {return  setDate(date, num)},
  setHour (date, hour)  {return  setHours(date, hour)},
  setMinute (date, minute) {return setMinutes(date, minute)},
  setSecond(date, second) { return setSeconds(date, second)},

  // Compare
  isAfter(date1, date2) { return isAfter(date1, date2)},
  isValidate(date) { return isValid(date)},

  locale: {
    getWeekFirstDay: () => {
      return zhCN.options!.weekStartsOn!;
    },
    getWeek: (locale, date) => {
      return getWeek(date, { locale: zhCN });
    },
    format: (locale, date, format) => {
      if (!isValid(date)) {
        return '';
      }
      return formatDate(date, localeParse(format), {
        locale: zhCN,
      });
    },
    parse: (locale, text, formats) => {
      for (let i = 0; i < formats.length; i += 1) {
        const format = localeParse(formats[i]);
        const formatText = text;
        const date = parseDate(formatText, format, new Date(), {
          locale: zhCN,
        });
        if (isValid(date)) {
          return date;
        }
      }
      return null;
    },
  },
};

export default generateConfig;

Then replace "dateFnsGenerateConfig" with this one in your DatePicker generating component.

miaopeng avatar Aug 14 '20 09:08 miaopeng

Instead of importing all locales, why not have generateConfig for date-fns take a second argument, which would be a map of all locales that you want to support? I think that's the best way to do it.

fgblomqvist avatar Aug 18 '20 15:08 fgblomqvist

It is the same with moment. 

SalahAdDin avatar Nov 15 '22 15:11 SalahAdDin