- package.json 最起码要包含
name
和version
- 快速初始化 package.json:
npm init --yes
dependencies
: 生产环境依赖的包 *devDependencies
: 开发、测试环境依赖的包
npm install moment
,
ornpm install moment --save
,
ornpm install moment --save-dev
npm outdated
npm uninstall moment
,
ornpm uninstall --save moment
npm 中的模块版本都需要遵循 semver规范, 1.2.3
: 1 主版本号, 2 次版本号, 3 补丁号
dependencies: {
"bunyan": "1.x",
"lodash": "*",
"express": "~4.0.0",
"ava": "0.16.0"
}
*
: 任意版本1.1.1
: 指定版本~1
: >= 1.0.0 && < 2.0.0(相当于1.x)~1.1
: >= 1.1.0 && < 1.2.0(相当于1.1.x)~1.1.0
: >= 1.1.0 && < 1.2.0(相当于1.1.x)^1.2.3
: >= 1.2.3 < 2.0.0^0.0.3
: >= 0.0.3 < 0.0.4^0.0
: >= 0.0.0 < 0.1.0^0.x
: >= 0.0.0 < 1.0.0
^
和~
:
~
前缀表示,安装大于指定的这个版本,并且匹配到 x.y.z 中 z 最新的版本^
前缀在^0.y.z
时的表现和~0.y.z
是一样的,然而^1.y.z
的时候,就会匹配到 y 和 z 都是最新的版本
我们可以通过 npm run myScript
来通过 npm 运行一个脚本或命令:
"scripts": {
"start": "node index.js"
}
以下 script 可以直接 npm xxx
运行,可以不加 run
:
- prepublish: Run BEFORE the package is published.(Also run on local npm install without any arguments.)
- publish, postpublish: Run AFTER the package is published. * preinstall: Run BEFORE the package is installed
- install, postinstall: Run AFTER the package is installed. * preuninstall, uninstall: Run BEFORE the package is uninstalled. * postuninstall: Run AFTER the package is uninstalled.
- preversion, version: Run BEFORE bump the package version. * postversion: Run AFTER bump the package version.
- pretest, test, posttest: Run by the npm test command.
- prestop, stop, poststop: Run by the npm stop command.
- prestart, start, poststart: Run by the npm start command.
- prerestart, restart, postrestart: Run by the npm restart command.Note: npm restart will run the stop and start scripts if no restart script is provided.
例如,typescript 写的 module 如果要发布到 npm,可以使用 prepublish
,在 npm publish
之前会先执行 tsc
命令:
"scripts": {
"prepublish": "tsc"
}
npm 对两个脚本提供了默认值,可以不定义直接使用:
"start": "node server.js"
"install": "node-gyp rebuild"
向 npm script 传递参数时,用 --
表明。
如 "test": "mocha test/*.js"
,传参 npm test -- --grep 'my test'
,相当于 "test": "mocha test/*.js --grep 'my test'"
。
npm run
会将当前 node_modules / .bin
目录加入 PATH
变量, 执行结束后再恢复PATH
, 如果本目录下已安装的 module 有可执行脚本,我们可以直接使用。不必全局安装或者使用 / node_modules / .bin
路径:
"test": "mocha test/*.js"
不需要全局安装 mocha
或者 . / node_modules / .bin / mocha test/*.js
。
package.json 中的字段都可以通过 npm_package_
前缀访问。
例如 package.json:
{
"name": "test",
"version": "1.0.0",
"scripts": {
"go": "node index.js"
}
}
index.js:
console.log(process.env.npm_package_name);
console.log(process.env.npm_package_version);
npm run go
输出:
test
1.0.0
我们可以通过 npm_config_
前缀访问 npm configuration。
例如:npm config get userconfig
输出为 /home/ubuntu/.npmrc
,可以通过环境变量访问 "test": "echo $npm_config_userconfig"
npm 脚本有 pre
和 post
两个钩子。
"prego": "echo 'before go'",
"go": "node index.js",
"postgo": "echo 'after go'",
npm run go
会顺序执行 npm run prego
=> npm run go
=> npm run postgo
。
利用 hook 可以做一些准备和清理操作:
"lint": "tslint 'src/*.js'",
"prebuild": "npm run lint",
"build": "tsc"
&
并行执行, 如npm run lint & npm run tsc
&&
串行执行, 如npm run lint && npm run test
npm script 中可以使用 shell 通配符。
*
代表任意文件, 如"test": "mocha test/*.js"
**
代表任意目录, 如"test": "mocha test/**/*.js "
npm script 执行 bash 命令
"bash": "echo $(pwd)",
npm run bash
> [email protected] bash /data/data/dongss/tmp
> echo $(pwd)
/data/data/dongss/tmp
如果 npm script 的 exit code 不是 0, 会认为执行失败, 终止进程。
背景:
- typescript 项目
- docker 交付和部署
npm script:
...
"build ": "tsc ",
...
最开始的 dockerfile:
FROM mynode:6.0
...
RUN npm --registry=http://registry.npm.taobao.org install
RUN npm run build
...
CMD ["npm ", "start "]
痛点:
每次都要安装依赖,某几个依赖需要编译,如 zookeeper, 甚至下载官方nodejs镜像,很不稳定。总结,有风险且速度慢。
改进思路:
- 构建一个专门用来安装依赖和编译 typescript 的镜像,做到:更换了编镜像的机器或项目新增加了依赖时才会下载。
- 将 npm 依赖和编译后的 js 代码 copy 进镜像
修改项目 npm script:
"prebuild": "npm --registry=http://registry.npm.taobao.org install",
"build": "tsc",
专门用来 build 的镜像, my-build:latest:
# 必须和项目完全相同的父镜像
FROM mynode:6.0
RUN mkdir /app
WORKDIR /app
修改项目的 dockerfile:
FROM mynode:6.0
...
# 不再每次构建镜像时安装依赖, 而是 copy 进去
COPY node_modules /app/node_modules
# RUN npm --registry=http://registry.npm.taobao.org install
# RUN npm run build
...
CMD ["npm ", "start "]
编译项目镜像时:
docker pull my-build:latest
docker run --rm=true -v ${PROJECT_DIR}:/app my-build:latest npm run build
docker build my-project:mytag .