Dependencies
NPM
1. Why is it here?
We developed a component library and encountered a problem while using it. Although we understood that this library should use the consumer environment, we incorrectly used dependencies. Thereby we got a library that cannot be used. So you need to understand how to organize dependencies.
2. A little bit of theory
At the moment, 3 types of dependencies are important for us and section of package.json
:
dependencies
- main dependencies. Dependencies specific to your project. Used directlyin the project code. An important point: if you develop a library using the framework as a dependency, then it has
no place in this section. The library will become part of the ecosystem of another project and will use
its environment. You need to understand exactly why the dependency turned out to be in this section. You also need
to understand how dependency conflicts are resolved: if a specific version of a dependency is specified in
the library, and another version of the same dependency is specified in a project that uses library,
then both versions are installed. As a result we can get non-working app due to non-obvious conflicts and freaky
behaviour.
devDependencies
- dependencies to develop. Everything is simple here. Tools to help us writeand maintain a project. For example: utilities, tools for writing and running tests, module builder.
In general, what should not be in the project after build. These dependencies are not installed
when we use our library in another project.
peerDependencies
- dependencies on which the project is hoping. Here you can see thedependencies and their versions or range of versions with which the project is guaranteed to work
when installed in another project. These dependencies are not installed when we use our library
in another project, but you see warnings if there are no required peer dependencies among
installed ones.
3. Peer dependencies
3.1. How to use?
So now it is clear that some dependencies are needed in peerDependencies
section. These dependencies are not installed when we pull dependencies for the project using npm install
or yarn
commands. Since we need last ones during development and ci process, at the moment, until we find the best option, it is proposed to duplicate peer dependencies in the devDependencies
section.
3.2. Example
core-ui-kit
- library of ui components based on react
. react
is listed in the peerDependencies
section with version 16.7.0 . This means that the library guarantees
its work with this version of react
. Accordingly, it is reasonable for the consumer to use this version in the project.
3.3. What version should we set for peer dependency?
It is not necessary to use a specific version. If we are sure that the library remains working, using a range of React versions, you can specify a range.
4. How to set version number of dependency
4.1. Only concrete version of dependency
If we use some dependency, we should set only concrete version of it. That is unacceptable to use fluent versions (^1.0.4
, ~1.0.4
), that can be accidently updated, among main dependencies (dependencies
) and dev dependencies (devDependencies
). We should use only concrete ones: 1.0.4
. If we need concrete patch or feature for some dependency, we should consciously update version to get these updates. Otherwise we should not get updates if we do not wait it.
Technically we can avoid fluent dependencies the following ways:
Define concrete version when we add dependency:
npm install --save-dev some-dep@1.0.4
Change default behaviour of parameter
save-prefix
of
.npmrc
(.yarnrc
) in the root of project:
.npmrc
:
.yarnrc
:
4.2. Fluent versions for peerDependencies
When we write our own library, we likely use peerDependencies
that imposes constraints on the environment in which it will be used. It makes sense to get as wide range as it is possible for peer dependencies to provide as much possibilities as possible for consumer projects that use our library. So it is preferable to set fluent versions (range of versions) for peer dependencies rather than concrete versions. However we should set only that range of versions we can guarantee our library works correctly with. If we do not really know whether our library works correctly with some versions of the peer dependency, we should set concrete version of the dependency.
Last updated