今天,我们将发布Node.js的翻译的第四部分。 在本文中,我们将开始讨论npm并考虑
package.json
和
package-lock.json
。

Npm基础
Npm(节点程序包管理器)是Node.js程序包管理器。 在本材料的第一部分中,我们已经提到过,现在npm中有超过一百万个软件包,这使其成为世界上最大的用一种语言编写的代码存储库。 这表明在npm中,您可以找到旨在解决几乎所有任务的软件包。
最初,npm是作为Node.js的程序包管理系统创建的,但今天它也用于开发JavaScript前端项目。 为了与npm注册表进行交互,使用了相同名称的命令,这为开发人员提供了大量机会。
▍加载包
使用
npm
命令,您可以从注册表中下载软件包。 下面我们将考虑其用法示例。
▍安装所有项目依赖项
如果项目具有
package.json
文件,则可以使用以下命令安装该项目的所有依赖项:
npm install
此命令将下载项目所需的所有内容,并将这些资料放置在
node_modules
文件夹中,如果项目目录中不存在该文件,
node_modules
创建该文件。
▍安装单独的包装
可以使用以下命令安装单独的一个:
npm install <package-name>
您经常可以看到该命令的使用方式不是很简单,而是带有一些标志。 考虑他们:
--save
标志使--save
可以安装软件包,并将有关该项目的条目添加到package.json
文件的dependencies
部分,其中描述了项目依赖项。 这些依赖项由项目使用以实现其主要功能,它们是在项目部署期间在服务器上安装的(在npm 5发行之后,“依赖项”部分中有关已安装软件包的条目会自动生成,而无需使用此标志)。--save-dev
标志允许您安装软件包并将其相关条目添加到包含package.json
文件的开发依赖项列表的部分(即,在项目开发过程中需要的包,例如用于测试的库,但对于其操作而言并非必需) package.json
称为devDependencies
。
▍包更新
要更新软件包,请使用以下命令:
npm update
收到此命令后,npm将检查所有软件包的新版本,如果它们找到满足
package.json
指定的软件包版本限制的新版本,请安装它们。
您还可以升级单独的软件包:
npm update <package-name>
▍上传某些版本的软件包
除了标准软件包下载外,npm还支持下载它们的特定版本。 特别要指出的是,某些库仅与其他库的某些较大版本兼容,也就是说,如果安装了此类库的依赖项而未考虑版本,则可能会破坏其工作。 在某些情况下,例如,该软件包的最新版本非常适合您,但是事实证明其中存在错误,可以安装特定版本的软件包。 等待软件包固定版本的发布,您可以使用其较旧但稳定的版本。
当所有团队成员都使用完全相同的库时,指定项目所需库的特定版本的功能在团队开发中很有用。 通过更改
package.json
项目文件,还可以集中执行向新版本的过渡。
在所有这些情况下,指定项目所需的软件包版本的功能非常有用。 Npm遵循语义版本控制(标准)的标准。
▍运行脚本
package.json
文件支持描述可以使用此构造启动的命令(脚本)的功能:
npm <task-name>
例如,以下是文件相应部分中的脚本列表:
{ "scripts": { "start-dev": "node lib/server-development", "start": "node lib/server-production" } }
使用此功能来启动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", } }
这种方法可以用以下简单结构替换充满错误的长命令的输入:
$ npm watch $ npm dev $ npm prod
pmnpm在哪里安装软件包?
使用npm(或
yarn )安装软件包时,有两个安装选项可用:本地和全局。
默认情况下,当您使用
npm install lodash
类的命令
npm install lodash
,该软件包将显示在项目文件夹中的
node_modules
文件夹中。 此外,如果执行了以上命令,npm还将在当前目录中的
package.json
文件的
dependencies
部分中添加
lodash
库的条目。
使用
-g
标志执行软件包的全局安装:
npm install -g lodash
通过执行这样的命令,npm不会将软件包安装在项目的本地文件夹中。 而是将软件包文件复制到某个全局位置。 这些文件到底在哪里?
为了找出答案,请使用以下命令:
npm root -g
在macOS或Linux上,软件包文件可能会出现在
/usr/local/lib/node_modules
。 在Windows上,可能类似于
C:\Users\YOU\AppData\Roaming\npm\node_modules
。
但是,如果使用Node.js nvm进行版本控制,则全局软件包文件夹的路径可能会更改。
例如,我使用nvm,上面的命令告诉我全局软件包安装在以下地址:
/Users/flavio/.nvm/versions/node/v8.9.0/lib/node_modules
。
▍使用并执行随npm安装的软件包
如何使用通过npm本地或全局安装的模块进入
node_modules
文件夹? 假设您安装了流行的
lodash
库,其中包含JavaScript开发中使用的许多辅助函数:
npm install lodash
这样的命令会将库安装在
node_modules
项目的本地文件夹中。
为了在代码中使用它,只需使用
require
命令将其导入:
const _ = require('lodash')
如果软件包是可执行文件,该怎么办?
在这种情况下,可执行文件将
node_modules/.bin/ folder
位于
node_modules/.bin/ folder
。
您可以通过安装
Cowsay软件包来了解这种机制的工作原理。 这是为命令行编写的漫画程序。 如果将一些文本传递到此数据包,则在控制台中以ASCII艺术风格显示牛的图像,并“发音”为相应的文本。 其他生物可以“说出”文字。
因此,在使用
npm install cowsay
安装软件包之后,它将连同其依赖项一起以
node_modules
。 并且在隐藏的
.bin
文件夹中将写入指向Cowsay二进制文件的符号链接。
如何实施?
当然,您可以在终端中输入
./node_modules/.bin/cowsay
之类的
./node_modules/.bin/cowsay
来调用该程序,这是一种
./node_modules/.bin/cowsay
的方法,但是最好使用
npx (一种用于启动npm包可执行文件的工具),该工具自5.2版起包含在npm中。 也就是说,在我们的情况下,我们需要以下命令:
npx cowsay
将自动找到npx包的路径。
Package.json文件
package.json
文件是许多基于Node.js生态系统的项目的重要元素。 如果您使用JavaScript编程(无论是服务器开发还是客户端开发),那么您可能已经看到了此文件。 为什么需要它? 您应该了解他什么,他会给您带来什么机会?
Package.json
是项目的一种清单文件。 他为开发人员提供了多种多样的可能性。 例如,它表示项目中使用的工具的中央设置存储库。 此外,在这里,
npm和
yarn还会写入有关已安装软件包的名称和版本的信息。
▍文件结构
这是一个简单的
package.json
文件的示例:
{ }
如您所见,它是空的。 对于特定应用程序,对于此类文件中应包含的内容,没有严格的要求。 文件结构的唯一要求是它必须遵循JSON格式的规则。 否则,尝试访问其内容的程序将无法读取该文件。
如果创建打算通过npm分发的Node.js程序包,则所有内容都会发生根本变化,并且
package.json
应该具有一组属性,可以帮助其他人使用该程序包。 稍后我们将详细讨论。
这是另一个示例
package.json
:
{ "name": "test-project" }
它设置
name
属性,其值是应用程序或程序包的名称,其材料包含在该文件所在的同一文件夹中。
这是我使用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" ] }
如您所见,这里有很多有趣的事情。 即,可以在此处区分以下属性:
name
设置应用程序(程序包)的名称。version
-包含有关应用程序当前版本的信息。description
应用程序的简短描述。- main-将入口设置为应用程序。
private
如果将此属性设置为true
,则可以防止将软件包意外发布到npm。scripts
-定义了一组可以运行的Node.js脚本。dependencies
-包含应用程序所依赖的npm软件包的列表。devDependencies
包含在开发项目时使用的npm软件包列表,但在实际工作时不使用。engines
-设置运行应用程序的Node.js版本的列表。browserlist
用于存储应用程序应支持的浏览器(及其版本)列表。
npm或整个应用程序生命周期中使用的其他工具都将使用所有这些属性。
packagepackage.json中使用的属性
让我们讨论可以在
package.json
使用的属性。 在这里,我们将使用“程序包”一词,但是有关程序包的所有说明也适用于不打算用作程序包的本地应用程序。
我们描述的大多数属性仅用于满足npm
存储库的需求,而某些属性则用于与代码(如同一npm)进行交互的程序。
名称属性
name
属性设置包的名称:
"name": "test-project"
名称必须短于214个字符,不能包含空格,只能由大写字母,连字符(
-
)和下划线(
_
)组成。
存在类似的限制,因为在npm中发布软件包时,其名称用于形成软件包页面的URL。
如果您在公共领域的GitHub上发布了程序包代码,则程序包名称的一个不错的选择是相应GitHub存储库的名称。
作者财产
author
属性包含有关软件包作者的信息:
{ "author": "Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)" }
可以以下格式显示:
{ "author": { "name": "Flavio Copes", "email": "flavio@flaviocopes.com", "url": "https://flaviocopes.com" } }
贡献者财产
contributors
属性包含一个数组,其中包含有关为该项目做出贡献的人员的信息:
{ "contributors": [ "Flavio Copes <flavio@flaviocopes.com> (https://flaviocopes.com)" ] }
该属性可能如下所示:
{ "contributors": [ { "name": "Flavio Copes", "email": "flavio@flaviocopes.com", "url": "https://flaviocopes.com" } ] }
错误属性
bugs
属性包含一个指向该项目的bug跟踪器的链接,很可能该链接将导致GitHub错误跟踪系统页面:
{ "bugs": "https://github.com/flaviocopes/package/issues" }
主页属性
homepage
属性允许您设置程序包主页:
{ "homepage": "https://flaviocopes.com/package" }
版本属性
version
属性包含有关软件包当前版本的信息:
"version": "1.0.0"
形成此属性的值时,必须遵循
语义版本控制的规则。 特别是,这意味着版本号始终由三位数字表示:xxx
第一个数字是软件包的主要版本,第二个是次要版本,第三个是补丁版本。
更改这些数字具有一定意义。 因此,仅纠正错误的软件包的发布会导致补丁版本价值的增加。 如果发布了软件包,则对该软件包所做的更改与先前版本向后兼容,则次要版本也会更改。 软件包的主要版本可能包含使这些软件包与以前的主要版本的软件包不兼容的更改。
许可属性
license
属性包含软件包
license
信息:
"license": "MIT"
关键字属性
keywords
属性包含与软件包功能相关的一组关键字:
"keywords": [ "email", "machine learning", "ai" ]
正确选择关键字可以帮助人们在搜索软件包以解决某些问题时找到所需的内容,使您可以对软件包进行分组并在查看npm网站时快速评估其可能的功能。
说明属性
description
属性包含对该程序包的简短描述:
"description": "A package to work with strings"
如果您打算在npm中发布程序包,此属性特别重要,因为它使npm网站的用户可以了解程序包的用途。
储存库属性
repository
属性指示软件包存储库所在的位置:
"repository": "github:flaviocopes/testing",
请注意,此属性的值具有
github
前缀。 Npm还支持此类其他一些流行服务的前缀:
"repository": "gitlab:flaviocopes/testing", "repository": "bitbucket:flaviocopes/testing",
软件包开发中使用的版本控制系统也可以明确设置:
"repository": { "type": "git", "url": "https://github.com/flaviocopes/testing.git" }
相同的程序包可以使用不同的版本控制系统:
"repository": { "type": "svn", "url": "..." }
物业主要
main
属性将入口点设置为包:
"main": "src/main.js"
将包导入应用程序时,将在此处搜索相应模块的导出内容。
私人财产
将
private
属性设置为
true
可以防止将该软件包意外发布到npm:
"private": true
脚本属性
scripts
属性设置可以使用npm工具启动的脚本或实用程序的列表:
"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" }
这些脚本是命令行应用程序。 通过执行
npm run XXXX
或
yarn XXXX
形式的命令,可以分别使用npm或yarn运行它们,其中
XXXX
是脚本的名称。 例如,它可能看起来像这样:
npm run dev
脚本可以随意调用,它们几乎可以完成开发人员可能想要的所有事情。
依赖项属性
Dependencies属性包含作为软件包依赖项安装的npm软件包列表:
"dependencies": { "vue": "^2.5.2" }
使用npm或yarn安装软件包时,将使用以下命令:
npm install <PACKAGENAME> yarn add <PACKAGENAME>
这些软件包会自动添加到正在开发的软件包的依赖项列表中。
DevDependencies属性
devDependencies
属性包含作为开发依赖关系安装的npm软件包列表:
"devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1" }
此列表不同于
dependencies
属性中存储的列表,因为其中可用的软件包仅安装在软件包开发者的系统中;在实际使用该软件包时,不会使用它们。
使用npm或yarn安装软件包时,它们会属于此列表,如下所示:
npm install --dev <PACKAGENAME> yarn add --dev <PACKAGENAME>
引擎属性
engines
属性指示使用哪个版本的Node.js和其他软件产品来提供软件包:
"engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0", "yarn": "^0.13.0" }
Browserlist属性
browserlist
属性允许
browserlist
报告程序包开发人员将支持哪些浏览器(及其版本):
"browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ]
Babel,Autoprefixer和其他工具使用此属性。 通过对该列表进行分析,他们可以仅将列出的浏览器所需的polyfill和辅助机制添加到软件包中。
作为示例,此处显示的
browserlist
属性的值表示您希望支持至少2%使用率至少1%的所有浏览器的主要版本(此数据取自
CanIUse.com ),但IE 8和该浏览器的旧版本除外(更多信息)可以在
browserlists软件包
页面上找到)。
package在package.json设置中存储各种软件工具
在
package.json
您可以存储各种辅助工具(如Babel或ESLint)的设置。
这些工具中的每一个都有一个特殊的属性,例如
eslintConfig
或
babel
。 有关使用此类属性的详细信息,请参见各个项目的文档。
package关于软件包版本和语义版本控制
, , , . ,
~3.0.0
^0.13.0
. , , .
, , , , :
~
: ~0.13.0
, - . , 0.13.1
, 0.14.0
— .^
: ^0.13.0
, , - . , 0.13.1
, 0.14.0
, .*
: , , , — .>
: , .>=
: , .<=
: , .<
: , .=
: .-
: , — 2.1.0 - 2.6.2
.||
: , . < 2.1 || > 2.6
.
:
, , -. ,
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 PHP) .
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, :
- get-stdin
- optimist
- string-width
- strip-eof
, , ,
requires
, :
- ansi-regex
- is-fullwidth-code-point
- minimist
- wordwrap
- strip-eof
,
version
,
resolved
, ,
integrity
, .
npm
package.json
package-lock.json
. npm npx.
亲爱的读者们! — npm yarn?
