NPM Magic

NPM Magic

package.json

  • package.json 最起码要包含 nameversion
  • 快速初始化 package.json: npm init --yes
  • dependencies: 生产环境依赖的包 * devDependencies: 开发、测试环境依赖的包

packages version management

install

npm install moment,
ornpm install moment --save,
ornpm install moment --save-dev

view

npm outdated

NPM Magic_第1张图片

uninstall

npm uninstall moment,
ornpm uninstall --save moment

packages version controll

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 scripts

我们可以通过 npm run myScript 来通过 npm 运行一个脚本或命令:

"scripts": {
    "start": "node index.js"
}

usage

以下 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"

arguments

向 npm script 传递参数时,用 -- 表明。

"test": "mocha test/*.js",传参 npm test -- --grep 'my test',相当于 "test": "mocha test/*.js --grep 'my test'"

environment - path

npm run 会将当前 node_modules / .bin 目录加入 PATH 变量, 执行结束后再恢复PATH, 如果本目录下已安装的 module 有可执行脚本,我们可以直接使用。不必全局安装或者使用 / node_modules / .bin 路径:

"test": "mocha test/*.js"

不需要全局安装 mocha 或者 . / node_modules / .bin / mocha test/*.js

environment - variables of package.json

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

environment - npm configuration

我们可以通过 npm_config_ 前缀访问 npm configuration。

例如:npm config get userconfig 输出为 /home/ubuntu/.npmrc,可以通过环境变量访问 "test": "echo $npm_config_userconfig"

hook

npm 脚本有 prepost 两个钩子。

"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"

execution sequence

  • & 并行执行, 如 npm run lint & npm run tsc
  • && 串行执行, 如 npm run lint && npm run test

wildcards

npm script 中可以使用 shell 通配符。

  • * 代表任意文件, 如 "test": "mocha test/*.js"
  • ** 代表任意目录, 如 "test": "mocha test/**/*.js "

exiting

如果 npm script 的 exit code 不是 0, 会认为执行失败, 终止进程。

practical usage

with docker

背景:

  • 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 .

原文

你可能感兴趣的:(Node.js,杂货)