diff --git a/.github/workflows/bundle.yml b/.github/workflows/bundle.yml new file mode 100644 index 00000000..ba8c98a6 --- /dev/null +++ b/.github/workflows/bundle.yml @@ -0,0 +1,82 @@ +name: Bundle +on: pull_request +jobs: + bundle_base: + runs-on: ubuntu-latest + outputs: + size: ${{ steps.size.outputs.size }} + strategy: + matrix: + node-version: ['16.15.0'] + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.base_ref }} + - uses: pnpm/action-setup@v2.2.2 + with: + version: 7 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - name: Install dependencies + run: pnpm install + - name: Build + run: pnpm build + - name: Save bundle size + id: size + run: | + echo "::set-output name=size::$(du -s dist/ | awk '{print $1}')" + - name: Publish result + if: ${{ hashFiles('stats.html') != '' }} + run: pnpm dlx surge . https://${{ github.base_ref }}-stats.surge.sh --token ${{ secrets.SURGE_TOKEN }} + + bundle_head: + runs-on: ubuntu-latest + outputs: + size: ${{ steps.size.outputs.size }} + strategy: + matrix: + node-version: ['16.15.0'] + steps: + - uses: actions/checkout@v2 + - uses: pnpm/action-setup@v2.2.2 + with: + version: 7 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - name: Install dependencies + run: pnpm install + - name: Build + run: pnpm build + - name: Save bundle size + id: size + run: | + echo "::set-output name=size::$(du -s dist/ | awk '{print $1}')" + - name: Publish result + if: ${{ hashFiles('stats.html') != '' }} + run: pnpm dlx surge . https://${{ github.head_ref }}-stats.surge.sh --token ${{ secrets.SURGE_TOKEN }} + + compare: + runs-on: ubuntu-latest + needs: [bundle_base, bundle_head] + steps: + - name: Add comment + uses: peter-evans/create-or-update-comment@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.number }} + body: | + Base: [${{needs.bundle_base.outputs.size}}](https://${{ github.base_ref }}-stats.surge.sh/stats.html) + Head: [${{needs.bundle_head.outputs.size}}](https://${{ github.head_ref }}-stats.surge.sh/stats.html) + - name: Compare bundle sizes + run: | + if [ "${{needs.bundle_base.outputs.size}}" -lt "${{needs.bundle_head.outputs.size}}" ]; then + exit 1 + else + exit 0 + fi diff --git a/.gitignore b/.gitignore index 800f3a80..1dd36fa2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # testing /coverage +stats.html # production /build diff --git a/.surgeignore b/.surgeignore new file mode 100644 index 00000000..87b054bf --- /dev/null +++ b/.surgeignore @@ -0,0 +1,2 @@ +* +!stats.html \ No newline at end of file diff --git a/package.json b/package.json index a12dcc24..e3340c5e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "lint:fix": "eslint --max-warnings 0 --fix .", "start": "vite", "build": "vite build", - "test": "vitest" + "test": "vitest", + "visualize": "pnpm run build && open ./stats.html", + "size": "pnpm run build && du -s dist/ | awk '{print $1}'" }, "dependencies": { "@date-io/date-fns": "^1.3.13", @@ -80,6 +82,7 @@ "eslint-plugin-testing-library": "^5.6.0", "jsdom": "^20.0.0", "prettier": "2.4.1", + "rollup-plugin-visualizer": "^5.8.0", "tslint-config-prettier": "^1.18.0", "typescript": "^4.7.4", "vite": "2.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a9d67f9..8b0b263c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,7 @@ specifiers: react-toastify: ^5.5.0 react-window: ^1.8.7 resize-observer-polyfill: ^1.5.1 + rollup-plugin-visualizer: ^5.8.0 shortid: ^2.2.16 tslint-config-prettier: ^1.18.0 typescript: ^4.7.4 @@ -116,6 +117,7 @@ devDependencies: eslint-plugin-testing-library: 5.6.0_qugx7qdu5zevzvxaiqyxfiwquq jsdom: 20.0.0 prettier: 2.4.1 + rollup-plugin-visualizer: 5.8.0_rollup@2.77.3 tslint-config-prettier: 1.18.0 typescript: 4.7.4 vite: 2.7.0 @@ -1650,6 +1652,14 @@ packages: resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} dev: false + /cliui/7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /clsx/1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -1849,6 +1859,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /define-lazy-prop/2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + /define-properties/1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} engines: {node: '>= 0.4'} @@ -1913,6 +1928,10 @@ packages: /electron-to-chromium/1.4.217: resolution: {integrity: sha512-iX8GbAMij7cOtJPZo02CClpaPMWjvN5meqXiJXkBgwvraNWTNH0Z7F9tkznI34JRPtWASoPM/xWamq3oNb49GA==} + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + /emojis-list/2.1.0: resolution: {integrity: sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==} engines: {node: '>= 0.10'} @@ -2693,6 +2712,11 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + /get-func-name/2.0.0: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} dev: true @@ -2950,11 +2974,22 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + /is-extglob/2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -3023,6 +3058,13 @@ packages: call-bind: 1.0.2 dev: true + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + /isexe/2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -3394,6 +3436,15 @@ packages: dependencies: wrappy: 1.0.2 + /open/8.4.0: + resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + /optionator/0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -3794,6 +3845,11 @@ packages: resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==} dev: false + /require-directory/2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + /resize-observer-polyfill/1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} dev: false @@ -3838,6 +3894,20 @@ packages: dependencies: glob: 7.2.3 + /rollup-plugin-visualizer/5.8.0_rollup@2.77.3: + resolution: {integrity: sha512-pY6j/7qHz5I9rB7d/bQoA5gX+2FbV3MBG055wrsFxDn550bgl0FNViRj6wDHh85PMswv+JVdZjhnMBzz/hdAHA==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: ^2.0.0 + dependencies: + nanoid: 3.3.4 + open: 8.4.0 + rollup: 2.77.3 + source-map: 0.7.4 + yargs: 17.5.1 + dev: true + /rollup/2.77.3: resolution: {integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==} engines: {node: '>=10.0.0'} @@ -3932,6 +4002,11 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + /source-map/0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} dev: false @@ -3946,6 +4021,15 @@ packages: engines: {node: '>=4'} dev: false + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + /string.prototype.matchall/4.0.7: resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==} dependencies: @@ -4357,6 +4441,15 @@ packages: engines: {node: '>=0.10.0'} dev: true + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -4386,6 +4479,11 @@ packages: resolution: {integrity: sha512-C9A3esyOuw/xRpwQUkG2e1Gjd8sZYh42t66COq8DaJgaaLOqmE8zWRH1ouL9mHtQ3WV//uT5Ki3ijHGSUdLiww==} dev: false + /y18n/5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true @@ -4395,6 +4493,24 @@ packages: engines: {node: '>= 6'} dev: false + /yargs-parser/21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs/17.5.1: + resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==} + engines: {node: '>=12'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/vite.config.ts b/vite.config.ts index 9361dc91..d38cf3a9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,10 @@ /// import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; +import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ - plugins: [react()], + plugins: [react(), visualizer()], test: { globals: true, environment: 'jsdom',