react-component / picker

📅 All Date Pickers you need.
https://picker.react-component.now.sh/
MIT License
257 stars 295 forks source link

Huge bundle size when using with date-fns #125

Open jperelli opened 3 years ago

jperelli commented 3 years ago

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!

q1998763 commented 3 years ago

same + 1

miaopeng commented 3 years ago

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.

fgblomqvist commented 3 years ago

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.

SalahAdDin commented 1 year ago

It is the same with moment.Â