Reputation: 48709
npm allows us to specify bundleDependencies
, but what are the advantages of doing so? I guess if we want to make absolutely sure we get the right version even if the module we reference gets deleted, or perhaps there is a speed benefit with bundling?
Anyone know the advantages of bundledDependencies
over normal dependencies?
Upvotes: 114
Views: 73401
Reputation: 413
The bundleDependencies
field allows you to specify internal dependencies (application components) and then require()
them in your app as if they were independent modules instead of cluttering your lib or publishing them to npm.
If/when they are matured to the point they could live as separate modules, you can put them on npm easily without modifying your code.
Upvotes: 25
Reputation: 131
Suppose you're using pnpm to manage a monorepo and you have a utils folder. To access this folder, you could do one of the following (the last option uses bundledDependencies
):
tsconfig.json
. BUT, this will break if you define another tsconfig.json
in a child package that also uses "paths" (the alias option)bundledDependencies
to maintain a private and local utils package that users will never be able to download from npm but you'll still be able to use them in your public packages. This way you also get to reference it by its name instead of the relative pathOf course, the solution may not always be to use bundledDependencies
, every problem has its own specific requirements, but I find bundledDependencies
to be very useful for that particular use case that happens often with monorepos.
Upvotes: 2
Reputation: 18005
For the quick reader : this QA is about the package.json bundledDependencies field, not about the package.
"bundledDependencies" are exactly what their name implies. Dependencies that should be inside your project. So the functionality is basically the same as normal dependencies. They will also be packed when running npm pack
.
Normal dependencies are usually installed from the npm registry. Thus bundled dependencies are useful when:
This way, you don't have to create (and maintain) your own npm repository, but get the same benefits that you get from npm packages.
When developing, I don't think that the main point is to prevent accidental updates though. We have better tools for that, namely code repositories (git, mercurial, svn...) or now lock files.
To pin your package versions, you can use:
Option1: Use the newer NPM version 5 that comes with node 8. It uses a package-lock.json
file (see the node blog and the node 8 release)
Option2: use yarn instead of npm
.
It is a package manager from facebook, faster than npm
and it uses a yarn.lock
file. It uses the same package.json
otherwise.
This is comparable to lockfiles in other package managers like Bundler or Cargo. It’s similar to npm’s npm-shrinkwrap.json, however it’s not lossy and it creates reproducible results.
npm
actually copied that feature from yarn
, amongst other things.
npm shrinkwrap
most of the time, and sometimes put the whole thing, including the node_module folder, into your code repository. Or possibly use shrinkpack. The best practices at the time were discussed on the node.js blog and on the joyent developer websites.This is a bit outside the scope of the question, but I'd like to mention the last kind of dependencies (that I know of): peer dependencies. Also see this related SO question and possibly the docs of yarn
on bundledDependencies.
Upvotes: 122
Reputation: 27304
I'm surprised I didn't see this here already, but when carefully selected, bundledDependencies
can be used to produce a distributable package from npm pack
that will run on a system where npm
is not configured. This is helpful if you have e.g. a system that's not networked / not on the internet: bring your package over on a thumb drive (or whatever) and unpack the tarball, then npm run
or node index.js
and it Just Works.
Maybe there's a better way to bundle up your application to run "offline", but if there is I haven't found it.
Upvotes: 6
Reputation: 792
Operationally, I look at bundledDependencies as a module's private module store, where dependencies is more public, resolved among your module and its dependencies (and sub-dependencies). Your module may rely on an older version of, say, react, but a dependency requires latest-and-greatest. Your package/install will result in your pinned version in node_modules/$yourmodule/node_modules/react
, while your dependency will get their version in node_modules/react
(or node_modules/$dependency/node_modules/react
if they're so inclined).
A caveat: I recently ran into a dependency that did not properly configure its dependency on react, and having react in bundledDependencies caused that dependent module to fail at runtime.
Upvotes: 0
Reputation: 4923
One of the biggest problems right now with Node is how fast it is changing. This means that production systems can be very fragile and an npm update
can easily break things.
Using bundledDependencies is a way to get round this issue by ensuring, as you correctly surmise, that you will always deliver the correct dependencies no matter what else may be changing.
You can also use this to bundle up your own, private bundles and deliver them with the install.
Upvotes: 50