📜 ⬆️ ⬇️

Node.js Part 4: npm guide, package.json and package-lock.json files

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 the package.json and package-lock.json .




Basics npm


Npm (node ​​package manager) is the Node.js package manager. In the first part of this material, we already mentioned that there are now 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 npm command, 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 the node_modules folder, 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:


â–Ť Pack Updates


To update packages, use the following command:

 npm update 

Upon 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 update 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 package.json 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).

â–Ť Run scripts


The package.json file 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 npm install lodash , the package is placed in the node_modules folder located in the project folder. In addition, if the above command was executed, npm will also add an entry for the lodash library to the dependencies section of the package.json file in the current directory.

Global installation of packages is performed using the -g flag:

 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 located in the /usr/local/lib/node_modules . On Windows, this could be something like C:\Users\YOU\AppData\Roaming\npm\node_modules .

However, if you are using nvm for managing versions of Node.js, 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 the following address: /Users/flavio/.nvm/versions/node/v8.9.0/lib/node_modules .

â–ŤUses and executes packages installed using npm


How to use modules installed using npm, locally or globally, that fall into the node_modules folders? Suppose you have installed the popular lodash library, which 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 require command:

 const _ = require('lodash') 

What if the package is an executable file?

In this case, the executable file will go to the 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 pass some text to this package, in the console, in the ASCII-art style, the image of the cow will be displayed, which “pronounces” the corresponding text. Other creatures may “voice” the text.

So, after installing the package using the npm install cowsay , it, along with its dependencies, will go into node_modules . And in the hidden .bin folder will be written symbolic links to binary files cowsay.

How to do them?

Of course, you can enter something like ./node_modules/.bin/cowsay to call the program, 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 from 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 package.json file 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 it and what opportunities does it give you?

Package.json is something like a manifest file for a project. It gives the developer a lot of diverse opportunities. For example, it is the central repository of settings for the tools used in the project. It is also 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 package.json file:

 { } 

As you can see, it is empty. There are no strict requirements regarding what should be present in such a file for a certain application. The only requirement for the file structure is that it must follow the rules of the JSON format. Otherwise, this file will not be able to be read by programs that try to access its contents.

If you create a Node.js package that you are going to distribute through npm, then everything changes radically, and your 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 package.json example:

 { "name": "test-project" } 

It sets the property name , the value of which is the name of the application or package, the materials of which 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:


All of these properties are used either by npm or by other tools used during the application life cycle.

â–ŤProperties used in package.json


Let's talk about the 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 name property specifies the name of the package:

 "name": "test-project" 

The name must be shorter than 214 characters, must not include spaces, must contain only uppercase 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 version of the package name.

Property author


The author property contains information about the author of the package:

 { "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 contributors property 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 bugs property contains a link to the project's bug tracker; it’s very likely that such a link will lead to the GitHub bug tracking system page:

 { "bugs": "https://github.com/flaviocopes/package/issues" } 

Property homepage


The homepage property allows you to set the package home page:

 { "homepage": "https://flaviocopes.com/package" } 

Version property


The version property 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 different 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 license property contains package license information:

 "license": "MIT" 

Property keywords


The keywords property contains an array of keywords related to the functionality of the package:

 "keywords": [ "email", "machine learning", "ai" ] 

The correct 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 website.

Property description


The description property contains a brief description of the package:

 "description": "A package to work with strings" 

This property is especially important if you plan to publish a package to npm, as it allows npm users to understand the purpose of the package.

Repository property


The repository property indicates where the package repository is located:

 "repository": "github:flaviocopes/testing", 

Note that the value of this property has a github prefix. Npm supports prefixes for some other popular services of this kind:

 "repository": "gitlab:flaviocopes/testing", "repository": "bitbucket:flaviocopes/testing", 

The version control system used in the development of a package can also be specified explicitly:

 "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 main property 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 private property is set to true to prevent the package from being accidentally published to npm:

 "private": true 

Scripts property


The scripts property 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 like 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 dependencies property contains a 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 devDependencies property 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 dependencies property, 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


The engines property 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


The browserlist property allows browserlist 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 example of the browserlist property shown here as an example 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 (for details this can be found on the browserlists package page ).

â–ŤSaving in package.json settings for various software tools


In package.json you can store settings for various auxiliary tools like Babel or ESLint.

Each of these tools has a special property, like eslintConfig or babel . Details on the use of such properties can be found in the documentation of the relevant projects.

â–ŤAbout package versions and semantic versioning


, , , . , ~3.0.0 ^0.13.0 . , , .

, , , , :


:


, , -. , 1.0.0 || >=1.1.0 <1.2.0 , 1.0.0 , , 1.1.0 , 1.2.0 .

package-lock.json


package-lock.json npm 5. Node.js-. ? , package.json , .

, , , , .

, package.json . package.json , (- ) .

Git node_modules , . , npm install , , , ~ , -, , , -.

^ . , , , .

, - , npm install . , . , , - , , , ( ) .

package-lock.json npm npm install .

, , ( Composer Python) .

package-lock.json Git-, , , , , Git .

package-lock.json npm update .

â–Ť package-lock.json


package-lock.json , cowsay, npm 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="   } } } 

. cowsay, :


, , , requires , :


, version , resolved , , integrity , .


npm package.json package-lock.json . npm npx.

Dear readers! — npm yarn?

Source: https://habr.com/ru/post/423703/


All Articles