Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Moment.js in Ant Design (Antd) with Day.js #529

Open
iamkun opened this issue Mar 10, 2019 · 25 comments
Open

Replace Moment.js in Ant Design (Antd) with Day.js #529

iamkun opened this issue Mar 10, 2019 · 25 comments
Labels
enhancement New feature or request

Comments

@iamkun
Copy link
Owner

iamkun commented Mar 10, 2019

在 Ant Design (Antd) 中使用 Day.js 替换 Moment

This is an experimental attempt of replacing Moment.js in Ant Design project (Antd) with Day.js. If your project is not built with Ant Design, you don't have to include all those plugins below.

这是一个实验性的在 Ant Design (Antd) 中使用 Day.js 替换 Moment 的方案,如果你的项目并没有使用 Ant Design 那则不需要引入下面列出的全部插件。

Results 结论

Update: Antd Official doc
更新:antd 官方文档
https://ant.design/docs/react/replace-moment

https://ant.design/docs/react/replace-moment-cn

Only 3 steps to replace Moment.js with Day.js. Bundle size reduced from 65kb -> 4.19 kb.
只需要 3 步就可以快速实现替换,打包体积从 65kb 减小到 4.19 kb

Name Size Size gzip
Moment.js 231 kb 65.55 kb
Day.js 11.11 kb 4.19 kb

moment dayjs

moment dayjs 2kb

Steps 步骤

  1. Install Day.js 安装 Day.js
npm install dayjs --save
npm install antd-dayjs-webpack-plugin
  1. Update Webpack config 更新 Webpack 配置
    More info 参考 https://github.com/ant-design/antd-dayjs-webpack-plugin
// webpack-config.js
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin');

module.exports = {
  plugins: [
    new AntdDayjsWebpackPlugin()
  ]
}

That's it. Done.
就这么简单就完成了。

Notice 说明

  1. Day.js is designed to be immutable, however, in order to make full compatible to moment.js in Antd, we have to use a plugin 🚨 BadMutable 🚨 to make Day.js mutable. This's not good and not what we want, but there's no better option. With this plugin enabled, all setters will update the instance itself.
  • Day.js 被设计成不可变的对象,但是为了完成对 moment.js 的替换,必须要引入一个 🚨 BadMutable 🚨插件让其变成可变对象,这并不是一个好的选择,但为了兼容也没有更好的办法。当使用这个插件后,所有的 setter 都会更新当前实例。
  1. Day.js is a lightweight library with only 2kb size, but we have to use some other plugins to make full compatible to moment.js in Antd, so the final bundle size is 4.19 kb (Still small 😀)
  • Day.js 是一个只有 2kb 的轻量级时间库,但为了完成对 moment.js 和 Antd 代码的替换,我们需要引入一些特殊的插件,这会使最终的体积变成 4.19 kb (但仍然很小呀😀 )
Previous manual solution:
  1. Update Webpack config 更新 Webpack 配置
    You don't have to replacemoment to dayjs one by one in your code, Webpack will do this.
    无需手动替换 momentdayjs,Webpack 可以自动完成这个事情。
module.exports = {
  resolve: {
    alias: {
      moment: 'dayjs',
    }
  }
}
  1. Init Day.js in project's main index.js 在项目 index.js 中初始化 Day.js
    In the main entrance page (usually index.js / main.js), import Day.js core and it's plugins.
    在项目的入口文件中 (通常是 index.js / main.js ),引入 Day.js 核心库和相关插件
//import moment from 'moment';
//moment.locale('zh-cn');

import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import isMoment from 'dayjs/plugin/isMoment';
import badMutable from 'dayjs/plugin/badMutable';
import localeData from 'dayjs/plugin/localeData';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import weekYear from 'dayjs/plugin/weekYear';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import 'dayjs/locale/zh-cn';

dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.extend(advancedFormat);
dayjs.extend(customParseFormat);
dayjs.extend(weekYear);
dayjs.extend(weekOfYear);
dayjs.extend(isMoment);
dayjs.extend(localeData);
dayjs.extend(badMutable);

dayjs.locale('zh-cn');
@chenyong
Copy link

Random idea... even I bundle two dayjs instances(one mutable, one immutable), it's still obviously smaller than using momentjs. It has to be 2 different names if they want to be both bundled.

@CyberNika
Copy link

很棒,尝试一下。如果 antd 能来做这个事情就更好了。

@ghost
Copy link

ghost commented Mar 11, 2019

@snokier ant-design/ant-design#15311 You can join this issue with maintainers from Antd.

@ghost
Copy link

ghost commented Mar 11, 2019

@chenyong Will that make user confusion? Since mutable and immutable is hard to make it clear for some developer (I think, may be)

@chenyong
Copy link

Since mutable and immutable is hard to make it clear for some developer (I think, may be)

I'm afraid so... when mutable data and immutable data get used together, people get confused.

@iamkun
Copy link
Owner Author

iamkun commented Mar 11, 2019

@chenyong

It would be better if Antd could make a little refactor of the way using moment.js.

Treat moment object as immutable, and call clone each time before changing it's value like moment().clone().xxx.

In this way, there's no need using BadMutable plugin anymore. And Day.js is immutable all the time.

@hytStart
Copy link

按着您的步骤,引入了dayjs和相关插件,还是说 antd只支持moment
The value/defaultValue of DatePicker or MonthPicker must be a moment object after antd@2.0

@iamkun
Copy link
Owner Author

iamkun commented Mar 11, 2019

@hytStart Can you provide a test git repo, please?

@hytStart
Copy link

@hytStart Can you provide a test git repo, please?

Hi, sorry to bother you,please correct me if it's my mistake.
index.js
datepicker.js

@iamkun
Copy link
Owner Author

iamkun commented Mar 12, 2019

@hytStart You forgot the step 2 section : Update Webpack config.

@yongdamsh
Copy link

@iamkun
The localeData plugin is incompatible with react-dates.
I applied all the steps you provided but I get an error like the screenshot below:
DevTools_-_www_dev-myrealtrip_com_accommodations

It seems to be the problem that moment().localeData() works but moment.localeData becomes undefined.

P.S. Thanks for the great way to replace moment lib!

@iamkun
Copy link
Owner Author

iamkun commented Apr 8, 2019

@yongdamsh Can you provide a test git repo, please?

@yongdamsh
Copy link

@iamkun
Here is a repo for reproduction, thanks!
https://github.com/yongdamsh/dayjs-reproduce.git

@yongdamsh
Copy link

@iamkun Do you have any progress?

@iamkun
Copy link
Owner Author

iamkun commented Apr 14, 2019

@yongdamsh Need some time. Updates: #569 add .weekday API

@iamkun
Copy link
Owner Author

iamkun commented Apr 26, 2019

@yongdamsh We need to implement some missing methods as a separate plugin. Hope we could finish it in next release.

@iamkun
Copy link
Owner Author

iamkun commented May 13, 2019

@yongdamsh would you please give me push permission of your dayjs-reproduce repo?

@ichsarut
Copy link

ichsarut commented Aug 6, 2019

I use electron-react-boilerplate with ant design. I am trying to replace moment with dayjs.
but I have got this error.

Screen Shot 2562-08-06 at 23 29 11

I have followed with your instructions.

Screen Shot 2562-08-06 at 23 30 38
Screen Shot 2562-08-06 at 23 33 07
Screen Shot 2562-08-06 at 23 33 19

@iamkun
Copy link
Owner Author

iamkun commented Aug 6, 2019

@ichsarut Hi, a test repo, please?

@ichsarut
Copy link

ichsarut commented Aug 7, 2019

@yongdamsh
Copy link

@iamkun Is there any progress on this comment? And as you know, I solved the issue that can't start the reproduce repo.

@iamkun
Copy link
Owner Author

iamkun commented Aug 8, 2019

@yongdamsh I've tested your repo with dayjs@1.8.15 and seems worked as expected.

@Vbubblery
Copy link

Is there any solution for ant design vue?

@iamkun
Copy link
Owner Author

iamkun commented Jan 2, 2020

Is there any solution for ant design vue?

@Vbubblery I haven't tried but should be the same.

@transtone
Copy link

https://ant.design/docs/react/replace-moment

https://ant.design/docs/react/replace-moment-cn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants