您的位置:首页 > 产品设计 > 产品经理

npm 与 package.json 快速入门

2018-03-20 15:56 483 查看
原文:http://blog.csdn.net/u011240877/article/details/76582670npm 是前端开发广泛使用的包管理工具,本人初次接触npm,有很多不懂,可以说要从安装开始学起,看到这篇文章后,也是在这边文章中了解到一些入门知识,同时感谢作者,并转载与大家分享。读完本文你将了解:什么是 npm
安装 npm
更新 npm
packagejson 文件packagejson 如何创建
packagejson 的内容
指定依赖的包
Semantic versioning语义化版本规则

安装 package本地安装 package安装参数 --save 和 --save -dev
使用下载好的包
更新本地 package
卸载本地 package

全局安装 package全局安装的权限问题
更新全局的 package
卸载全局 package

其他命令npm run
npm install from github
npm info
npm adduser
npm homerepo
npm prune
npm publish

国内镜像
总结
Thanks

什么是 npm?


官方文档中对它的介绍是:npm makes it easy for JavaScript developers to share and reuse code, and it makes it easy to update the code that you’re sharing.即: npm 是一个包管理器,它让 JavaScript 开发者分享、复用代码更方便(有点 maven 的感觉哈)。在程序开发中我们常常需要依赖别人提供的框架,写 JS 也不例外。这些可以重复的框架代码被称作包(package)或者模块(module),一个包可以是一个文件夹里放着几个文件,同时有一个叫做 
package.json
 的文件。一个网站里通常有几十甚至上百个 package,分散在各处,通常会将这些包按照各自的功能进行划分(类似我们安卓开发中的划分子模块),但是如果重复造一些轮子,不如上传到一个公共平台,让更多的人一起使用、参与这个特定功能的模块。而 npm 的作用就是让我们发布、下载一些 JS 轮子更加方便。我们可以去官方网站 https://www.npmjs.com/ 浏览、搜索想要的轮子,也可以直接在命令行中 search 一下意中轮。

使用 npm 后我们可以非常方便地查看依赖的轮子是否有更新、是否需要下载新版本。现在我们知道 npm 是干什么的了。当人们说起 “npm” 时,可能在说三个东西:一个网站,就是前面提到用于搜索 JS 模块的网站:https://www.npmjs.com/
一个仓库,保存着人们分享的 JS 模块的大数据库
命令行里的客户端,开发者使用它来管理、安装、发布模块
只要开发者发布某个模块到仓库中,其他人就可以从 npm 网站或者命令行中下载、使用它了!

安装 npm

npm 是依附于 node.js 的,我们可以去它的官网 https://nodejs.org/en/download/ 下载安装 node.js。下载好 node.js, npm 也就有了,使用 
npm -v
 查看安装的 npm 版本:
zhangshixin$ node -v
v6.10.0
1
2

更新 npm

npm 更新地可比 node 勤快多了,因此你下载的 node 附带的 npm 版本可能不是最新的,你可以使用如下命令下载最新 npm:
npm install npm@latest -g
1
其中 install 不用介绍了,就是安装,后面的 
npm@latest
 就是 
<packageName>@<version>
 的格式,我们在下载其他模块时也是这个格式。
-g
 代表全局安装。

package.json 文件

package.json
 文件非常重要,因此需要单独一小节介绍。管理本地安装 npm 包的最好方式就是创建 
package.json
 文件。一个 
package.json
 文件可以有以下几点作用:作为一个描述文件,描述了你的项目依赖哪些包
允许我们使用 “语义化版本规则”(后面介绍)指明你项目依赖包的版本
让你的构建更好地与其他开发者分享,便于重复使用

package.json 如何创建

使用 
npm init
 即可在当前目录创建一个 
package.json
 文件:

如图所示,输入 
npm init
 后会弹出一堆问题,我们可以输入对应内容,也可以使用默认值。在回答一堆问题后输入 
yes
 就会生成图中所示内容的 
package.json
 文件。如果嫌回答这一大堆问题麻烦,可以直接输入 
npm init --yes
 跳过回答问题步骤,直接生成默认值的 
package.json
 文件:

package.json 的内容

package.json
 文件至少要有两部分内容:“name” 
全部小写,没有空格,可以使用下划线或者横线

“version” 
x.x.x 的格式
符合“语义化版本规则”

比如:
{
"name": "shixinzhang-demo-package",
"version": "1.0.0"
}
1
2
3
4
其他内容:
description
:描述信息,有助于搜索
main
: 入口文件,一般都是 
index.js

scripts
:支持的脚本,默认是一个空的 test
keywords
:关键字,有助于在人们使用 
npm search
 搜索时发现你的项目
author
:作者信息
license
:默认是 MIT
bugs
:当前项目的一些错误信息,如果有的话
我们可以为 
init
 命令设置一些默认值,比如:
> npm set init.author.email "shixinzhang2016@gmail.com"
> npm set init.author.name "shixinzhang"
> npm set init.license "MIT"
1
2
3
注意: 
如果 package.json 中没有 
description
 信息,npm 使用项目中的 README.md 的第一行作为描述信息。这个描述信息有助于别人搜索你的项目,因此建议好好写 
description
 信息。

指定依赖的包

我们需要在 
package.json
 文件中指定项目依赖的包,这样别人在拿到这个项目时才可以使用 
npm install
 下载。包有两种依赖方式:
dependencies
:在生产环境中需要用到的依赖
devDependencies
:在开发、测试环境中用到的依赖
举个例子:
{
"name": "my-weex-demo",
"version": "1.0.0",
"description": "a weex project",
"main": "index.js",
"scripts": {
"build": "weex-builder src dist",
"build_plugin": "webpack --config ./tools/webpack.config.plugin.js --color",
"dev": "weex-builder src dist -w",
"serve": "serve -p 8080"
},
"keywords": [
"weex"
],
"author": "fkysly@gmail.com",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.14.0",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.18.0",
"vue-loader": "^10.0.2",
"eslint": "^3.5.0",
"serve": "^1.4.0",
"webpack": "^1.13.2",
"weex-loader": "^0.3.3",
"weex-builder": "^0.2.6"
},
"dependencies": {
"weex-html5": "^0.3.2",
"weex-components": "*"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Semantic versioning(语义化版本规则)

https://docs.npmjs.com/getting-started/semantic-versioning
dependencies
 的内容,以 
"weex-html5": "^0.3.2"
 为例,我们知道 key 是依赖的包名称,value 是这个包的版本。那版本前面的 ^ 或者版本直接是一个 * 是什么意思呢?这就是 npm 的 “Semantic versioning”,简称”Semver”,中文含义即“语义化版本规则”。在安卓开发中我们有过这样的经验:有时候依赖的包升级后大改版,之前提供的接口不见了,这对使用者的项目可能造成极大的影响。因此我们在声明对某个包的依赖时需要指明是否允许 update 到新版本,什么情况下允许更新。这就需要先了解 npm 包提供者应该注意的版本号规范。如果一个项目打算与别人分享,应该从 1.0.0 版本开始。以后要升级版本应该遵循以下标准:补丁版本:解决了 Bug 或者一些较小的更改,增加最后一位数字,比如 1.0.1
小版本:增加了新特性,同时不会影响之前的版本,增加中间一位数字,比如 1.1.0
大版本:大改版,无法兼容之前的,增加第一位数字,比如 2.0.0
了解了提供者的版本规范后, npm 包使用者就可以针对自己的需要填写依赖包的版本规则。作为使用者,我们可以在 
package.json
 文件中写明我们可以接受这个包的更新程度(假设当前依赖的是 1.0.4 版本):如果只打算接受补丁版本的更新(也就是最后一位的改变),就可以这么写: 
1.0
1.0.x
~1.0.4

如果接受小版本的更新(第二位的改变),就可以这么写: 
1
1.x
^1.0.4

如果可以接受大版本的更新(自然接受小版本和补丁版本的改变),就可以这么写: 
*
x

小结一下:总共三种版本变化类型,接受依赖包哪种类型的更新,就把版本号准确写到前一位。

安装 package

使用 npm 安装 package 有两种方式:本地(当前项目路径)安装 或者 全局安装。你选择哪种安装方式取决于你将如何使用这个包:如果你只是想在当前项目里用 
require()
 加载使用,那你可以安装到本地 
npm install
 默认就是安装到本地的

如果你想要在命令行里直接使用,比如 
grunt
 CLI,就需要安装到全局了
如果在你的项目里有 
package.json
 文件,运行 
npm install
 后它会查找文件中列出的依赖包,然后下载符合语义化版本规则的版本。
npm install
 默认会安装 
package.json
 中 
dependencies
 和 
devDependencies
 里的所有模块。如果想只安装 
dependencies
 中的内容,可以使用 
--production
 字段:
npm install --production
1

本地安装 package

npm 使用下面的命令下载一个包:
npm install <package_name>
1
后面就是要安装包的名称。这个命令会在当前目录创建一个 
node_modules
 目录,然后下载我们指定的包到这个目录中。举个例子:
zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ npm install lodash
zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ ls
index.js        package-lock.json
node_modules        package.json
zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ ls node_modules/
lodash
1
2
3
4
5
6
下载后的项目文件夹:

安装指定版本:
npm install
 默认安装最新版本,如果想要安装指定版本,可以在库名称后加 
@版本号
$ npm install sax@latest
$ npm install sax@0.1.1
$ npm install sax@">=0.1.0 <0.2.0"
1
2
3
如果当前项目有 
package.json
 文件,下载包时会下载这个文件中指定的版本; 
如果当前项目中没有 
package.json
 文件,就会下载指定包的最新版本。有时下载会报错:
npm install error saveError ENOENT: no such file or directory, open '/Users/zhangshixin/package.json'
解决办法: 
- 在目录下执行 
npm init
 创建 
package.json
,输入初始化信息 
- 然后再执行下载命令

安装参数 
--save
 和 
--save -dev

添加依赖时我们可以手动修改 
package.json
 文件,添加或者修改 
dependencies
 
devDependencies
 中的内容即可。另一种更酷的方式是用命令行,在使用 
npm install
 时增加 
--save
 或者 
--save -dev
 后缀:
npm install <package_name> --save
 表示将这个包名及对应的版本添加到 
package.json
的 
dependencies

npm install <package_name> --save-dev
 表示将这个包名及对应的版本添加到 
package.json
的 
devDependencies

使用下载好的包

下载后 
node_modules
 文件夹中有要使用的包,我们就可以使用其中的代码了。比如在 Node.js 项目中,我们可以用 
require(XXX)
 引入它。举个例子: 
创建一个 index.js 文件,写入如下代码:

在使用 
require('lodash')
 后引入了 lodash 库,然后调用了它的 
without()
 方法,这个方法可以去除第一个数组参数中与第二个参数重复的数据。保存这个文件后,使用 
node index.js
 运行这个文件,成功的话就可以得到运行结果;如果之前安装失败,可能就会遇到这个错误:
module.js:340
throw err;
^
Error: Cannot find module 'lodash'
1
2
3
4
这时你需要在这个目录下重新运行 
npm install lodash
 安装。

更新本地 package

有时候我们想知道依赖的包是否有新版本,可以使用 
npm outdated
 查看,如果发现有的包有新版本,就可以使用 
npm update <package-name>
 更新它,或者直接 
npm update
 更新所有:

上图中,我们在输入 
npm update
 后发现本地的 
lodash
 模块还不是最新的,这是为什么呢?原来,npm update 的工作过程是这样的:先到远程仓库查询最新版本
然后对比本地版本,如果本地版本不存在,或者远程版本较新
查看 
package.json
 中对应的语义版本规则
如果当前新版本符合语义规则,就更新,否则不更新
一开始我本地的 package.json 的依赖是这样的:
"dependencies": {
"lodash": "^3.1.0"
}
1
2
3
根据前面的介绍我们可以知道,这表示只接受小版本或者补丁版本的更新,因此在执行了一次 
npm update
 后它变成了这样:
"dependencies": {
"lodash": "^3.10.1"
}
1
2
3
第二位升到了最高,但是无法更新第一位,因此无法更新到最新的 4.17.4。所以我需要把它修改成:
"dependencies": {
"lodash": "*"
}
1
2
3
这表示任何版本的更新都接受,然后再执行 
npm update
,就发现更新成功了:

小结一下:执行 
npm outdated
 后可以看到有三个版本号:

第一个是当前 node_modules 中该模块的版本,第二个是 
package.json
 文件中声明的版本,第三个是远程仓库最新的版本。只有当前模块版本低于远程,package.json 中的版本语义规则满足情况,才能更新成功。

卸载本地 package

卸载一个本地 package 很简单,
npm uninstall <package-name>
 即可:

官方文档说输入 
npm uninstall --save lodash
 才能在删除项目的同时移除 
package.json
 中对它的依赖。但我没加 
--save
 也达到了一样的效果,一脸懵逼。卸载后再 
ls node_modules/
 查看目录下,发现没有东西,删除成功。

全局安装 package

如果你想要直接在命令行中使用某个包,比如 
jshint
 ,你可以全局安装它。全局安装比本地安装多了个 
-g
:
npm install -g <package-name>
1
以 
jshint
 为例,全局安装命令是:
npm install -g jshint
1


安装后可以使用 
npm ls -g --depth=0
 查看安装在全局第一层的包。

全局安装的权限问题

在全局安装时可能会遇到 
EACCES
 权限问题,解决办法办法有如下 3 种:1.
sudo npm install -g jshint
,使用 
sudo
 简单粗暴,但是治标不治本2.修改 npm 全局默认目录的权限先获取 npm 全局目录:
npm config get prefix
,一般都是 
/usr/local
; 
然后修改这个目录权限为当前用户:
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
1
3.使用其他包管理器帮你解决这个问题实在懒得弄可以直接卸载 node,然后使用 Homebrew 重装 node:
brew install node
1
Homebrew 会帮我们处理好权限的问题。

更新全局的 package

想知道哪些包需要更新,可以使用 
npm outdated -g --depth=0
,然后使用 
npm update -g <package>
更新指定的包:

要更新所有全局包,可以使用 
npm update -g
,可以发现对比本地的,只是多了个 
-g
。不过官方说在 2.6.1 以下的 npm ,直接使用 
npm update -g
 并不安全,因为它会递归地更新所有全局依赖。这种情况下可以使用 
npm-check
 ,贴一张它的截图:

Github 地址:https://github.com/dylang/npm-check

卸载全局 package

一句搞定:
npm uninstall -g <package>

其他命令

npm run

部分摘自 阮一峰的 NPM 教程npm 还可以直接运行 
package.json
 中 
scripts
 指定的脚本:
{
"name": "demo",
"scripts": {
"lint": "jshint **.js",
"test": "mocha test/"
}
}
1
2
3
4
5
6
7
npm run 是 npm run-script 的缩写。命令行输入 
npm run lint
 或者 
npm run-script lint
 就会执行 
jshint **.js
 。
npm run
 会创建一个Shell,执行指定的命令,并临时将node_modules/.bin加入PATH 变量,这意味着本地模块可以直接运行。
package.json
 中的 
scripts
 执行的脚本是本地项目内 
node_modules
 -> 
.bin
 内的脚本。
"scripts": {
"build": "weex-builder src dist",
"build_plugin": "webpack --config ./tools/webpack.config.plugin.js --color",
"dev": "weex-builder src dist -w",
"serve": "serve -p 8080"
}
1
2
3
4
5
6


直接运行 
npm run
 会列出当前项目的 
package.json
 中 
scripts
 属性下的所有脚本命令。

npm install from github

npm install 也可以直接从 github 下载:
$ npm install git://github.com/package/path.git
$ npm install git://github.com/package/path.git#0.1.0
1
2

npm info

npm info <package-name>
 可以查看指定包的信息:

npm adduser

npm adduser
 用于在npmjs.com注册一个用户:
$ npm adduser
Username: YOUR_USER_NAME
Password: YOUR_PASSWORD
Email: YOUR_EMAIL@domain.com
1
2
3
4

npm home/repo

npm home <package-name>
命令可以打开指定模块的主页; 
npm repo <package-name>
命令则是打开指定模块的代码仓库。

npm prune

prune 即“修剪”的意思。
npm prune
 可以检查出当前项目的 
node_modules
目录中,没有在 
package.json
里提到的模块。

npm publish

现在水平还不够,等写出可以复用的 JS 代码后,我们就可以将它发布到 npm 仓库上,类似 Github 的提交。这部分主要摘自阮一峰的 NPM 教程要想发布,首先需要使用 
npm adduser
向 
npmjs.com
申请用户名(当然去官网也可以)。接着使用 
npm login
 在命令行中登录。登录以后,就可以使用 
npm publish
命令发布。
$ npm publish
1
2
如果当前模块是一个beta版,比如1.3.1-beta.3,那么发布的时候需要使用tag参数,将其发布到指定标签,默认的发布标签是latest。
$ npm publish --tag beta
1
2
如果发布私有模块,模块初始化的时候,需要加上scope参数。只有npm的付费用户才能发布私有模块。
$ npm init --scope=<yourscope>
1
2
如果你的模块是用ES6写的,那么发布的时候,最好转成ES5。首先,需要安装Babel。
$ npm install --save-dev babel-cli@6 babel-preset-es2015@6
1
2
然后,在
package.json
里面写入
build
脚本。
"scripts": {
"build": "babel source --presets babel-preset-es2015 --out-dir distribution",
"prepublish": "npm run build"
}
1
2
3
4
5
运行上面的脚本,会将source目录里面的ES6源码文件,转为distribution目录里面的ES5源码文件。

国内镜像

不翻的话有时候 npm 比较卡,可以使用国内的淘宝镜像 cnpm: https://npm.taobao.org
cnpm
 支持 
npm
 除了 
publish
 之外的所有命令。

总结


经过这么一番总结,总算可以说 npm 入门了。接触前端后发现这个圈子太复杂了,各种工具各种框架,眼花缭乱啊。一步一步来吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  npm  package.json