inrupt/solid-client-js

package size is very large, bloats dependent projects and gives next.js heartburn

travis opened this issue · 2 comments

Search terms you've used

package, size, rollup

Bug description

When we use this package as a dependency it adds ~100k (after minification and gzipping) to the size of the parent.

We suspect this is related somehow to the fact that this package is 7MB unpacked according to NPM:

https://www.npmjs.com/package/@inrupt/solid-client

We first discovered this while trying to debug failing Next.js builds and have an open ticket there:

vercel/next.js#35602

We've tracked this down to some combination of swrlit, @inrupt/solid-client and @inrupt/solid-client-authn-browser and strongly suspect the issue is with one of the Inrupt libraries. Including @inrupt/solid-client bloats the minified/gzipped CJS package by ~90kB (but not the ESM package!) and including @inrupt/solid-client-authn-browser bloats both the CJS and ESM minified/gzipped packages by ~100kB.

To Reproduce

  1. git clone https://github.com/mysilio-co/swrlit.git
  2. cd swrlit
  3. git checkout debug-big-package
  4. edit src/index.ts and uncomment import "@inrupt/solid-client"
  5. run npm install
  6. run npm run build && npm run size

Expected result

Minified/gzipped package size should be under 10kB

Actual result

Minified/gzipped CJS package size is 92.59 kB

Environment

  System:
    OS: macOS 11.6.4
    CPU: (8) x64 Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz
    Memory: 101.23 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Browsers:
    Brave Browser: 99.1.36.119
    Chrome: 99.0.4844.84
    Firefox: 98.0.2
    Safari: 14.1.2
  npmPackages:
    @babel/core: ^7.12.3 => 7.14.3
    @inrupt/solid-client: ^1.19.0 => 1.19.0
    @inrupt/solid-client-authn-browser: ^1.11.2 => 1.11.2
    @inrupt/vocab-common-rdf: ^1.0.3 => 1.0.3
    @inrupt/vocab-solid-common: ^0.7.5 => 0.7.5
    @size-limit/preset-big-lib: ^7.0.8 => 7.0.8
    @storybook/addon-essentials: ^6.0.28 => 6.2.9
    @storybook/addon-info: ^5.3.21 => 5.3.21
    @storybook/addon-links: ^6.0.28 => 6.1.1
    @storybook/addons: ^6.0.28 => 6.1.1
    @storybook/react: ^6.0.28 => 6.2.9
    @testing-library/react-hooks: ^3.4.2 => 3.4.2
    @types/jest: ^25.2.3 => 25.2.3
    @types/react: ^17.0.30 => 17.0.30
    @types/react-dom: ^17.0.9 => 17.0.9
    @types/url-parse: ^1.4.3 => 1.4.3
    babel-loader: ^8.2.1 => 8.2.2
    dequal: ^2.0.2 => 2.0.2
    molid: ^0.3.0 => 0.3.0
    react: ^17.0.1 => 17.0.2
    react-dom: ^17.0.2 => 17.0.2
    react-is: ^17.0.2 => 17.0.2
    react-test-renderer: ^17.0.2 => 17.0.2
    size-limit: ^7.0.8 => 7.0.8
    swr: ^1.0.1 => 1.0.1
    ts-jest: ^25.5.1 => 25.5.1
    tsdx: ^0.14.1 => 0.14.1
    tslib: ^2.3.1 => 2.3.1
    typedoc: ^0.22.6 => 0.22.6
    typescript: ^4.4.4 => 4.4.4
    url-parse: ^1.4.7 => 1.5.1
    whatwg-fetch: ^3.5.0 => 3.5.0
  npmGlobalPackages:
    corepack: 0.10.0
    npm: 8.1.2
    size-limit: 7.0.8
    tsdx: 0.14.1
    yalc: 1.0.0-pre.53

Additional information

This is a very strange issue - I tried fiddling with the rollup build a bit but didn't have any luck. The Next.js build issue is non-deterministic but seems related to the weight of this dependency. Have been working on debugging this for several days and have tried many things - happy to chat in higher bandwidth if that would be helpful!

Hey @jaredpalmer, any thoughts on what could cause this behaviour from tsdx? I suspect this is related to tree-shaking (our SDKs and all of their dependencies would be quite large if all bundled into a single file — we don't generally recommend this).

But also @travis, it looks like you're using the root import, rather than subpath imports, which is likely inflating the amount of code here.

Just to follow up here, the package size on the npmjs.org website is misleading for understanding how big a package is in your application. The bulk of that 7MB is because our package is including the src directory, instead of just shipping compiled files.

If you're using commonjs, and do require("@inrupt/solid-client") then you get 627KB of unminified javascript (the dist/index.js file)

If you use ESM and do import * as solidClient from "@inrupt/solid-client, then you'll get 4KB of dist/index.mjs plus all the files that file imports; but you can also do import { getSolidDataset } from @inrupt/solid-client/resource/solidDataset` and that'll be much less code to load.

The equivalent here would be importing the entirety of moment.js or another complex library, without tree-shaking out the stuff you don't need. I'm inclined to say this is a tooling problem.