Home > Software engineering >  bundling and publishing an NPM library. Is it common to resolve all dependencies and include them in
bundling and publishing an NPM library. Is it common to resolve all dependencies and include them in

Time:02-27

I've been tasked with the development of a NPM package with a custom component (in this case a react component) that makes uses of other dependencies such as plate, slate, etc.

I'm in the process of preparing the output dist but it's not clear to me what the best practices are when doing so: Should all dependencies be resolved and bundled into a big .js file or this can be ignored ? (I'm using rollup resolve here). I'm afraid this would produce a huge file including the source of all the dependencies but as I stated I'm really not familiar with the process...

In the other hand, is it common NOT to resolve such dependencies and let the final consumer of the component do so ? (I'm only assuming here)

CodePudding user response:

It's all about pros and cons... and what is possible. For example React itself can only exist in one version in an entire project so you should never include that.

Dependencies that are needed but not included should be added as peerDependencies in your package.json and it is the responsibility of the consumer to download them. The downside with including dependencies (as dependencies so that they will be downloaded automatically by the consumer) is that the bundle of the consumer might be bigger than it needs to be. Here you should take into account who will consume it; is it for internal use in your organization or public use? Do you know anything about the context it will be used in? It's best not to include dependencies since it will contribute to smaller resulting bundle for the consumer but if it's unlikely that the depending dependencies are present in the build environment of the consumer, you might as well add it to your package. The situation that you want to avoid is that your package includes a different version of the same package that the consumer is already using; then the resulting bundle may contain two versions of a lot of code that could potentially be reduced to one version (if the version used by the consumer and by your package are compatible). Of course all of this potentially becomes worse and more likely with large common dependencies than with small uncommon dependencies.

An example: in my organization we use Material-UI. We have a package with React components using Material-UI which we consume in other projects. Since Material-UI will always be present in the projects, it's bad practice to include it in the package, even though it will place a higher responsibility on the consumers (us) to align different versions of the package with whatever version of Material-UI that we're using in the applicable project. Given another consumption context, including it in the package might have made more sense.

According to me, you should never bundle your package since it makes tree shaking more complicated for the consumer. This applies to esm packages (cjs is not tree-shakeable). In cjs on the other hand it's devastating with bundled packages since it prevents the consumer from making more specific imports to avoid importing a lot of unused code, e.g.

import Comp from "package/Component"

instead of

import { Comp } from "package"
  • Related