此文已由作者黄锴授权网易云社区发布。

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

强大的命令功能

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

查询脚本

你可以通过输入npm run查看所有的命令列表(虽然你也可以直接查看package.json)

自定义脚本

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

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

然后你可以通过npm run ...执行 注意,start命令可以不用run,后面会讲

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

例如执行tap命令,你可以直接写:

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

而不是

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

传递参数

如果我们在执行npm run xxx 操作的时候想给里面的脚本传参数可以使用—,如下所示:

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

嵌套的属性也可以通过_代替.进行嵌套显示:**$npm_package_scripts_start**

configuration

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

例如:

一些常用的脚本配置

这里引用阮老师的一些配置,可以看到配合一定的插件,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

主要特点:

1、临时安装可执行依赖包,不用全局安装,不用担心长期的污染。 2、可以执行依赖包中的命令,安装完成自动运行。 3、自动加载node_modules中依赖包,不用指定$PATH。 4、可以指定node版本、命令的版本,解决了不同项目使用不同版本的命令的问题。

内置命令(脚本)

npm自带了 数十个内置命令,这些命令都可以直接通过npm执行,除了install,还有很多实用的

与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的简写

其他实用的命令

我们经常用的是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参数输出全部结果

乱七八糟的版本号

我相信只要打开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

npm有很多默认配置,可以通过以下命令查看,可以去官网查看这些命令的详细信息

npm config ls -l

通过以下命令可以修改配置

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可以查看所有需要更新的包

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

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

参考文档:

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 一致性协议的关键点

npm和package.json那些不为常人所知的小秘密的更多相关文章

  1. node 通过指令创建一个package.json文件及npm安装package.json

    描述包的文件是package.json文件. 一个这样的文件,里面的信息还是挺大的.我们可以放弃手动建立.为了练手我们有命令行来建一个这样的包; 完成name,varsion....license项的 ...

  2. npm的package.json字段含义中文文档

    简介 本文档有所有package.json中必要的配置.它必须是真正的json,而不是js对象. 本文档中描述的很多行为都受npm-config(7)的影响. 默认值 npm会根据包内容设置一些默认值 ...

  3. NodeJS - npm WARN package.json : No repository field:can not open package.json

    最近在研究node.js,在安装npm的时候发现了几个报错,瞬间蒙圈,查找文献基本解决(文献好少呀~  -.-)   一.报错:“can not open  path/path/package.jso ...

  4. npm init node 通过指令创建一个package.json文件及npm安装package.json

    描述包的文件是package.json文件. 一个这样的文件,里面的信息还是挺大的.我们可以放弃手动建立.为了练手我们有命令行来建一个这样的包; 完成name,varsion....license项的 ...

  5. npm安装package.json

    npm安装package.json时,直接转到当前项目目录下,用命令npm install 或npm install --save-dev安装即可,自动将package.json中的模块安装到node ...

  6. npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...

  7. [转载]npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017-08-02 19:16:20 拭心 阅读数 78648更多 分类专栏: 学学前端   版权声明:本文为博主原创文章,遵循CC 4.0 BY ...

  8. npm与package.json快速入门

    本文转载自npm与package.json快速入门 导语 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解了一些,这次结合官方文章总结一下,加深下理解吧! 读完本 ...

  9. npm中package.json详解

    通常我们使用npm init命令来创建一个npm程序时,会自动生成一个package.json文件.package.json文件会描述这个NPM包的所有相关信息,包括作者.简介.包依赖.构建等信息,格 ...

随机推荐

  1. openh264 在 osx 上的 nasm 问题

    先在 pc 上编译,熟悉一下. 编译遇到一个问题: nasm -DUNIX64 -DPREFIX -f macho64 -I./codec/common/x86/ -o codec/common/x8 ...

  2. UltimateRecyclerView的用法具体解释

    近期在用非常多第三方库的时候,发现有一些附带的demo写的不是非常全面或者样例的代码太多,凝视太少,要想使用还要去看下源代码什么的(.. .用第三方开源库不就是想节省时间嘛).所以决定每周两到三篇.写 ...

  3. EasyRTMP安卓Android手机直播之AAC采集、编码与RTMP推送

    本文转自EasyDarwin团队Kim的博客:http://blog.csdn.net/jinlong0603/article/details/52963378 EasyRTMP Android版de ...

  4. Timing breakdown phases explained

    https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#timing-explana ...

  5. Local Response Normalization 60 million parameters and 500,000 neurons

    CNN是工具,在图像识别中是发现图像中待识别对象的特征的工具,是剔除对识别结果无用信息的工具. ImageNet Classification with Deep Convolutional Neur ...

  6. cocos2d-js实现 双击android后退按钮 即退出游戏

    之前测了一下android自带的后退按钮,用在cocos2d-js中是没有获取到的 (可能是cocos2d-js已经把android的后退事件截取了,所以原生java代码没有用), 没办法就只能用co ...

  7. ideal 控制台乱码 解决

    run config  中 tomcat VM options中填入一下命令 -Dfile.encoding=UTF-8

  8. 完美的jquery事件绑定方法on()

    在讲on()方法之前,我们先讲讲在on()方法出现前的那些事件绑定方法: .live() jQuery 1.3新增的live()方法,使用方法例如以下: $("#info_table td& ...

  9. 20170319 ABAP 生成XML文件

    方法一:ABAP 使用method方式操作XML 转自:http://www.cnblogs.com/jiangzhengjun/p/4265595.html 方法二:STRANS 转换工具;使用st ...

  10. Struts多个文件上传

    Struts2多个文件上传 10级学员 韩晓爽课堂笔记 多个文件上传分为List集合和数组,下面我们着重介绍一下list集合的上传.都大同小异. 一 介绍 1. 在struts2文件上传的时候要先导入 ...