From 84a57a01b6a643461f80e8c1ed8a1cfa7ef86fa8 Mon Sep 17 00:00:00 2001 From: Hossein Dehnokhalaji Date: Mon, 20 Apr 2020 14:18:19 +0100 Subject: [PATCH] Reduce bundle size (#252) * Add cross-env to fix windows build * Use clsx intead of classnames * Add babel-plugin-optimize-clsx * Drop mui v3 support * Remove redundant * Fixes #251 - Fix bug with custom variant classes prop --- .babelrc | 1 + CHANGELOG.md | 18 ++- package-lock.json | 188 ++++++++++++++++++++++++-- package.json | 9 +- src/SnackbarContainer.tsx | 4 +- src/SnackbarItem/SnackbarItem.tsx | 34 ++--- src/SnackbarItem/SnackbarItem.util.ts | 8 +- src/SnackbarProvider.tsx | 3 - 8 files changed, 219 insertions(+), 46 deletions(-) diff --git a/.babelrc b/.babelrc index d7b09b8b..a2d6052c 100644 --- a/.babelrc +++ b/.babelrc @@ -5,6 +5,7 @@ "@babel/preset-react" ], "plugins": [ + "babel-plugin-optimize-clsx", "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-object-rest-spread" ], diff --git a/CHANGELOG.md b/CHANGELOG.md index 9748a6fa..82b30836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,27 @@ Thanks to all contributers who improved notistack by opening an issue/PR. -### `notistack@0.9.10` +### `notistack@0.9.12` ###### to be published * **@pctestjfarz**: Add swipe to dismiss feature [#138](https://github.com/iamhosseindhv/notistack/issues/138) * **@molynerd**: Add support to update content of snackbar in place [#50](https://github.com/iamhosseindhv/notistack/issues/50) * **@david-chau**: Allow `asc`, `desc` or custom sort order of snackbars [#160](https://github.com/iamhosseindhv/notistack/issues/160) +
+ +### `notistack@0.9.11` +###### April 20, 2020 +* **@mehmetkose @andrewmclagan @oliviertassinari @merceyz**: Reduce Bundle size by using `clsx` instead of `classnames`, Use `babel-plugin-optimize-clsx` [#163](https://github.com/iamhosseindhv/notistack/issues/163) +* **@kikoanis** Fix bug with custom variant `classes` [#251](https://github.com/iamhosseindhv/notistack/issues/251) +* Drop support for Material UI v3 + + + +
+ +### `notistack@0.9.10` +###### April 17, 2020 +* Migrate codebase to typescript. +
diff --git a/package-lock.json b/package-lock.json index 5c0c5f80..b144cdad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2258,6 +2258,12 @@ "@babel/types": "7.0.0-beta.44" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", @@ -3822,12 +3828,6 @@ "react-is": "^16.8.0" } }, - "@types/classnames": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz", - "integrity": "sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==", - "dev": true - }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -4100,6 +4100,15 @@ } } }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4216,6 +4225,81 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-optimize-clsx": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-optimize-clsx/-/babel-plugin-optimize-clsx-2.6.0.tgz", + "integrity": "sha512-FizJqgyoj8EG3Y3F+BLxB+0rxDb9AFfh826ob4e70SXMxOcmibpi/8RiEHQ2FbGt/2PF6k2128dZ1xVQ4f1JNA==", + "dev": true, + "requires": { + "@babel/generator": "^7.6.2", + "@babel/template": "^7.6.0", + "@babel/types": "^7.6.1", + "lodash": "^4.17.15", + "object-hash": "^1.3.1" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -4369,6 +4453,17 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -4400,11 +4495,6 @@ } } }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" - }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -4423,8 +4513,7 @@ "clsx": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz", - "integrity": "sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==", - "dev": true + "integrity": "sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==" }, "collection-visit": { "version": "1.0.0", @@ -4541,6 +4630,58 @@ "dev": true, "optional": true }, + "cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", + "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -6761,6 +6902,12 @@ } } }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "dev": true + }, "object-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", @@ -7926,6 +8073,15 @@ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -8005,6 +8161,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", diff --git a/package.json b/package.json index 8bc4286f..5e450966 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "scripts": { "types": "tsc", - "build": "NODE_ENV=production BABEL_ENV=production babel src -d build --copy-files --extensions \".js,.ts,.tsx\"", + "build": "cross-env NODE_ENV=production BABEL_ENV=production babel src -d build --copy-files --extensions \".js,.ts,.tsx\"", "prebuild": "rimraf build && npm run docs", "prepublishOnly": "npm run build", "docs": "rimraf typedoc.json && typedoc --tsconfig", @@ -26,7 +26,7 @@ "peerDependencies": { "react": "^16.8.0", "react-dom": "^16.8.0", - "@material-ui/core": "^3.2.0 || ^4.0.0" + "@material-ui/core": "^4.0.0" }, "devDependencies": { "@babel/cli": "^7.8.4", @@ -37,7 +37,6 @@ "@babel/preset-react": "^7.8.3", "@babel/preset-typescript": "^7.8.3", "@material-ui/core": "^4.9.5", - "@types/classnames": "^2.2.10", "@types/node": "^13.9.0", "@types/react": "^16.9.23", "@types/react-dom": "^16.9.5", @@ -45,7 +44,9 @@ "@typescript-eslint/eslint-plugin": "^2.22.0", "@typescript-eslint/parser": "^2.22.0", "babel-eslint": "^8.2.6", + "babel-plugin-optimize-clsx": "^2.6.0", "babel-runtime": "^6.26.0", + "cross-env": "^7.0.2", "eslint": "^6.1.0", "eslint-config-airbnb": "~16.1.0", "eslint-plugin-import": "~2.9.0", @@ -58,7 +59,7 @@ "typescript": "^3.8.3" }, "dependencies": { - "classnames": "^2.2.6", + "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0", "react-is": "^16.8.6" }, diff --git a/src/SnackbarContainer.tsx b/src/SnackbarContainer.tsx index 4001ec84..dee9bc32 100644 --- a/src/SnackbarContainer.tsx +++ b/src/SnackbarContainer.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import classNames from 'classnames'; +import clsx from 'clsx'; import { makeStyles } from '@material-ui/core/styles'; import { SNACKBAR_INDENTS } from './utils/constants'; import { SnackbarProviderProps } from '.'; @@ -57,7 +57,7 @@ const SnackbarContainer: React.FC = (props) => { const classes = useStyle(); const { className, anchorOrigin, dense, ...other } = props; - const combinedClassname = classNames( + const combinedClassname = clsx( classes.root, classes[anchorOrigin.vertical], classes[anchorOrigin.horizontal], diff --git a/src/SnackbarItem/SnackbarItem.tsx b/src/SnackbarItem/SnackbarItem.tsx index a2894d9a..862e9ba5 100644 --- a/src/SnackbarItem/SnackbarItem.tsx +++ b/src/SnackbarItem/SnackbarItem.tsx @@ -1,17 +1,17 @@ -import React, { useState, useEffect, useRef, memo } from 'react'; -import classNames from 'classnames'; -import { makeStyles } from '@material-ui/core/styles'; -import Snackbar, { SnackbarClassKey } from '@material-ui/core/Snackbar'; +import React, { useState, useEffect, useRef } from 'react'; +import clsx from 'clsx'; +import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; +import Snackbar from '@material-ui/core/Snackbar'; import Slide from '@material-ui/core/Slide'; import Collapse from '@material-ui/core/Collapse'; import SnackbarContent from '@material-ui/core/SnackbarContent'; import { getTransitionDirection, omitNonMuiKeys, omitNonCollapseKeys } from './SnackbarItem.util'; import { capitalise, allClasses, REASONS, SNACKBAR_INDENTS } from '../utils/constants'; -import { SnackbarProviderProps, OptionalBy, SnackbarKey, CloseReason, SharedProps, RequiredBy, IconVariant, ClassNameMap, VariantClassKey } from '../index'; +import { SnackbarProviderProps, OptionalBy, SnackbarKey, CloseReason, SharedProps, RequiredBy, IconVariant, VariantClassKey } from '../index'; import { Snack } from '../SnackbarProvider'; - -const useStyle = makeStyles(theme => ({ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +const styles = (theme: Theme) => createStyles({ ...allClasses.mui, base: { fontSize: '0.875rem', @@ -49,10 +49,8 @@ const useStyle = makeStyles(theme => ({ }, collapseContainer: { [theme.breakpoints.down('xs')]: { - // @ts-ignore support for material-ui v3. soon to be removed - paddingLeft: typeof theme.spacing === 'function' ? theme.spacing(1) : theme.spacing.unit, - // @ts-ignore - paddingRight: typeof theme.spacing === 'function' ? theme.spacing(1) : theme.spacing.unit, + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), }, }, collapseWrapper: { @@ -64,7 +62,7 @@ const useStyle = makeStyles(theme => ({ marginTop: SNACKBAR_INDENTS.snackbar.dense, marginBottom: SNACKBAR_INDENTS.snackbar.dense, }, -})); +}); type RemovedProps = @@ -76,18 +74,16 @@ type RemovedProps = | 'preventDuplicate' -export interface SnackbarItemProps extends RequiredBy, 'onEntered' | 'onExited' | 'onClose'> { +export interface SnackbarItemProps extends WithStyles, RequiredBy, 'onEntered' | 'onExited' | 'onClose'> { snack: Snack; - classes: Partial>; dense: SnackbarProviderProps['dense']; iconVariant: OptionalBy; hideIconVariant: SnackbarProviderProps['hideIconVariant']; } -const SnackbarItem: React.FC = (props) => { +const SnackbarItem: React.FC = ({ classes, ...props }) => { const timeout = useRef>(); const [collapsed, setCollapsed] = useState(true); - const classes = useStyle(); useEffect(() => (): void => { if (timeout.current) { @@ -221,10 +217,10 @@ const SnackbarItem: React.FC = (props) => { > {snackContent || ( = (props) => { ); }; -export default memo(SnackbarItem); +export default withStyles(styles)(SnackbarItem); diff --git a/src/SnackbarItem/SnackbarItem.util.ts b/src/SnackbarItem/SnackbarItem.util.ts index 05cec0fc..d46f50f9 100644 --- a/src/SnackbarItem/SnackbarItem.util.ts +++ b/src/SnackbarItem/SnackbarItem.util.ts @@ -1,4 +1,4 @@ -import classNames from 'classnames'; +import clsx from 'clsx'; import { SnackbarProps } from '@material-ui/core/Snackbar'; import { allClasses } from '../utils/constants'; import { SnackbarItemProps } from './SnackbarItem'; @@ -29,14 +29,14 @@ export const omitNonMuiKeys: (classes: { wrappedRoot: string } & SnackbarProps[' return { ...snackbarMuiClasses, - root: classNames(classes.root, classes.wrappedRoot), + root: clsx(classes.root, classes.wrappedRoot), }; }; /** * Omit all class keys except what we need for collapse component */ -export const omitNonCollapseKeys = (classes: { collapseContainer: string; collapseWrapper: string; collapseWrapperDense: string }, dense: SnackbarItemProps['dense']): { container: string; wrapper: string } => ({ +export const omitNonCollapseKeys = (classes: SnackbarItemProps['classes'], dense: SnackbarItemProps['dense']): { container: string; wrapper: string } => ({ container: classes.collapseContainer, - wrapper: classNames(classes.collapseWrapper, { [classes.collapseWrapperDense]: dense }), + wrapper: clsx(classes.collapseWrapper, { [classes.collapseWrapperDense]: dense }), }); diff --git a/src/SnackbarProvider.tsx b/src/SnackbarProvider.tsx index a2d3b768..97ace8e1 100644 --- a/src/SnackbarProvider.tsx +++ b/src/SnackbarProvider.tsx @@ -306,7 +306,4 @@ class SnackbarProvider extends Component { } } -// @ts-ignore // polyfill for Node -const Element = typeof Element === 'undefined' ? function () { } : Element; // eslint-disable-line - export default SnackbarProvider;