Skip to content

Commit 9d2f1c8

Browse files
Removed moment.js (swapped to dayjs) (OpusCapita#54)
Changed dependencies ==== Removed `moment.js` in favor of `dayjs` and `@opuscapita/i18n/lib/converters/DateConverter`. Result: build size with all dependencies but `react` and `react-dom`: - before `942 kb` - after `484 kb` Also updated `@opuscapita/react-autocompletes` to `3.0.1`, which saves another `70 kb` of bundle. Final size: `414kb` unminified, or 44% less size.
1 parent 8974acf commit 9d2f1c8

File tree

25 files changed

+281
-245
lines changed

25 files changed

+281
-245
lines changed

.circleci/config.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defaults: &defaults
22
docker:
3-
- image: opuscapita/minsk-core-ci:grails-2.4.4-jdk-8u131-nodejs-8.9.4-maven-3.3.9-docker
3+
- image: opuscapita/minsk-core-ci:grails-2.4.4-jdk-8u131-nodejs-8.9.4-maven-3.3.9
44
working_directory: ~/build
55

66
version: 2
@@ -20,19 +20,24 @@ jobs:
2020
- react-showroom
2121

2222
- run:
23-
name: "Installing dependencies."
24-
command: yarn install
23+
name: Installing dependencies.
24+
command: npm install
2525

2626
- save_cache:
2727
key: react-showroom-{{ .Branch }}-{{ checksum "package.json" }}
2828
paths:
2929
- ./node_modules
30+
- ./package-lock.json
3031
- ./yarn.lock
3132

3233
- run:
33-
name: "Running lint."
34+
name: Running lint.
3435
command: npm run lint
3536

37+
- run:
38+
name: Running tests.
39+
command: npm test
40+
3641
update-gh-pages:
3742
docker:
3843
<<: *defaults

config/doc/webpack.config.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
44

55
const PACKAGE_VERSION = require('../../package.json').version;
66
const PACKAGE_NAME = require('../../package.json').name;
7-
const {HOST, PORT} = require('../../.env');
7+
const { HOST, PORT } = require('../../.env');
88
const NODE_ENV = process.env.NODE_ENV;
99

1010
module.exports = {
@@ -27,10 +27,10 @@ module.exports = {
2727
},
2828
bail: true,
2929
plugins: [
30-
new webpack.DefinePlugin({
31-
'process.env.NODE_ENV': '"production"'
32-
}),
33-
new LodashModuleReplacementPlugin()
30+
new webpack.DefinePlugin({
31+
'process.env.NODE_ENV': '"production"'
32+
}),
33+
new LodashModuleReplacementPlugin()
3434
],
3535
externals: {
3636
react: {
@@ -56,8 +56,8 @@ module.exports = {
5656
module: {
5757
rules: [
5858
{
59-
test : /\.(png|jpg|jpeg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
60-
use : ['file-loader']
59+
test: /\.(png|jpg|jpeg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
60+
use: ['file-loader']
6161
},
6262
{
6363
test: /\.md$/,

config/webpack.config.js

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
99
const nodeExternals = require('webpack-node-externals');
1010

1111
const PACKAGE_VERSION = require('../package.json').version;
12-
const PACKAGE_NAME = require('../package.json').name;
1312
const HOST = require('../.env').HOST;
1413
const PORT = require('../.env').PORT;
1514
const NODE_ENV = process.env.NODE_ENV;
@@ -18,21 +17,21 @@ const IS_LINK_MODE = NODE_ENV === 'link';
1817
const WEBPACK_BUNDLE_ANALYZE = process.env.WEBPACK_BUNDLE_ANALYZE;
1918

2019
let plugins = [
21-
new ProgressBarPlugin(),
22-
new webpack.NoEmitOnErrorsPlugin(),
23-
new webpack.DefinePlugin({
24-
'process.env.HOST': JSON.stringify(HOST),
25-
'process.env.PORT': JSON.stringify(PORT),
26-
'process.env.NODE_ENV': `"${NODE_ENV}"`
27-
}),
28-
new LodashModuleReplacementPlugin()
20+
new ProgressBarPlugin(),
21+
new webpack.NoEmitOnErrorsPlugin(),
22+
new webpack.DefinePlugin({
23+
'process.env.HOST': JSON.stringify(HOST),
24+
'process.env.PORT': JSON.stringify(PORT),
25+
'process.env.NODE_ENV': `"${NODE_ENV}"`
26+
}),
27+
new LodashModuleReplacementPlugin()
2928
];
3029

31-
if(IS_LINK_MODE) {
30+
if (IS_LINK_MODE) {
3231
plugins.push(new WriteFilePlugin());
3332
}
3433

35-
if(WEBPACK_BUNDLE_ANALYZE && IS_PRODUCTION_MODE) {
34+
if (WEBPACK_BUNDLE_ANALYZE && IS_PRODUCTION_MODE) {
3635
let bundleAnalyzerPlugin = new BundleAnalyzerPlugin({
3736
analyzerMode: 'static',
3837
analyzerHost: '127.0.0.1',
@@ -94,7 +93,7 @@ module.exports = {
9493
publicPath: '/',
9594
path: path.resolve(__dirname, '../lib'),
9695
filename: `index.js`,
97-
library: `MarkdownInput`,
96+
library: `ReactDates`,
9897
libraryTarget: 'umd'
9998
},
10099
devtool: IS_PRODUCTION_MODE ? false : 'inline-source-map',
@@ -112,8 +111,8 @@ module.exports = {
112111
module: {
113112
rules: [
114113
{
115-
test : /\.(png|jpg|jpeg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
116-
use : ['file-loader']
114+
test: /\.(png|jpg|jpeg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
115+
use: ['file-loader']
117116
},
118117
{
119118
test: /\.md$/,

package.json

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
"scripts": {
1616
"link-mode": "cross-env NODE_ENV=link webpack --config ./config/webpack.config.js",
1717
"lint": "eslint src",
18+
"lint-fix": "eslint src --fix",
1819
"start": "cross-env NODE_ENV=development && showroom-scan src && babel-node www/index",
1920
"test": "mocha src/**/*.spec.js --compilers js:babel-register --require config/test/mocha-setup.js --require ignore-styles",
20-
"npm-build": "rimraf lib && cross-env NODE_ENV=production webpack --config ./config/webpack.config.js",
21+
"npm-build": "rimraf lib && cross-env NODE_ENV=production WEBPACK_BUNDLE_ANALYZE=true webpack --config ./config/webpack.config.js",
2122
"npm-publish": "npm run npm-build && npm publish",
2223
"publish-release": "npm run npm-publish"
2324
},
@@ -36,6 +37,15 @@
3637
"react": "^15.6.2 || ^16.2.0",
3738
"react-dom": "^15.6.2 || ^16.2.0"
3839
},
40+
"dependencies": {
41+
"@opuscapita/i18n": "1.2.5",
42+
"@opuscapita/react-autocompletes": "3.0.1",
43+
"dayjs": "1.6.4",
44+
"lodash": "4.17.4",
45+
"prop-types": "15.6.0",
46+
"react-day-picker": "6.1.0",
47+
"react-portal": "4.1.2"
48+
},
3949
"devDependencies": {
4050
"@opuscapita/npm-scripts": "2.0.0-beta.2",
4151
"@opuscapita/react-showroom-client": "1.3.0-beta.6",
@@ -68,7 +78,6 @@
6878
"json-loader": "0.5.4",
6979
"less": "2.7.2",
7080
"less-loader": "2.2.3",
71-
"lodash": "4.17.4",
7281
"lodash-webpack-plugin": "0.11.4",
7382
"mocha": "3.3.0",
7483
"postcss-loader": "1.3.3",
@@ -88,13 +97,5 @@
8897
"webpack-dev-middleware": "1.10.2",
8998
"webpack-node-externals": "1.6.0",
9099
"write-file-webpack-plugin": "4.1.0"
91-
},
92-
"dependencies": {
93-
"@opuscapita/react-autocompletes": "2.0.3",
94-
"lodash": "4.17.4",
95-
"moment": "2.18.1",
96-
"prop-types": "15.6.0",
97-
"react-day-picker": "6.1.0",
98-
"react-portal": "4.1.2"
99100
}
100101
}

src/client/components/DateInput/DateInput.DOCUMENTATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Based on configured to OpusCapita defaults [react-day-picker](https://github.com
4747
<DateInput
4848
value={_scope.state.value}
4949
dateFormat="dd/MM/yyyy"
50-
locale="hu"
50+
locale="fi"
5151
onBlur={(e) => console.log('Blur!', e)}
5252
onChange={_scope.handleChange.bind(_scope)}
5353
onFocus={(e) => console.log('Focus!', e)}

src/client/components/DateInput/DateInput.react.js

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,15 @@ import DayPicker from '../DayPicker';
66
import DateVariants from '../DateVariants';
77
import InputAddonButton from '../InputAddonButton';
88
import { spring, presets, Motion } from 'react-motion';
9-
import assign from 'lodash/assign';
10-
import moment from '../moment';
9+
import dayjs from '../../dayjs';
1110
import getMessage from '../translations';
1211
import isEqual from 'lodash/isEqual';
1312
import { Portal } from 'react-portal';
14-
import { getCoords } from '../utils/get-coords';
13+
import { getCoords, splitProps } from '../utils';
1514

1615
let springPreset = presets.gentle;
1716
let easeOutCubic = (t) => (--t) * t * t + 1; // eslint-disable-line no-param-reassign
1817

19-
function splitProps(props, specificPropNames = []) {
20-
let result = Object.keys(props).reduce((result, propName) => {
21-
let isPropSpecific = specificPropNames.indexOf(propName) >= 0;
22-
if (isPropSpecific) {
23-
let commonProps = assign({}, result[0]);
24-
let specificProps = assign({}, result[1], { [propName]: props[propName] });
25-
return [commonProps, specificProps];
26-
}
27-
28-
let commonProps = assign({}, result[0], { [propName]: props[propName] });
29-
let specificProps = assign({}, result[1]);
30-
return [commonProps, specificProps];
31-
}, [{}, {}]);
32-
33-
return result;
34-
}
35-
36-
3718
let propTypes = {
3819
className: PropTypes.string,
3920
dateFormat: PropTypes.string,
@@ -70,15 +51,15 @@ let defaultProps = {
7051
variants: [
7152
{
7253
getLabel: (locale) => getMessage(locale, 'yesterday'),
73-
getValue: (locale) => moment().locale(locale).subtract(1, 'days').toDate()
54+
getValue: (locale) => dayjs().locale(locale).subtract(1, 'days').toDate()
7455
},
7556
{
7657
getLabel: (locale) => getMessage(locale, 'today'),
77-
getValue: (locale) => moment().locale(locale).toDate()
58+
getValue: (locale) => dayjs().locale(locale).toDate()
7859
},
7960
{
8061
getLabel: (locale) => getMessage(locale, 'tomorrow'),
81-
getValue: (locale) => moment().locale(locale).add(1, 'days').toDate()
62+
getValue: (locale) => dayjs().locale(locale).add(1, 'days').toDate()
8263
}
8364
]
8465
};
@@ -249,7 +230,7 @@ class DateInput extends Component {
249230

250231
let { error, showPicker, showVariants } = this.state;
251232

252-
let momentCompatibleDateFormat = dateFormat.replace(/d/g, 'D').replace(/y/g, 'Y');
233+
let dayjsCompatibleDateFormat = dateFormat.replace(/d/g, 'D').replace(/y/g, 'Y');
253234

254235
let splittedProps = splitProps(restProps, Object.keys(DayPicker.propTypes));
255236
let dayPickerSpecificProps = splittedProps[1];
@@ -368,7 +349,7 @@ class DateInput extends Component {
368349
>
369350
<div className={`opuscapita_date-input__input-container`}>
370351
<DateInputField
371-
dateFormat={momentCompatibleDateFormat}
352+
dateFormat={dayjsCompatibleDateFormat}
372353
disabled={disabled}
373354
onBlur={this.handleBlur}
374355
onChange={this.handleDateChange}

src/client/components/DateInputField/DateInputField.react.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import PropTypes from 'prop-types';
22
import React, { Component } from 'react';
3-
import moment from '../moment';
3+
import DateConverter from '@opuscapita/i18n/lib/converters/DateConverter';
4+
import dayjs from '../../dayjs';
45
import './DateInputField.less';
56

67
let propTypes = {
@@ -30,13 +31,13 @@ class DateInputField extends Component {
3031
constructor(props) {
3132
super(props);
3233
this.state = {
33-
inputValue: props.value ? moment(props.value.toISOString()).format(props.dateFormat) : ''
34+
inputValue: props.value ? dayjs(props.value.toISOString()).format(props.dateFormat) : ''
3435
};
3536
}
3637

3738
componentWillReceiveProps(nextProps) {
3839
if (this.props.value !== nextProps.value || this.props.dateFormat !== nextProps.dateFormat) {
39-
let inputValue = nextProps.value ? moment(nextProps.value.toISOString()).format(nextProps.dateFormat) : '';
40+
let inputValue = nextProps.value ? dayjs(nextProps.value.toISOString()).format(nextProps.dateFormat) : '';
4041
this.setState({ inputValue });
4142
}
4243
}
@@ -46,14 +47,14 @@ class DateInputField extends Component {
4647
};
4748

4849
validate(dateString, dateFormat) {
49-
let momentDate = moment(dateString, dateFormat, true);
50-
let error = momentDate.isValid() ? null : momentDate.invalidAt();
51-
52-
if (error !== null && dateString.length) {
53-
this.props.onError(error);
54-
} else {
55-
let value = !dateString.length ? null : momentDate.toDate();
50+
const i18nCompatibleFormat = dateFormat.replace(/D/g, 'd').replace(/Y/g, 'y');
51+
const dc = new DateConverter(i18nCompatibleFormat);
52+
try {
53+
const date = dc.stringToValue(dateString);
54+
const value = !dateString.length ? null : date;
5655
this.props.onChange(value);
56+
} catch (err) {
57+
this.props.onError(err.message);
5758
}
5859
}
5960

src/client/components/DatePicker/DatePicker.react.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,13 @@ import React, { Component } from 'react';
33
import './DatePicker.less';
44
import DayPicker from '../DayPicker';
55
import { spring, presets, Motion } from 'react-motion';
6-
import assign from 'lodash/assign';
76
import isEqual from 'lodash/isEqual';
87
import { Portal } from 'react-portal';
9-
import { getCoords } from '../utils/get-coords';
8+
import { getCoords, splitProps } from '../utils';
109

1110
let springPreset = presets.gentle;
1211
let easeOutCubic = (t) => (--t) * t * t + 1; // eslint-disable-line no-param-reassign
1312

14-
function splitProps(props, specificPropNames = []) {
15-
let result = Object.keys(props).reduce((result, propName) => {
16-
let isPropSpecific = specificPropNames.indexOf(propName) >= 0;
17-
if (isPropSpecific) {
18-
let commonProps = assign({}, result[0]);
19-
let specificProps = assign({}, result[1], { [propName]: props[propName] });
20-
return [commonProps, specificProps];
21-
}
22-
23-
let commonProps = assign({}, result[0], { [propName]: props[propName] });
24-
let specificProps = assign({}, result[1]);
25-
return [commonProps, specificProps];
26-
}, [{}, {}]);
27-
28-
return result;
29-
}
30-
3113
let propTypes = {
3214
className: PropTypes.string,
3315
disabled: PropTypes.bool,

0 commit comments

Comments
 (0)