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

refactor: optimize bundle size with isolated modules #1839

Merged
merged 47 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e53ac42
reimplement lodash as custom utils
saurabhdaware Nov 18, 2023
3d00f19
fix: build error
saurabhdaware Nov 18, 2023
734f218
fix: isEmpty implementation
saurabhdaware Nov 19, 2023
4b68e60
fix: get function
saurabhdaware Nov 19, 2023
ffedda3
fix: broken types
saurabhdaware Nov 19, 2023
79df5cb
feat: add bundling changes
saurabhdaware Nov 20, 2023
ba0158b
Merge branch 'rip-lodash' of github.com:razorpay/blade into rollup-pls
saurabhdaware Nov 20, 2023
9f21eec
chore: wip test
anuraghazra Nov 21, 2023
ed77d7d
feat: isolate modules & isolate types
anuraghazra Nov 23, 2023
4261a5a
chore: update examples
anuraghazra Nov 23, 2023
a117f41
chore: lib root
anuraghazra Nov 24, 2023
7baf202
chore: update lock
anuraghazra Nov 24, 2023
72a542a
fix: nodenext type resolution
anuraghazra Nov 28, 2023
55a3cb2
chore: prod and dev bundles
anuraghazra Nov 28, 2023
117c282
fix: native bundle
anuraghazra Nov 29, 2023
b48d07b
chore: add gitignore
anuraghazra Nov 29, 2023
f8ef0cb
chore: update packagejson
anuraghazra Nov 30, 2023
2d36f14
Merge remote-tracking branch 'origin' into anu/bundle-optimize-wip
anuraghazra Nov 30, 2023
edfe95d
fix: table related deps
anuraghazra Dec 1, 2023
8c2afb9
chore: update packagejson deps
anuraghazra Dec 3, 2023
02c1d9c
chore: update lock file
anuraghazra Dec 3, 2023
0a9c288
chore: add css generation back
anuraghazra Dec 4, 2023
6da27a7
fix: dependencies
anuraghazra Dec 5, 2023
4bb6f00
chore: lock update
anuraghazra Dec 5, 2023
7b75c7d
chore: move reanimated to peer dep
anuraghazra Dec 6, 2023
d5beca1
chore: update entry point
anuraghazra Dec 6, 2023
bafefd9
chore: update vite example
anuraghazra Dec 6, 2023
a071df9
chore: update basic example
anuraghazra Dec 6, 2023
8f369bf
chore: update docs
anuraghazra Dec 6, 2023
a3a6a4f
chore: move rn deps to peer
anuraghazra Dec 11, 2023
d3e22cb
chore: update lock
anuraghazra Dec 11, 2023
0ca8d47
chore: update docs
anuraghazra Dec 11, 2023
5e11a0d
Merge remote-tracking branch 'origin/master' into anu/bundle-optimize…
anuraghazra Dec 11, 2023
e2e4f73
Create weak-adults-dance.md
anuraghazra Dec 11, 2023
537043f
chore: fix bad imports
anuraghazra Dec 11, 2023
8e0e164
Merge branch 'anu/bundle-optimize-wip' of https://github.com/razorpay…
anuraghazra Dec 11, 2023
b87b285
chore: reexport useTheme from utils
anuraghazra Dec 11, 2023
c67e99e
chore: fix examples
anuraghazra Dec 11, 2023
b573db9
chore: fix examples
anuraghazra Dec 11, 2023
11e61a5
chore: added test for utils
anuraghazra Dec 11, 2023
cdf3e95
chore: fix eslint
anuraghazra Dec 11, 2023
d94f9ed
chore: fix lint
anuraghazra Dec 11, 2023
50af723
chore: remove bundlemon
anuraghazra Dec 12, 2023
c9b5a21
chore: remove build.sh file
anuraghazra Dec 13, 2023
c83fff4
chore: add migration doc
anuraghazra Dec 13, 2023
dae76a6
chore: update module name mapper changelog
anuraghazra Dec 13, 2023
07deaa3
Merge remote-tracking branch 'origin' into anu/bundle-optimize-wip
anuraghazra Dec 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .changeset/weak-adults-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
"@razorpay/blade": minor
---

feat(blade): optimize bundle size with isolated modules & enable codesplitting

**Migration:**

## Jest

**transformIgnorePatterns:**

In your jest config's [`transformIgnorePatterns`](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring) add `@table-library` so that it gets transpiled by jest.

```diff
// jest.config.js
transformIgnorePatterns: [
- '/node_modules/(?!(@razorpay/blade|commander)|uuid|@babel/runtime/)',
+ '/node_modules/(?!(@razorpay/blade|commander)|uuid|@babel/runtime|@table-library/)',
],
```

**moduleNameMapper:**

In your jest config's [`moduleNameMapper`](https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring), you can remove the aliased blade modules:

This is present in [x](https://github.com/razorpay/x/blob/master/jest.config.js#L49-L51), [frontend-website](https://github.com/razorpay/frontend-website/blob/master/jest.config.js#L14-L16) & [admin-dashboard](https://github.com/razorpay/admin-dashboard/blob/master/jest.config.js#L14-L16) repo.

```diff
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
- '@razorpay/blade/tokens': '@razorpay/blade/build/tokens/index.development.web.js',
- '@razorpay/blade/utils': '@razorpay/blade/build/utils/index.development.web.js',
- '@razorpay/blade/components': '@razorpay/blade/build/components/index.development.web.js',
},
```

## Third Party Libs

While this change is not a breaking change, but we've made a few changes in how the dependencies are handled by blade internally.

- Web:

In web, we've marked all the dependencies as `external`, that means you don't need to install the peer dependencies manually,
If you have `@floating-ui/react` in your `package.json` you can safely remove it, yarn/npm will automatically install the appropriate version for you.

- Native:

In native, we've marked all the dependencies as peerDependencies, so that web consumers doesn't have to install them + ensures there are no mismatches between blade vs consumer dependencies.
Please refer to the [installation guide](https://blade.razorpay.com/?path=/docs/guides-installation--page#-add-blade-to-your-application)https://blade.razorpay.com/?path=/docs/guides-installation--page#-add-blade-to-your-application for more details.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ coverage
**/storybook-site
**/build
packages/blade/components.js
packages/blade/components.native.js
packages/blade/components.d.ts
packages/blade/tokens.js
packages/blade/tokens.native.js
packages/blade/tokens.d.ts
packages/blade/utils.js
packages/blade/utils.native.js
packages/blade/utils.d.ts


Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/blade-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ jobs:
- name: Run TypeScript Checks
run: yarn typecheck
working-directory: packages/blade
- name: Check Bundle Size
run: yarn bundlemon
working-directory: packages/blade
env:
CI_COMMIT_SHA: ${{github.event.pull_request.head.sha || github.sha}}
- name: Check Tree Shaking
run: yarn size-limit
working-directory: packages/blade
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ coverage
**/storybook-site
**/build
packages/blade/components.js
packages/blade/components.native.js
saurabhdaware marked this conversation as resolved.
Show resolved Hide resolved
packages/blade/components.d.ts
packages/blade/tokens.js
packages/blade/tokens.native.js
packages/blade/tokens.d.ts
packages/blade/utils.js
packages/blade/utils.native.js
packages/blade/utils.d.ts

# misc
Expand Down
18 changes: 16 additions & 2 deletions packages/blade/.storybook/react-native/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,23 @@ const getStories = () => {
'./src/components/SkipNav/SkipNav.stories.tsx': require('../../src/components/SkipNav/SkipNav.stories.tsx'),
'./src/components/Spinner/BaseSpinner/BaseSpinner.stories.tsx': require('../../src/components/Spinner/BaseSpinner/BaseSpinner.stories.tsx'),
'./src/components/Spinner/Spinner/Spinner.stories.tsx': require('../../src/components/Spinner/Spinner/Spinner.stories.tsx'),
'./src/components/SpotlightPopoverTour/Tour.stories.tsx': require('../../src/components/SpotlightPopoverTour/Tour.stories.tsx'),
'./src/components/SpotlightPopoverTour/docs/Tour.stories.tsx': require('../../src/components/SpotlightPopoverTour/docs/Tour.stories.tsx'),
'./src/components/SpotlightPopoverTour/docs/TourDocs.stories.tsx': require('../../src/components/SpotlightPopoverTour/docs/TourDocs.stories.tsx'),
'./src/components/Switch/Switch.stories.tsx': require('../../src/components/Switch/Switch.stories.tsx'),
'./src/components/Table/docs/Table.stories.tsx': require('../../src/components/Table/docs/Table.stories.tsx'),
'./src/components/Table/docs/APIStories/TableAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableBodyAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableBodyAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableCellAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableCellAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableFooterAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableFooterAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableFooterCellAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableFooterCellAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableFooterRowAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableFooterRowAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableHeaderAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableHeaderAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableHeaderCellAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableHeaderCellAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableHeaderRowAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableHeaderRowAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TablePaginationAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TablePaginationAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableRowAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableRowAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableToolbarActionsAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableToolbarActionsAPI.stories.tsx'),
'./src/components/Table/docs/APIStories/TableToolbarAPI.stories.tsx': require('../../src/components/Table/docs/APIStories/TableToolbarAPI.stories.tsx'),
'./src/components/Table/docs/BasicTable.stories.tsx': require('../../src/components/Table/docs/BasicTable.stories.tsx'),
'./src/components/Table/docs/TableExamples.stories.tsx': require('../../src/components/Table/docs/TableExamples.stories.tsx'),
'./src/components/Tabs/Tabs.stories.tsx': require('../../src/components/Tabs/Tabs.stories.tsx'),
'./src/components/Tag/Tag.stories.tsx': require('../../src/components/Tag/Tag.stories.tsx'),
Expand Down
68 changes: 68 additions & 0 deletions packages/blade/dependencies-external-plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Modified from: https://github.com/pmowrer/rollup-plugin-peer-deps-external/blob/master/src/index.js#L3
// eslint-disable-next-line import/no-extraneous-dependencies
import { either } from 'ramda';
const isFunction = (fn) => typeof fn === 'function';

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what did we change in this plugin from the original source?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing, just kept it as is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arre then why did we moved it here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because i cannot import .ts file in this .mjs file without first transpiling it.

/**
* Utility function mapping a Rollup config's `external` option into a function.

* In Rollup, the `external` config option can be provided as "either a function
* that takes an id and returns true (external) or false (not external), or an
* Array of module IDs, or regular expressions to match module IDs, that should
* remain external to the bundle. Can also be just a single ID or regular
* expression." (https://rollupjs.org/guide/en/#external)
*
* An `external` configuration in string/regexp/array format can be represented
* in the function format, but not vice-versa. This utility accepts either format
* and returns the function representation such that we can easily retain the user's
* configuration while simultaneously appending peer dependencies to it.
*
* @param {String|RegExp|Array|Function} external The `external` property from Rollup's config.
* @returns {Function} Function equivalent of the passed in `external`.
*/
function externalToFn(external) {
if (isFunction(external)) {
return external;
} else if (typeof external === 'string') {
return (id) => external === id;
} else if (external instanceof RegExp) {
return (id) => external.test(id);
} else if (Array.isArray(external)) {
return (id) =>
external.some((module) => (module instanceof RegExp ? module.test(id) : module === id));
}
// Per the rollup docs, `undefined` isn't a valid value for the `external` option,
// but it has been reported to have been passed in configs starting with 2.11.0.
// It's unclear why it's happening so we'll support it for now:
// https://github.com/pmowrer/rollup-plugin-peer-deps-external/issues/29
else if (typeof external === 'undefined') {
return () => false;
} else {
throw new Error(
`rollup-plugin-peer-deps-external: 'external' option must be a function or an array.`,
);
}
}

const moduleRegExp = (module) => new RegExp(`^${module}(\\/\.+)*$`);

function getModulesMatcher(modulesNames) {
const regexps = modulesNames.map(moduleRegExp);
return (id) => regexps.some((regexp) => regexp.test(id));
}
function depsExternalPlugin({ externalDependencies } = {}) {
return {
name: 'deps-external',
options: (opts) => {
opts.external = either(
// Retain existing `external` config
externalToFn(opts.external),
getModulesMatcher(externalDependencies),
);

return opts;
},
};
}

export { depsExternalPlugin };
44 changes: 28 additions & 16 deletions packages/blade/docs/guides/Installation.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,40 @@ Blade has a peer dependency on a few libraries, you can skip adding it if you al
> **Note**
>
> Currently, blade only supports styled-components v5 only
- `@floating-ui/react`

```shell
yarn add @razorpay/blade [email protected] @floating-ui/react
yarn add @razorpay/blade [email protected]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@floating-ui/react is no longer a peer dependency?

```
2. Follow [this guide](#-install-fonts) to install the fonts.

3. For **React Native** projects you need to do additional setup for the peer dependencies:

- `react-native-reanimated`
- Follow [this guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) to install it on Android & iOS which is required by Blade.
- `react-native-svg`
- Follow [this guide](https://github.com/react-native-svg/react-native-svg#with-react-native-cli) to install it on Android & iOS which is required by Blade.
- `react-native-gesture-handler`
- Follow [this guide](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) to install it, note that you don't need to add `<GestureHandlerRootView style={{ flex: 1 }}>` again on the root because BladeProvider already adds that out of the box.
- `@gorhom/bottom-sheet`
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up.
- `@gorhom/portal`
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up.
- `@floating-ui/react-native`
- Add this as peer dependency, no need to do additional setup.
- `react-native-pager-view`
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation).
```shell
yarn add @floating-ui/[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] @gorhom/[email protected] @gorhom/[email protected]
```

- `react-native-reanimated`
- Follow [this guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) to install it on Android & iOS which is required by Blade.
- `react-native-svg`
- Follow [this guide](https://github.com/react-native-svg/react-native-svg#with-react-native-cli) to install it on Android & iOS which is required by Blade.
- `react-native-gesture-handler`
- Follow [this guide](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) to install it, note that you don't need to add `<GestureHandlerRootView style={{ flex: 1 }}>` again on the root because BladeProvider already adds that out of the box.
- `@gorhom/bottom-sheet`
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up.
- `@gorhom/portal`
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up.
- `@floating-ui/react-native`
- Add this as peer dependency, no need to do additional setup.
- `react-native-tab-view`
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation).
- `react-native-pager-view`
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation).

And finally run `pod install` command so that blade's RN dependencies are linked to your project:

```shell
cd ios && pod install
```

## 🔜 Add blade libraries to your Figma project

Expand Down
4 changes: 2 additions & 2 deletions packages/blade/docs/tokens/Border.stories.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Meta, DocsContainer } from '@storybook/addon-docs';
import { BladeProvider } from '../../src/components';
import { makeBorderSize, useTheme } from '../../src/utils';
import { BladeProvider, useTheme } from '../../src/components';
import { makeBorderSize } from '../../src/utils';
import { paymentTheme, bankingTheme } from '../../src/tokens';

<Meta
Expand Down
Loading
Loading