## 【译】package.json的使用
> Tips:package.json这一章比较重要,所以,我对npm官方文档[Using a package.json](https://docs.npmjs.com/getting-started/using-a-package.json) 这一小节在个人理解的基础上做了翻译,你也可以直接查看[官方文档](https://docs.npmjs.com/getting-started/using-a-package.json)。
[TOC]
管理本地安装的包的最好方法是创建一个`package.json`文件。
**`package.json`文件会给你提供很多好东西:**
1. 它是你这个工程的基础依赖和基本信息描述的集合。
2. 它允许你使用语义化版本管理规则,指定项目中能使用的包的版本。
3. 使你的构建版本可以重新生成,方便你与其他开发者分享代码。
### 必要项
`package.json `必须包括以下几项:
* **"name"**
* 全部为小写字母
* 一个单词,无空格
* 允许半角破折号和下划线
* **"version"**
* 格式为 x.x.x
* 遵循语义化版本号规则 [semver spec](https://docs.npmjs.com/getting-started/semantic-versioning)
示例:
~~~
{
"name": "my-awesome-package",
"version": "1.0.0"
}
~~~
只要有这两项,就可以创建一个最简单的node 模块
### 创建package.json文件
`$ npm init [-f|--force|-y|--yes]`
npm init是初始化项目命令,会在你运行此命令的文件夹根目录下创建项目配置文件`package.json`。同时,在命令行,程序会依次提示你输入。这些问题最终会记录到`package.json`文件中。
当你在命令行输入`npm init`命令时,它会向用户提问一系列问题,如果不用修改默认配置,一路回车就可以了,这些问题最终会记录到`package.json`文件中。
在命令行回答问题这个过程不是必须的,你可以在后面添加 `-f`(即在命令行输入 `npm init -f`)跳过回答问题的过程,这时,程序会使用默认值直接生成`package.json`文件。`npm init` 有4个可选参数,这里,其他3个参数(`--force、-y、--yes`)的效果和 `-f`是一样的。
生成的`package.json`如下(npm版本不同,`JSON`字段会有不同):
~~~
{
"name": "my_package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"repository": {
"type": "git",
"url": ""
},
"bugs": {
"url": ""
},
"homepage": ""
}
~~~
* name:模块的名称,默认值是作者名字(如果有设置),除非在git目录中,它会是git仓库的名字,否则,为当前所在文件夹的名称,当你将这个模块发布之后,其他开发者就可以通过搜索这个名称找到你发布的模块。
* version:版本号,刚初始化的项目总是1.0.0;
* description: 模块描述,默认为空,当你发布模块时,npm将使用README.md 或者README的第一行来描述,这个描述可以方便其他开发者找到你的模块,提高模块被其他开发者发现的概率。
* main:默认为index.js;
* scripts:默认创建一行空的测试脚本;(这里可以先适当囫囵吞枣)
* keywords:搜索关键字,默认为空,版本发布的时候,建议写上,方便其他开发者搜索
* author:作者
* license:默认为ISC开源证书
* repository: 如果你有把这个模块托管到git仓库(比如github),这里可以填写这个URL地址
* bugs: bug反馈地址(也是针对像在github做了代码托管的模块),默认为空
* homepage: 作者主页默认为空
你也可以通过set命令来设置npm init过程的默认值。比如下边的这些:
> npm set init.author.email "wombat@npmjs.com"
npm set init.author.name "ag_dubs"
npm set init.license "MIT"
### 自定义npm init过程
除了设置`npm init`的默认值,你还可以完全自定义`npm Init` 整个过程。只需要在用户目录下,创建一个`.npm-init.js`文件,然后在`.npm-init.js`中编写代码即可。你可以像下面这样编写`.npm-init.js`
~~~
module.exports = {
customField: 'Custom Field',
otherCustomField: 'This field is really cool'
}
~~~
你也可以自定义在`npm init`过程中命令行提问的问题,这时,你需要用到prompt方法,写法如下:
```
module.exports = prompt("what's your favorite flavor of ice cream buddy?", "I LIKE THEM ALL");
```
更多自定义npm init过程的细节可以参考[init-package-json](https://github.com/npm/init-package-json)
### 指定依赖包
你开发的模块很多时候需要引入其他开发者开发的第三方模块,这个时候,你需要在`package.json`中输入引入所有需要的模块,你可以通过以下两种方式来实现:
* dependencies: 这些模块是你开发的模块的依赖项,没有这些模块你的代码就会报错
* devDependencies: 这些模块只在开发环境下使用,比如`jshint、grunt`等开发过程中的辅助工具
你可以直接用IDE打开package.json文件,然后手动编辑,其格式如下:
~~~
{
"name": "my_package",
"version": "1.0.0",
"dependencies": {
"my_dep": "^1.0.0"
},
"devDependencies" : {
"my_test_framework": "^3.1.0"
}
}
~~~
不过,我们一般不会通过手动编辑`package.json`来引入第三方模块,而是通过`--save 和 --save-dev`这两个安装标记来实现,这是添加依赖到你的package.json文件的更简单(也更酷)的方式。
添加`package.json`依赖的入口(即执行该命令之后,第三方模块会被写入到`dependencies`字段中):
`$ npm install <package_name> --save`
添加package.json开发环境依赖的入口(即执行该命令之后,第三方模块会被写入到`devDependencies`字段中):
`$ npm install <package_name> --save-dev`
dependencies和devDependencies的成员都必须按照`“模块名称”:"模块版本"`来编写,
`模块版本`的写法遵从语义化版本管理的规则。
### 管理依赖包的版本
`npm`使用语义化版本管理依赖包,也就是我们常说的“SemVer”。
如果在项目文件夹下存在`package.json`文件,你在此文件夹下运行命令`npm install`,npm就会检查文件中列出的依赖包,并下载所有满足语义化规则的最新版本的依赖包。
语以化版本号的内容不是本教程的重点,请参考[语义化版本控制](http://www.tuicool.com/articles/JnmuE3R)