package.json简介
1.概述
如果你项目里的模块,都是用npm来管理的,那么在这个项目的根目录下,肯定有一个package.json文件,它定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,将package.json中的模块安装到node_modules文件夹下,也就是配置项目所需的运行和开发环境。
生成package.json文件
package.json文件可以手工编写,也可以使用npm init命令自动生成。这个命令采用互动方式,要求用户回答一些问题,然后在当前目录生成一个基本的package.json文件。所有问题之中,只有项目名称(name)和项目版本(version)是必填的,其他都是选填的。
如果你一路按回车确认感觉有些麻烦,你可以直接加一个-y参数,这样npm就直接给我们生成了,即npm init -y。有了package.json文件,直接使用npm install命令,就会在当前目录中安装所需要的模块。
如果一个模块不在package.json文件之中,可以单独安装这个模块,并使用相应的参数,将其写入package.json文件之中。
npm install express --save
npm install express --save-dev
说明:--save 会把依赖包名称添加到 dependencies(运行时依赖) 键下,--save-dev 则添加到devDependencies(开发时依赖) 键下。正常使用npm install时,会下载dependencies和devDependencies中的模块,当使用npm install –production或者注明NODE_ENV变量值为production时,只会下载dependencies中的模块。
补充说明:运行时依赖和开发时依赖刚开始不太容易理解,简单补充一下;小明参加了一场马拉松比赛(正在开发一个项目),为了让自己能够吸引别人的注意(写个好看的项目),他买了一套很有个性的衣服(在项目中用了一个著名的第三方插件A)。他和其他参赛者一样,需要跑完全程,并分出1、2、3名;(如期完成项目,并评估项目质量)。结果先放一边,先来分析什么是开发时。衣服有很多,所以他完全可以“这套不行,换那套”。无论他换什么衣服,都不影响他跑马拉松(写完项目);换言之,第三方插件多半是可以找到替代品的,它只是在跑步时(开发时)起到一定作用;跑完后(项目完工,打包),就没用了,这就是开发时依赖;运行时依赖就好说了,小明的鞋子就是一个运行时依赖;他可以不穿鞋跑马拉松吗?那他的脚肯定废了(这个项目是用vue写的,那它能把vue相关的东西全删掉?那项目肯定就废了)。这两种依赖的侧重点不同,但并不适合去比较两者;因为小明如果跑得慢,也不会是鞋的错,如果你对裸奔这种事情毫无感知的话。跑得快也不会是衣服拉风,有种你试试不穿鞋去跑。相辅相成的存在。
提示:package.json里面不能有注释,否则会报错
2.name
你的模块名称
3.version
项目版本
4.description
一个描述,方便别人了解你的模块作用,搜索(npm search)的时候也有用,格式为字符串。
5.keywords
关键字。方便使用者在 npm search中搜索。格式为字符串。
6.scripts字段
npm 允许在package.json文件里面,使用scripts字段定义脚本命令。
{
// ...
"scripts": {
"build": "node build.js",
"preinstall": "echo here it comes!"
}
}
上面代码build命令对应的脚本是node build.js。
命令行下使用npm run命令,就可以执行这段脚本。
npm run build
// 等同于执行
node build.js
这些定义在package.json的命令(scripts)就称为 npm 脚本。查看当前项目的所有 npm 脚本命令,可以使用的npm run命令。
值得留意的是,上面的npm脚本是自定义的;它还有些内置的脚本命令。当然,都是要提前定义的;最大的特点就是那几个内置命令不需要 run,比如 npm start
7.dependencies字段
dependencies字段指定了项目运行所依赖的模块,格式为对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
"dependencies": {
"browserify": "13.0.0",
"karma-browserify": "~5.0.1",
"element-ui": "^1.2.2",
"vue": "latest"
}
版本格式如下:
- 指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
- 波浪号指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
- 插入号指定版本:比如^1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
- latest:安装最新版本。用命令行的写法:
npm install jquery@latest
8.devDependencies字段
devDependencies指定项目开发所需要的模块,格式为对象。该对象的各个成员和dependencies字段的相同。
9.engines 字段
指明了该项目所需要的node.js版本。也可以指定适用的npm版本
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
10.Repository字段
用于指示源代码存放的位置
"repository" :{
"type" : "git",
"url" : "http://github.com/npm/npm.git"
}
// or
"repository" :{
"type" : "svn",
"url" : "http://v8.googlecode.com/svn/trunk/"
}
11.browserslist
处理CSS属性前缀的插件,最知名的就是Autoprefixer了,用来兼容各种浏览器;它使用Browserlist来确定哪些浏览器版本将得到支持从而添加前缀。格式为数组。
"browserslist": [
"> 1%", //全球有超过1%的人使用的浏览器
"last 2 versions", //根据CanIUse.com追踪的最后两个版本的所有浏览器
"not ie <= 8" // 不支持ie8及以下
]
12.private
设为true:意为私有模块儿;这个包将不会发布到npm平台下。
13.sideEffects
将文件标记为无副作用。比如有一个js文件,它导出了一个函数
export function func () {
// do something
}
但是没有在任何地方 import 这个方法。在用webpack打包后,可以找到这样的一个注释:/* unused harmony export func */
所以这时应该在打包时,删掉没有 import 的方法;就可以写成下面这样:
{
"name": "your-project",
"sideEffects": false
}
在 import 时,会存在一些有副作用的代码的;副作用的定义(来自webpack官方定义):在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export,会影响全局作用域;如果某些文件,有这种情况;就可以写成这样:
{
"name": "your-project",
"sideEffects": [
// 有副作用的文件路径字符串
]
}
13.bin
这个字段的作用相比前面的,可能是最有意思的了。因为它提供了命令行编程的能力;看下面代码
"bin": {
"demo": "./bin/index.js"
}
这样写的意思,就是自定义一个demo命令;只要在命令行里面输入demo,它就会去执行当前项目下,bin目录中的index.js文件;这里强调一下,其实就算是index.txt也是可以执行的;这里写成js无非想让人觉得更加的亲切,流行的写法都是不写后缀的,就一个文件名。因为如果在需要执行的文件里面,不加入一个特殊的语句,是执行不了的。假设bin目录下有这个一个index.js文件
#!/usr/bin/env node
console.log('欧耶,前端也可以写命令行编程耶')
注意第一句话,它的作用就是让这个文件有在node环境下执行的能力;但是这样还不够。最后一步,在项目的根目录下,执行
$ npm link
这个命令,就可以将你自定义的命令链接到全局环境;以至于你在任何地方,打开cmd窗口时,执行你的自定义命令都是可以运行这个文件的;注意了,只要有那第一句话,执行的文件要不要后缀都无所谓的;它只会被node当成一个js去执行。再结合node的环境变量,给你的自定义命令传参,可以实现一些好玩的自动化的工具。