npm和package.json那些不为常人所知的小秘密

此文已由做者黄锴受权网易云社区发布。
javascript

欢迎访问网易云社区,了解更多网易技术产品运营经验。css


强大的命令功能

若是你没使用过script,那你可算是历来没手动编辑过package.json。script做为package.json里最强大的功能,它赋予你新增脚本的能力。特别是从npm@2.0.0 以后,你能够用自定义参数执行脚本。甚至有人宣言,有了npm你能够中止使用Grunt和Gulp了html

查询脚本

你能够经过输入npm run查看全部的命令列表(虽然你也能够直接查看package.json)java

image-20181023103906319

自定义脚本

例如咱们最经常使用的npm start,npm run dev ……,这些脚本都是能够用户自定义的,只用在scripts中写相应的shell脚本,能够快速的帮助咱们编写打包,启动脚本。node

"scripts": {    "build": "webpack --config build.js",    "start": "node index.js",    "test": "tap test/*.js"}

而后你能够经过npm run ...执行 注意,start命令能够不用run,后面会讲react

同时,执行脚本的时,npm会临时自动将目录的node_modules/.bin加入PATH变量。这意味着,可使用node_modules中任何脚本,而无需添加node_modules/.bin前缀。好比,当前项目的依赖里面有 Mocha,只要直接写mocha test就能够了。linux

例如执行tap命令,你能够直接写:webpack

"scripts": {"test": "tap test/\*.js"}

而不是git

"scripts": {"test": "node_modules/.bin/tap test/\*.js"}

传递参数

若是咱们在执行npm run xxx 操做的时候想给里面的脚本传参数可使用—,以下所示:github

 "scripts": {    "test": "mocha test/",    "test:xunit": "npm run test -- --reporter xunit"
  }

这种设置对于组合一些高级配置的命令是很是有用的。

“scripts”: {    "lint": "jshint **.js",    "lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"}

生命周期钩子

这里借用不少框架的生命周期钩子的概念,其实npm也在不一样的生命周期 提供了一些钩子,能够方便你在项目运行的不一样时间点进行一些脚本的编写。

它的钩子分为两类:pre- 和 post- ,前者是在脚本运行前,后者是在脚本运行后执行。全部的命令脚本均可以使用钩子(包括自定义的脚本)。

例如:运行npm run build,会按如下顺序执行:

npm run prebuild -->  npm run build -->  npm run postbuild

pre脚本和post脚本也是出口代码敏感(exit-code-sensitive) 的,这意味着若是您的pre脚本以非零出口代码退出,那么NPM将当即中止,而且不运行后续脚本。

一般你能够在pre脚本上执行一些准备工做,在post脚本上执行一些后续操做。

"clean": "rimraf ./dist && mkdir dist","prebuild": "npm run clean","build": "cross-env NODE_ENV=production webpack"

另外,还有不少额外的生命周期钩子,能够方便使用,例如husky  和 pre-commit 包提供了有关git的commit的生命周期钩子。

使用环境变量

根据官网的介绍 ,在"scripts"中编写的脚本还能够方便使用一些内置变量,这些内置变量会在Node运行的时候放在process.env下,若是是shell脚本,就直接使用环境变量$…,  这对你编写一些脚本工具特别有用。

package.json

package.json内的全部的配置项均可以经过npm_package_前缀拿到,例如

"show": "echo $npm_package_name && echo $npm_package_version"

若是是使用node:

"show": "node ./show.js"
// show.jsconst { log } = console;
log(process.env.npm_package_name);
log(process.env.npm_package_version);

image-20181024114103465

嵌套的属性也能够经过_代替.进行嵌套显示:**$npm_package_scripts_start**

configuration

配置参数放在**npm_config_**前缀的环境中(你能够经过 npm config set 设置一些配置变量,下面介绍config的时候会介绍)

例如:

image-20181030105015315

一些经常使用的脚本配置

这里引用阮老师的一些配置,能够看到配合必定的插件,npm但是实现一些很实用的功能

// 删除目录"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",

npx

npm v5.2.0 以后还引入了npx,引入这个命令的目的是为了提高开发者使用包内提供的命令行工具的体验。(在node_modules中,全部可执行文件,也就是package中带bin的,都会放在node_modules/.bin中)

举例:使用create-react-app建立一个react项目。

老方法:

npm install -g create-react-app   // 实际就是把package.json中的bin命令链接到了/usr/local/bin中create-react-app my-app

npx方式:

npx create-react-app my-app // 执行本`node_modules/.bin`中的对应命令

这条命令会临时安装 create-react-app 包,命令完成后create-react-app 会删掉,不会出如今 global 中。下次再执行,仍是会从新临时安装。

npx 会帮你执行依赖包里的二进制文件。

举例来讲,以前咱们可能会写这样的命令:

npm i -D webpack
./node_modules/.bin/webpack -v

若是你对 bash 比较熟,可能会写成这样:

npm i -D webpack
**npm bin**/webpack -v

有了 npx,你只须要这样:

npm i -D webpack
npx webpack -v

也就是说 npx 会自动查找当前依赖包中的可执行文件,若是找不到,就会去 PATH 里找。若是依然找不到,就会帮你安装!

npx 甚至支持运行远程仓库的可执行文件:

npx github:piuccio/cowsay hello

再好比 npx http-server 能够一句话帮你开启一个静态服务器!(第一次运行会稍微慢一些)

npx http-server

指定node版原本运行npm scripts:

npx -p node@8 npm run build

主要特色:

一、临时安装可执行依赖包,不用全局安装,不用担忧长期的污染。 二、能够执行依赖包中的命令,安装完成自动运行。 三、自动加载node_modules中依赖包,不用指定$PATH。 四、能够指定node版本、命令的版本,解决了不一样项目使用不一样版本的命令的问题。

内置命令(脚本)

npm自带了 数十个内置命令,这些命令均可以直接经过npm执行,除了install,还有不少实用的

image-20181023105039767

与script相关

其中有几条和咱们刚才说过的script十分相关,咱们能够经过在scripts中改写命令执行。

  • start , npm run start的简写,若是不在script中配置start,那么npm start默认执行node server.js

  • test ,npm run test的简写,执行自定义test脚本,没有默认行为。

  • stop,npm run stop的简写

  • restart,npm run stop && npm run restart && npm run start的简写

image-20181023110627346

其余实用的命令

咱们常常用的是install,可是其实还有不少命令很实用:

  • npm -l  列举全部npm自带的命令简介,而后经过npm help能够详细查看某个命令

  • npm search 快速查询npm中的相关包(和咱们去npm官网查是同样的)

  • npm root 查看全局的node_modules目录

  • npm audit fix 这个命令很实用,自动扫描您的项目漏洞,并自动安装任何兼容更新到脆弱的依赖

  • npm restart 从新启动模块

  • npm prune 移除当前不在package.json中可是存在node_modules中的依赖

  • npm repo 浏览器端打开项目地址(GitHub), 省去打开浏览器查找的操做!

  • npm docs 查看项目文档,同上

  • npm home 在浏览器端查看项目(项目主页),同上

  • npm search 查找包含该字符串的依赖包

  • npm view[field][--json]列出依赖信息,包括历史版本,能够指定field来查看某个具体信息,好比(versions) 能够添加–json参数输出所有结果

    image-20181023111220672

乱七八糟的版本号

我相信只要打开package.json,第一眼就会被里面一堆乱七八糟的数字给晃得晕头转向,随便给你晃一眼:

  { "foo" : "1.0.0 - 2.9999.9999"
  , "bar" : ">=1.0.2 <2.1.2"
  , "baz" : ">1.0.2 <=2.3.4"
  , "boo" : "^2.0.1"
  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
  , "lal" : "git://……"
  , "asd" : "http://asdf.com/asdf.tar.gz"
  , "til" : "~1.2"
  , "abc" : "haha/abc"
  , "elf" : "~1.2.3"
  , "two" : "2.x"
  , "thr" : "3.3.x"
  ……  }

光是看到数字就已经晕了,还有~,<>,^这么多符号。npm官网推荐使用语义化的版本好,通常按以下规则:

首先版本按照大版本.次要版本.小版本,通常来讲初始版本是1.0.0:

  • 小版本:修改bug或其余小的改动

  • 次要版本:增长了新的特性不改变已有特性

  • 大版本:大的变更,可能影响了向后的兼容性

版本匹配

  • 指定版本:好比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:安装最新版本。

node-semver

若是你须要在程序中作版本匹配,手写是否是很麻烦(我以前还真的本身用正则写了一个,超麻烦)其实npm提供了一个现成的匹配版本号的工具: https://github.com/npm/node-semver#functions

指定项目运行环境

不少时候,咱们的项目只能在特定的环境下执行,在其余环境下可能会报错,所以咱们须要在package.json中限制用户执行项目的环境:

engines指明了该项目所须要的node.js版本

"engines": {"node" : ">= 4.0.0","npm": ">= 3.0.0"}

os指定了用户执行的操做系统:

"os": [ "darwin", "linux", "!win32" ],

cpu能够指定包运行的cpu架构

  "cpu": [ "x64", "!arm" ]

config

以前咱们说过npm有个配置文件,里面的变量能够经过$npmconfig拿到,而这个配置文件一般在:

  • 项目config file (/path/to/my/project/.npmrc) : 一般要本身建立

  • 用户config file (~/.npmrc)

  • 全局config file ($PREFIX/etc/npmrc)

  • npm内置config file (/path/to/npm/npmrc)

经过如下命令能够查看config信息:

npm config ls/list

123

npm有不少默认配置,能够经过如下命令查看,能够去官网查看这些命令的详细信息

npm config ls -l

image-20181030115814087

经过如下命令能够修改配置

npm config set key valuenpm set key valuenpm config get keynpm get key

固然,也能够经过$npm_config_key = 来修改,或者在node中经过**process.env.npm_config_key = 来修改,

数组值是经过在键名后面添加“[]”来指定的。例如:

key[] = "first value"key[] = "second value"

安装非NPM上发布的包

一般,咱们安装的包都是在npm官网上,经过版本标明。可是,若是我想使用没上传到npm上的包怎么办?其实你能够直接加网址或git地址。官网明确了如下类型的包都是能够的:

a) 包含一个由package.json文件描述的程序的文件夹。

b) 包含(a)的gzipped tarball 。

c)解析为(b)的URL。

d) \@\ : 在registry上发布的(c)

e)\@\ : 能指向(d)。

f)\:  具备latest标签,且知足(e)。

g)git url,当clone时,获得(a)。

只要知足以上条件,你的包不用发布到npm上都能使用。其中,git url能够是如下形式:

git://github.com/user/project.git#commit-ishgit+ssh://user@hostname:project.git#commit-ishgit+http://user@hostname/project/blah.git#commit-ishgit+https://user@hostname/project/blah.git#commit-ish

其中,commit-ish 能够是任意的tag,branch,sha。

dependencies & devDependencies & peerDependencies

众所周知,package.json里有一堆dpendencies字段,他们像亲兄弟同样,老是结伴同行。不少人容易弄混他们究竟是什么关系。

因为这里面内容挺多的,会整理在另外一篇文章中,后续这里会放上连接

更新包

咱们知道npm自带的npm update能够根据pacaage.json的版本号更新包,可是你须要手动的更新版本号,所以出现了升级插件npm-check-updates,能够自动搜索当前包的更新状况,而且修改pacage.json

安装npm-check-updates

$ npm install -g npm-check-updates

ncu命令

ncu是npm-check-updates的缩写命令

$ ncu  -v  #查询版本号
$ ncu    #直接输入ncu能够查看全部须要更新的包

image-20181030113416839

$ ncu -u  # 更新全部的包,并修改package.json文件

image-20181030113457081

$ ncu -f regex # 只匹配特定的正则格式的包
$ ncu -g # 更新全局包

image-20181030113548646

参考文档:

https://docs.npmjs.com/misc/scripts

https://docs.npmjs.com/cli/run-script

https://docs.npmjs.com/files/package.json

https://stackoverflow.com/questions/18875674/whats-the-difference-between-dependencies-devdependencies-and-peerdependencies

http://javascript.ruanyifeng.com/nodejs/packagejson.html#toc1

https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击




相关文章:
【推荐】 流式处理框架storm浅析(下篇)
【推荐】 “货品未动,数据先行”,德邦快递与网易云联合打造“智能物流”
【推荐】 一文看尽 Raft 一致性协议的关键点

相关文章
相关标签/搜索