Node.js Part 4: npm guide, package.json and package-lock.json files
- Transfer
- Tutorial
Today we publish the fourth part of the translation guide for Node.js. In this article we will start talking about npm and also consider the features of files
Npm (node package manager) is the Node.js package manager. In the first part of this material, we already mentioned that now there are more than half a million packages in npm, which makes it the world's largest repository of code written in one language. This suggests that in npm you can find packages designed to solve almost any problem.
Initially, npm was created as a package management system for Node.js, but today it is also used in the development of JavaScript front-end projects. To interact with the npm registry, the same-name command is used, which gives the developer a huge number of possibilities.
Using the command,
If the project has a file
This command will load everything the project needs and put these materials in a folder
Separate can be set with the following command:
You can often see how this command is used not in this simple form, but with some flags. Consider them:
To update packages, use the following command:
After receiving this command, npm will check all packages for the presence of their new versions, and if it finds new versions that meet the restrictions on the package versions specified in
You can also upgrade a separate package:
In addition to the standard package downloads, npm also supports downloading of certain versions. In particular, it can be noted that some libraries are compatible only with certain major releases of other libraries, that is, if the dependencies of such libraries were installed without taking into account versions, this could disrupt their work. The ability to install a certain version of a certain package is also useful in situations where, for example, the most recent release of this package suits you perfectly, but it turns out that there is an error in it. Waiting for the release of the revised version of the package, you can use its older but stable release.
The ability to specify specific versions of the required libraries for a project is useful in team development, when all team members use exactly the same libraries. The transition to their new versions is also carried out centrally, by making changes to the project file
In all these cases, the ability to specify the package versions required by the project is extremely useful. Npm follows the standard of semantic versioning (semver).
The file
For example, here’s what the list of scripts looks like in the corresponding section of the file:
It is quite common to use this feature to launch a webpack:
This approach makes it possible to replace the input of long commands, fraught with errors, with the following simple constructions:
When installing packages using npm (or yarn ), two installation options are available: local and global.
By default, when using a command like to install a package
Global installation of packages is performed using the flag
By executing such a command, npm does not install the package in the local project folder. Instead, it copies package files to a global location. Where exactly do these files go?
To find out, use the following command:
On macOS or Linux, package files may be in a directory
However, if you are using the version management of Node.js nvm, the path to the global packages folder may change.
For example, I use nvm, and the above command tells me that global packages are installed at that address:
How to use modules installed using npm, locally or globally, that fall into folders
This command will install the library in the local project folder
In order to use it in your code, it is enough to import it using the command
What if the package is an executable file?
In this case, the executable file will fall into the folder
You can look at how the work of this mechanism looks like by installing the cowsay package . It is a comic program written for the command line. If you transfer to this package any text, in the console, in the style of ASCII art, an image of a cow will be displayed that “pronounces” the corresponding text. Other creatures can “voice” the text.
So, after installing the package using the command
How to do them?
Of course, you can, to call the program, enter something like in the terminal
The path to the npx package will find automatically.
The file
Here is an example of the simplest file
As you can see, it is empty. There are no strict requirements regarding what should be present in such a file for some application. The only requirement for the file structure is that it must follow the rules of the JSON format. Otherwise, this file cannot be read by programs that attempt to access its contents.
If you create a Node.js package that you are going to distribute through npm, then everything changes radically, and you
Here is another example
It contains a property
Here is a more complicated example, which I took from an example application written using Vue.js:
As you can see, here is really nemeryanno everything interesting. Namely, the following properties can be distinguished here:
All of these properties are used either by npm or by other tools used during the application life cycle.
Talk about properties that can be used in
Most of the properties that we describe are used only for the needs of the npm repository , some are used by programs that interact with code like the same npm.
The property
The name must be shorter than 214 characters, must not include spaces, must consist only of capital letters, hyphens (
Such restrictions exist because when a package is published to npm, its name is used to form the URL of the package page.
If you publish the package code on GitHub, in a public domain, then the name of the corresponding GitHub repository is a good option for the package name.
The property
It can be presented in this format:
The property
This property may look like this:
The property
This property
This property
When forming the value of this property, one should follow the rules of semantic versioning . This means, in particular, that the version number is always represented by three digits: xxx
The first number is the major version of the package, the second is the minor version, and the third is the patch version.
Changing these numbers carries a certain meaning. Thus, the release of the package, which only fixes errors, leads to an increase in the value of the patch version. If the release of the package comes out, the changes made in which are distinguished by backward compatibility with the previous release - then the minor version changes. Major versions of packages may contain changes that make these packages incompatible with packages of previous major versions.
The property
The property
Proper selection of keywords helps people find what they need when searching for packages to solve certain problems, allows them to group packages and quickly evaluate their possible functionality when browsing the npm site.
The property
This property is especially important if you plan to publish the package to npm, as it allows users of the npm site to understand the purpose of the package.
The property
Note that the value of this property has a prefix
The version control system used when developing a package can also be specified in the explicit form:
The same package can use different version control systems:
The property
When a package is imported into an application, this is where the search will be made for what the corresponding module is exporting.
The property
This property
These scripts are command line applications. They can be run using npm or yarn, executing, respectively, commands of the form
Scripts can be called as you want, they can do almost everything that a developer can wish for.
The property
When installing a package using npm or yarn, the following commands are used:
These packages are automatically added to the list of dependencies of the developed package.
The property
This list is different from the one that is stored in the property
Packages fall into this list when they are installed using npm or yarn, performed as follows:
This property
This property
Babel, Autoprefixer and other tools use this feature. The analysis of this list allows them to add to the package only those polyfills and auxiliary mechanisms that are needed for the listed browsers.
The property value shown here as an example
You
Each of these tools corresponds to a particular property, like
In the examples above, you could see that the version numbers of the packages are not only defined as ordinary numbers separated by dots, but also using certain special characters. For example, in the form
Taking into account the fact that when using semantic versioning, all version numbers of packages consist of sequences representing three numbers, the meaning of which we spoke above, we will describe the following rules for using version specifiers:
There are some more rules:
Most of the above qualifiers can be combined, for example, by specifying ranges of suitable versions of dependency packages. For example, a type construct
The file has been
The purpose of this file is to track the exact versions of the installed packages, which allows the developed product to be 100% reproducible in its original form, even if those who support the packages have updated them.
This file solves a very specific problem that cannot be solved by means
Git doesn't commit folder
The same goes for the specifier
So, someone is trying to initialize the project using the command
The file
This concept is not new, package managers used in other programming languages (like the Composer manager in PHP) have been using a similar system for many years.
File
Versions of dependencies will be updated in
This example shows the structure of the file
Let's sort this file. We install the cowsay package, which depends on the following packages:
These packages, in turn, depend on other packages, information about which we can learn from the properties
They are added to the file in alphabetical order, each has a field
Today we started talking about npm and figured out the structure and purpose of the files
Dear readers! Which package manager do you prefer - npm or yarn?
package.json
and package-lock.json
.[We advise to read] Other parts of the cycle
Часть 1: Общие сведения и начало работы
Часть 2: JavaScript, V8, некоторые приёмы разработки
Часть 3: Хостинг, REPL, работа с консолью, модули
Часть 4: npm, файлы package.json и package-lock.json
Часть 5: npm и npx
Часть 6: цикл событий, стек вызовов, таймеры
Часть 7: асинхронное программирование
Часть 8: Руководство по Node.js, часть 8: протоколы HTTP и WebSocket
Часть 9: Руководство по Node.js, часть 9: работа с файловой системой
Часть 10: Руководство по Node.js, часть 10: стандартные модули, потоки, базы данных, NODE_ENV
Полная PDF-версия руководства по Node.js
Часть 2: JavaScript, V8, некоторые приёмы разработки
Часть 3: Хостинг, REPL, работа с консолью, модули
Часть 4: npm, файлы package.json и package-lock.json
Часть 5: npm и npx
Часть 6: цикл событий, стек вызовов, таймеры
Часть 7: асинхронное программирование
Часть 8: Руководство по Node.js, часть 8: протоколы HTTP и WebSocket
Часть 9: Руководство по Node.js, часть 9: работа с файловой системой
Часть 10: Руководство по Node.js, часть 10: стандартные модули, потоки, базы данных, NODE_ENV
Полная PDF-версия руководства по Node.js
Basics npm
Npm (node package manager) is the Node.js package manager. In the first part of this material, we already mentioned that now there are more than half a million packages in npm, which makes it the world's largest repository of code written in one language. This suggests that in npm you can find packages designed to solve almost any problem.
Initially, npm was created as a package management system for Node.js, but today it is also used in the development of JavaScript front-end projects. To interact with the npm registry, the same-name command is used, which gives the developer a huge number of possibilities.
▍Download packages
Using the command,
npm
you can download packages from the registry. Below we look at examples of its use.▍Install all project dependencies
If the project has a file
package.json
, then you can install all the dependencies of this project with the following command:npm install
This command will load everything the project needs and put these materials in a folder
node_modules
, creating it if it does not exist in the project directory.▍ Installing a separate package
Separate can be set with the following command:
npm install <package-name>
You can often see how this command is used not in this simple form, but with some flags. Consider them:
- The flag
--save
allows you to install a package and add an entry about it to the section of thedependencies
filepackage.json
that describes the dependencies of the project. These dependencies are used by the project to implement its main functionality, they are installed during its deployment on the server (after npm 5 is released, records about installed packages in the dependency section are made automatically without using this flag). - The flag
--save-dev
allows you to install a package and add an entry about it to a section containing a list of development dependencies (that is, packages that are needed during project development, such as libraries for testing, but not required for its operation) of a filepackage.json
calleddevDependencies
.
▍ Pack Updates
To update packages, use the following command:
npm update
After receiving this command, npm will check all packages for the presence of their new versions, and if it finds new versions that meet the restrictions on the package versions specified in
package.json
, install them. You can also upgrade a separate package:
npm update <package-name>
▍Download packages of certain versions
In addition to the standard package downloads, npm also supports downloading of certain versions. In particular, it can be noted that some libraries are compatible only with certain major releases of other libraries, that is, if the dependencies of such libraries were installed without taking into account versions, this could disrupt their work. The ability to install a certain version of a certain package is also useful in situations where, for example, the most recent release of this package suits you perfectly, but it turns out that there is an error in it. Waiting for the release of the revised version of the package, you can use its older but stable release.
The ability to specify specific versions of the required libraries for a project is useful in team development, when all team members use exactly the same libraries. The transition to their new versions is also carried out centrally, by making changes to the project file
package.json
. In all these cases, the ability to specify the package versions required by the project is extremely useful. Npm follows the standard of semantic versioning (semver).
▍ Run scripts
The file
package.json
supports the ability to describe commands (scripts), which can be run using this construct:npm <task-name>
For example, here’s what the list of scripts looks like in the corresponding section of the file:
{
"scripts": {
"start-dev": "node lib/server-development",
"start": "node lib/server-production"
}
}
It is quite common to use this feature to launch a webpack:
{
"scripts": {
"watch": "webpack --watch --progress --colors --config webpack.conf.js",
"dev": "webpack --progress --colors --config webpack.conf.js",
"prod": "NODE_ENV=production webpack -p --config webpack.conf.js",
}
}
This approach makes it possible to replace the input of long commands, fraught with errors, with the following simple constructions:
$ npm watch
$ npm dev
$ npm prod
▍ Where does npm install packages?
When installing packages using npm (or yarn ), two installation options are available: local and global.
By default, when using a command like to install a package
npm install lodash
, the package is in a folder node_modules
located in the project folder. In addition, if the above command was executed, npm will also add a library entry lodash
to the dependencies
file section package.json
that is in the current directory. Global installation of packages is performed using the flag
-g
:npm install -g lodash
By executing such a command, npm does not install the package in the local project folder. Instead, it copies package files to a global location. Where exactly do these files go?
To find out, use the following command:
npm root -g
On macOS or Linux, package files may be in a directory
/usr/local/lib/node_modules
. On Windows, this may be something like C:\Users\YOU\AppData\Roaming\npm\node_modules
. However, if you are using the version management of Node.js nvm, the path to the global packages folder may change.
For example, I use nvm, and the above command tells me that global packages are installed at that address:
/Users/flavio/.nvm/versions/node/v8.9.0/lib/node_modules
.▍Using and executing packages installed using npm
How to use modules installed using npm, locally or globally, that fall into folders
node_modules
? Suppose you have installed a popular library lodash
that contains many support functions used in JavaScript development:npm install lodash
This command will install the library in the local project folder
node_modules
. In order to use it in your code, it is enough to import it using the command
require
:const _ = require('lodash')
What if the package is an executable file?
In this case, the executable file will fall into the folder
node_modules/.bin/ folder
. You can look at how the work of this mechanism looks like by installing the cowsay package . It is a comic program written for the command line. If you transfer to this package any text, in the console, in the style of ASCII art, an image of a cow will be displayed that “pronounces” the corresponding text. Other creatures can “voice” the text.
So, after installing the package using the command
npm install cowsay
, it, along with its dependencies, will fall into node_modules
. And in the hidden folder .bin
will be written symbolic links to binary files cowsay. How to do them?
Of course, you can, to call the program, enter something like in the terminal
./node_modules/.bin/cowsay
, this is a working approach, but it is much better to use npx , a tool for running executable files of npm-packages, included in npm starting with version 5.2. Namely, in our case we need the following command:npx cowsay
The path to the npx package will find automatically.
Package.json file
The file
package.json
is the most important element of a multitude of projects based on the Node.js ecosystem. If you programmed in JavaScript, whether it was server-side or client-side development, then you probably already encountered this file. Why is it needed? What should you know about him and what opportunities does he give you? Package.json
is something like a manifest file for a project. He gives the developer a lot of diverse opportunities. For example, it is the central repository of settings for the tools used in the project. In addition, it is the place where npm and yarn record information about the names and versions of installed packages.ФайлаFile structure
Here is an example of the simplest file
package.json
:{
}
As you can see, it is empty. There are no strict requirements regarding what should be present in such a file for some application. The only requirement for the file structure is that it must follow the rules of the JSON format. Otherwise, this file cannot be read by programs that attempt to access its contents.
If you create a Node.js package that you are going to distribute through npm, then everything changes radically, and you
package.json
should have a set of properties that will help other people use the package. We will talk more about this later. Here is another example
package.json
:{
"name": "test-project"
}
It contains a property
name
whose value is the name of the application or package whose materials are contained in the same folder as this file. Here is a more complicated example, which I took from an example application written using Vue.js:
{
"name": "test-project",
"version": "1.0.0",
"description": "A Vue.js project",
"main": "src/main.js",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"test": "npm run unit",
"lint": "eslint --ext .js,.vue src test/unit",
"build": "node build/build.js"
},
"dependencies": {
"vue": "^2.5.2"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-jest": "^21.0.2",
"babel-loader": "^7.1.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-airbnb-base": "^11.3.0",
"eslint-friendly-formatter": "^3.0.0",
"eslint-import-resolver-webpack": "^0.8.3",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"jest": "^22.0.4",
"jest-serializer-vue": "^0.3.0",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-jest": "^1.0.2",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
As you can see, here is really nemeryanno everything interesting. Namely, the following properties can be distinguished here:
name
- sets the name of the application (package).version
- contains information about the current version of the application.description
- a brief description of the application.main
- sets the entry point to the application.private
- if this property is set totrue
, this prevents the package from being accidentally published to npm.scripts
- sets a set of Node.js scripts that can be run.dependencies
- contains a list of npm-packages on which the application depends.devDependencies
- contains a list of npm-packages used in the development of the project, but not in its actual work.engines
- sets the list of Node.js versions on which the application runs.browserlist
- used to store the list of browsers (and their versions) that the application should support.
All of these properties are used either by npm or by other tools used during the application life cycle.
▍Properties used in package.json
Talk about properties that can be used in
package.json
. Here we will use the term “package”, but everything that is said about packages is also true for local applications that are not planned to be used as packages. Most of the properties that we describe are used only for the needs of the npm repository , some are used by programs that interact with code like the same npm.
Name property
The property
name
sets the package name:"name": "test-project"
The name must be shorter than 214 characters, must not include spaces, must consist only of capital letters, hyphens (
-
) and underscores ( _
). Such restrictions exist because when a package is published to npm, its name is used to form the URL of the package page.
If you publish the package code on GitHub, in a public domain, then the name of the corresponding GitHub repository is a good option for the package name.
Property author
The property
author
contains information about the package author:{
"author": "Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)"
}
It can be presented in this format:
{
"author": {
"name": "Flavio Copes",
"email": "flavio@flaviocopes.com",
"url": "https://flaviocopes.com"
}
}
Property contributors
The property
contributors
contains an array with information about the people who contributed to the project:{
"contributors": [
"Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)"
]
}
This property may look like this:
{
"contributors": [
{
"name": "Flavio Copes",
"email": "flavio@flaviocopes.com",
"url": "https://flaviocopes.com"
}
]
}
Bugs property
The property
bugs
contains a link to the project's bug tracker. It is very likely that such a link will lead to the GitHub bug tracking system page:{
"bugs": "https://github.com/flaviocopes/package/issues"
}
Property homepage
This property
homepage
allows you to set the package home page:{
"homepage": "https://flaviocopes.com/package"
}
Version property
This property
version
contains information about the current version of the package:"version": "1.0.0"
When forming the value of this property, one should follow the rules of semantic versioning . This means, in particular, that the version number is always represented by three digits: xxx
The first number is the major version of the package, the second is the minor version, and the third is the patch version.
Changing these numbers carries a certain meaning. Thus, the release of the package, which only fixes errors, leads to an increase in the value of the patch version. If the release of the package comes out, the changes made in which are distinguished by backward compatibility with the previous release - then the minor version changes. Major versions of packages may contain changes that make these packages incompatible with packages of previous major versions.
License property
The property
license
contains information about the license package:"license": "MIT"
Property keywords
The property
keywords
contains an array of keywords related to the functionality of the package:"keywords": [
"email",
"machine learning",
"ai"
]
Proper selection of keywords helps people find what they need when searching for packages to solve certain problems, allows them to group packages and quickly evaluate their possible functionality when browsing the npm site.
Property description
The property
description
contains a brief description of the package:"description": "A package to work with strings"
This property is especially important if you plan to publish the package to npm, as it allows users of the npm site to understand the purpose of the package.
Repository property
The property
repository
indicates where the package repository is located:"repository": "github:flaviocopes/testing",
Note that the value of this property has a prefix
github
. Npm supports prefixes for some other popular services of this kind:"repository": "gitlab:flaviocopes/testing",
"repository": "bitbucket:flaviocopes/testing",
The version control system used when developing a package can also be specified in the explicit form:
"repository": {
"type": "git",
"url": "https://github.com/flaviocopes/testing.git"
}
The same package can use different version control systems:
"repository": {
"type": "svn",
"url": "..."
}
Main property
The property
main
sets the entry point to the package:"main": "src/main.js"
When a package is imported into an application, this is where the search will be made for what the corresponding module is exporting.
Private property
The property
private
set true
to prevent the package from being accidentally published to npm:"private": true
Scripts property
This property
scripts
specifies a list of scripts or utilities that can be run using npm tools:"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"test": "npm run unit",
"lint": "eslint --ext .js,.vue src test/unit",
"build": "node build/build.js"
}
These scripts are command line applications. They can be run using npm or yarn, executing, respectively, commands of the form
npm run XXXX
or yarn XXXX
, where XXXX
is the name of the script. For example, it may look like this:npm run dev
Scripts can be called as you want, they can do almost everything that a developer can wish for.
Dependencies property
The property
dependencies
contains the list of npm-packages installed as package dependencies:"dependencies": {
"vue": "^2.5.2"
}
When installing a package using npm or yarn, the following commands are used:
npm install <PACKAGENAME>
yarn add <PACKAGENAME>
These packages are automatically added to the list of dependencies of the developed package.
DevDependencies property
The property
devDependencies
contains a list of npm packages installed as development dependencies:"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1"
}
This list is different from the one that is stored in the property
dependencies
, since the packages it contains are installed only in the package developer’s system; they are not used in practical use of the package. Packages fall into this list when they are installed using npm or yarn, performed as follows:
npm install --dev <PACKAGENAME>
yarn add --dev <PACKAGENAME>
Property engines
This property
engines
indicates which versions of Node.js and other software products are used to make the package work:"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0",
"yarn": "^0.13.0"
}
Browserlist property
This property
browserlist
allows you to report which browsers (and their versions) the developer of the package is going to support:"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
Babel, Autoprefixer and other tools use this feature. The analysis of this list allows them to add to the package only those polyfills and auxiliary mechanisms that are needed for the listed browsers.
The property value shown here as an example
browserlist
means that you want to support at least 2 major versions of all browsers with at least 1% of use (this data is taken from CanIUse.com ), except for IE 8 and older versions of this browser (more about this can be found on the browserlists package page ).▍Saving in package.json settings for various software tools
You
package.json
can store settings for various auxiliary tools like Babel or ESLint. Each of these tools corresponds to a particular property, like
eslintConfig
or babel
. Details on the use of such properties can be found in the documentation of relevant projects.▍About package versions and semantic versioning
In the examples above, you could see that the version numbers of the packages are not only defined as ordinary numbers separated by dots, but also using certain special characters. For example, in the form
~3.0.0
or ^0.13.0
. Here we use the so-called version specifiers, which determine the range of package versions that are suitable for use in our package. Taking into account the fact that when using semantic versioning, all version numbers of packages consist of sequences representing three numbers, the meaning of which we spoke above, we will describe the following rules for using version specifiers:
~
: if you specify a version in the form,~0.13.0
this means that you are only interested in the patch releases of the package. That is, the package0.13.1
will suit you, but0.14.0
not.^
: If the version number is specified in the form^0.13.0
, this means that new patch versions and minor versions of the package are suitable for you. That is, you will arrange a version of the package0.13.1
,0.14.0
and so on.*
: using this symbol, you inform the system that you will be satisfied with any fresh versions of the package, including its new major releases.>
: Any versions of the package that are larger than the specified one are suitable.>=
: Any package versions that are equal to or greater than the specified one are suitable.<=
: You will be satisfied with packages whose versions are equal to the specified one or less.<
: you are interested in packages whose versions are less than the specified.=
: you only need the specified version of the package.-
: used to specify a range of suitable versions, for example -2.1.0 - 2.6.2
.||
: allows you to combine sets of package related conditions. For example, it might look like< 2.1 || > 2.6
.
There are some more rules:
- no extra characters: if the version number of the package without additional characters is used, it means that your package only needs the specified version of the dependency package and no other.
latest
: indicates that you need the most recent version of a certain package.
Most of the above qualifiers can be combined, for example, by specifying ranges of suitable versions of dependency packages. For example, a type construct
1.0.0 || >=1.1.0 <1.2.0
indicates that it is planned to use either a package 1.0.0
version or a version whose number is greater than or equal to 1.1.0
, but smaller 1.2.0
.File package-lock.json
The file has been
package-lock.json
used since the advent of npm version 5. It is created automatically when you install Node.js packages. What is this file? Perhaps you are not familiar with him even if you knew about him package.json
, which exists much longer than him. The purpose of this file is to track the exact versions of the installed packages, which allows the developed product to be 100% reproducible in its original form, even if those who support the packages have updated them.
This file solves a very specific problem that cannot be solved by means
package.json
. You package.json
can specify which updates of a certain package are suitable for you (patch versions or minor versions) using the above version specifiers. Git doesn't commit folder
node_modules
, as it usually has huge dimensions. When you try to recreate a project on another computer, using the command npm install
will result in that if using the specifier ~
as applied to a version of a package, its patch release was released, the package that was used during the development will be installed, but this patch release. The same goes for the specifier
^
. If, while specifying the package version, the specifiers were not used, then the specified version will be installed and the problem in question will be irrelevant in this situation. So, someone is trying to initialize the project using the command
npm install
. When new versions of packages are released, it will turn out that this project is different from the original one. Even if following the rules of semantic versioning, minor releases and patch releases should not contain changes that prevent backward compatibility, we all know that bugs are able to penetrate (and penetrate) anywhere. The file
package-lock.json
keeps unchanged the version information of each installed package, and npm will use these versions of the packages when executing the command npm install
. This concept is not new, package managers used in other programming languages (like the Composer manager in PHP) have been using a similar system for many years.
File
package-lock.json
You need to send it to a Git repository, which will allow other people to download it if the project is publicly available, or when a team of programmers is developing it, or if you use Git to deploy the project. Versions of dependencies will be updated in
package-lock.json
after the command is executed npm update
.▍Sample package-lock.json file
This example shows the structure of the file
package-lock.json
that is included with the cowsay package installed in an empty folder with the npm command install cowsay
:{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.
0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"cowsay": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz"
,
"integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkM
Ajufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
"requires": {
"get-stdin": "^5.0.1",
"optimist": "~0.6.1",
"string-width": "~2.1.1",
"strip-eof": "^1.0.0"
}
},
"get-stdin": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.
1.tgz",
"integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/
is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"minimist": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10
.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
},
"optimist": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"requires": {
"minimist": "~0.0.1",
"wordwrap": "~0.0.2"
}
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"requires": {
"ansi-regex": "^3.0.0"
}
},
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
}
}
}
Let's sort this file. We install the cowsay package, which depends on the following packages:
- get-stdin
- optimist
- string-width
- strip-eof
These packages, in turn, depend on other packages, information about which we can learn from the properties
requires
that some of them have:- ansi-regex
- is-fullwidth-code-point
- minimist
- wordwrap
- strip-eof
They are added to the file in alphabetical order, each has a field
version
, there is a field resolved
indicating the location of the package, and a string property integrity
that can be used to check the integrity of the package.Results
Today we started talking about npm and figured out the structure and purpose of the files
package.json
and package-lock.json
. Next time, we’ll continue to analyze the capabilities of npm and touch on using npx. Dear readers! Which package manager do you prefer - npm or yarn?