介绍
在nodejs中,我们必然会与package.json文件打交道,本文就是介绍package.json中的各个属性的具体含义与用法。
生成方式
package.json文件的生成方式有两种:
- 手动编辑
- 使用命令行生成
属性介绍
必须属性
- name:姓名
- version:版本号
描述信息
- description:描述信息
- keywords:关键词
- author:作者
- contributors:贡献者
- homepage:主页
- repository:仓库
- bugs:BUG反馈地址
依赖配置
- dependencies:生产环境依赖
- 使用命令 npm install xxx | npm i xxx | npm install xxx --save时将包添加至生产环境
- devDependencies:开发环境依赖
- 使用命令 npm install xxx -D | npm i xxx -D | npm install xxx --save-D | npm install xxx --save-dev时将包添加至开发环境
- peerDependencies:兼容依赖
- optionalDependencies:不阻断安装依赖
- bundledDependencies:打包依赖
- engines:版本要求
- engines只是起到一个说明的作用,即使用户安装的版本不符合要求,也不影响依赖包的安装
脚本配置
- scripts:脚本命令
- 代码示例
"scripts": { "build": "node build.js" }- 注:以上执行npm run build 就相当于执行 node build.js
- 这些定义在package.json里面的脚本,就称之为npm脚本
- 优点
- 项目的相关脚本,可以集中在一个地方
- 不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要怎么测试你的项目,只要运行npm run test即可
- 可以利用npm提供的许多辅助功能
- 相关命令
- npm run: 查看所有npm脚本命令
- 原理
- 每当执行npm run,就会自动新建一个Shell,在这个Shell里面执行指定的脚本命令
- 只要是Shell可以运行的命令,就就可以写在npm脚本里面
- npm新建的Shell,会将当前目录node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样,所以,再node_modules/.bin子目录里面的所有脚本,都可以直接使用脚本名调用,而不用加上路径
- 由于npm脚本的唯一要求是可以再Shell执行,因此它不一定是Node脚本,任何可执行文件都可以写在里面。
- 使用技巧
- 通配符
- 由于npm脚本是Shell脚本,所以可以使用Shell通配符
- 如果要将通配符传入原始命令,防止被Shell转义,要将星号转义
- 代码示例
"lint": "jshint *.js" "lint": "jshint **/*.js" "test": "tap test/\*.js"
- 传参
- 向npm脚本传入参数,要使用--标明
- 代码示例
"lint": "jshint **.js" //传参调用 npm run lint -- --reporter checkstyle > checkstyle.xml //该过程也可以直接在package.json文件中直接封装成一个命令 "lint": "jshint **.js" "lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"
- 执行顺序
- 如果npm脚本里面需要执行多个任务,那么需要明确执行顺序
- 并行执行(平行执行)
- 使用 & 符号
- 代码示例
npm run script1.js & npm run script2.js
- 继发执行(一个任务完成后,才能执行下一个任务)
- 使用 && 符号
- 代码示例
npm run script1.js && npm run script2.js
- 注:这两个符号是Bash的功能。此外,还可以使用node的任务管理模块:
- script-runner
- npm-run-all
- redrun
- 简写
- 四个常用的npm脚本有简写
- npm start <---> npm run start
- npm stop <---> npm run stop
- npm test <---> npm run test
- npm restart <---> npm run stop && npm run restart && npm run start的简写
- npm restart是一个复合命令、实际会执行三个脚本命令:stop、restart、start,执行顺序如下
- prerestart -> prestop -> stop -> poststop -> restart -> prestart -> start -> poststart -> postrestart
- 四个常用的npm脚本有简写
- 通配符
- 默认值
- 一般来讲,npm脚本由用户提供,但是,npm对两个脚本提供了默认值。即这两个脚本不用定义,就可以直接使用
- 默认脚本
"start": "node server.js", "install": "node-gyp rebuild" - 解析
- npm run start的默认值是node server.js,前提是项目根目录下由server.js这个脚本
- npm run install的默认值是node-gyp rebuild,前提是项目根目录下由binding,gyp文件
- 钩子
- npm脚本有pre和post两个钩子。
- 用户在执行npm run build的时候,会自动执行下面的顺序
- npm run prebuild && npm run build && npm run postbuild
- 通常在这两个钩子里面,完成一些准备工作和清理工作。
- 自定义的脚本命令也可以加上pre和post钩子
- 例如: myscript这个脚本命令,也有premyscript和postmyscript钩子
- 注意:双重的pre和post是无效的,例如prepretest和postposttest是无效的
- npm提供了一个npm_lifecycle_event变量,返回当前正在运行的脚本名称,比如pretest、test、posttest等等。
- 在同一个脚本文件中,为不同的npm scripts命令编写代码
const TARGET = process.env.npm_lifecycle_event if(TARGET === 'test'){ console.log('Running the test task!') } if(TARGET === 'pretest'){ console.log('Running the pretest task!') } if(TARGET === 'posttest'){ console.log('Running the posttest task!') }
- 在同一个脚本文件中,为不同的npm scripts命令编写代码
- 注意:
- prepublish钩子问题
- npm4中:
- prepublish不仅会在npm publish命令之前运行,还会在npm install (不带任何参数)命令之前运行。
- 在npm4中引入一个新的钩子prepare,行为等同于prepublish
- npm5中:
- prepublish将只在npm publish命令之前运行
- npm4中:
- 钩子问题不仅仅在脚本中有,install,uninstall等也有
- prepublish钩子问题
- 变量
- npm脚本有个很强大的功能,就是可以使用npm的内部变量,通过npm_package_前缀,npm脚本可以拿到package.json里面的字段。
- 获取方式
- process.env.npm_package_xxx
- 代码示例
console.log('获取的项目名称:', process.env.npm_package_name)
- 代码示例
- 嵌套的package.json字段
- 代码示例
console.log('获取的嵌套内容:', process.env.npm_package_config_port)
- 代码示例
- process.env.npm_package_xxx
- 使用env命令可以列出所有环境变量
- 常用脚本示例
//删除目录 "clean": "rimraf dist/*", //本地搭建一个HTTP服务 "serve": "http-server -p 9090 dist/", //打开浏览器 "open:dev": "opener http://localhost:9090", //实时刷新 "livereload": "live-reload --port 9091 dist/", //构建HTML文件 "build:html": "jade index.jade > dist/index.html", //只要CSS文件有变动,就重新执行构建 "watch:css": "watch 'npm run build:css' assets/styles/", //只要HTML文件有变动,就重新执行构建 "watch:html": "watch 'npm run build:html' assets/html", //部署到Amazon S3 "deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/", //构建favicon "build:favicon": "node scripts/favicon.js",
- 代码示例
- config:配置命令行环境变量
- 个人理解,创建一些环境变量给脚本使用
文件&目录
- main:指定加载的入口文件,在browser和Node环境中都可以使用
- 如果我们将项目发布为npm包,那么当使用require导入该npm包时,会去main定义的路径的文件的module.exports属性。
- 如果不指定该字段,默认时项目根目录下的index.js,如果没有找到,就会报错。
- browser:定义npm包在browser环境下的入口文件
- 如果npm包只在web端使用,并且严禁在server端使用,使用browser来定义入口文件
- module:定义npm包的ESM规范的入口文件
- browser环境和node环境均可使用
- .js文件是使用commonJS规范的语法(require('xxx)), .mjs是使用ESM规范的语法(import 'xxx')
- bin:指定各个内部命令对应的可执行文件的位置
- files:当把npm包作为依赖包安装时需要说明的文件列表
- man:查看Linux中的指令帮助、配置文件帮助和编程帮助
- directories:规范项目的目录
- 这个属性实际上没有什么实际作用,但是不排除将来会有什么比较有意义的用处
发布配置
- private:防止意外的将私有库发布到npm服务器
- preferGlobal:当用户不把该模块安装为全局模块时,该属性设置为true的情况下就会显示警告
- publishConfig:配置会在模块发布时生效,用于设置发布时一些配置项的集合
- os:设置npm包可以在什么操作系统使用
- cpu:限制用户的安装环境
- license:指定软件的开源协议
第三方配置
- typings:用来指定 TypeScript 的入口文件
- eslintConfig:eslint 的配置可以写在单独的配置文件. eslintrc.json 中,也可以写在 package.json 文件的 eslintConfig 配置项中
- babel:用来指定 Babel 的编译配置
- unpkg:使用该字段可以让 npm 上所有的文件都开启 cdn 服务
- lint-staged:是一个在 Git 暂存文件上运行 linters 的工具,配置后每次修改一个文件即可给所有文件执行一次 lint 检查,通常配合 gitHooks 一起使用
- gitHooks:用来定义一个钩子,在提交(commit)之前执行 ESlint 检查。
- browserslist:用来告知支持哪些浏览器及版本