你真的懂package.json吗

前言
在Node.js中,模块是一个库或框架,也是一个Node.js项目。Node.js项目遵循模块化的架构,当我们创建了一个Node.js项目,意味着创建了一个模块,这个模块的描述文件,被称为package.json。
我之前看别人项目中package.json文件的scripts这样写:
"dev": "rimraf "config/.conf.json" && rimraf "src/next.config.js" && cpx ".conf.json" "config/" && nodemon server/index.ts",
"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"
复制代码当时看的有点懵, 于是又补了下相关知识, 发现原来package.json有很多地方被我们忽略了呀, 如果有道友和我一样有点懵的话, 本文不容错过。
bin
它是一个命令名和本地文件名的映射。在安装时,如果是全局安装,npm将会使用符号链接把这些文件链接到prefix/bin,如果是本地安装,会链接到./node_modules/.bin/。
通俗点理解就是我们全局安装, 我们就可以在命令行中执行这个文件, 本地安装我们可以在当前工程目录的命令行中执行该文件。
"bin": {
"gynpm": "./bin/index.js"
}
复制代码要注意: 这个index.js文件的头部必须有这个#!/usr/bin/env node节点, 否则脚本将在没有节点可执行文件的情况下启动。
小实验
通过npm init -y创建一个package.json文件。
{
"name": "cc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"mason": "./index.js"
},
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {}
}
复制代码在package.json的同级目录新建index.js文件

!/usr/bin/env node

console.log('cool')
复制代码然后在项目目录下执行: mac下: sudo npm i -g, window下: npm i -g
接下来你在任意目录新开一个命令行, 输入mason, 你讲看到
cool字段。
不知道通过这个小实验能不能帮助大家更好的理解这个bin的作用。像我们常用的vue-cli, create-react-app等都是通过bin属性将命令映射到了全局上。
main
main很重要, 它是我们项目的主要入口。
"main": "app.js"
复制代码像这样, 我们项目就会以根目录下的app.js文件作为我们的项目入口文件了。
scripts
npm 允许在package.json文件里面,使用scripts字段定义脚本命令。
优点:
项目的相关脚本,可以集中在一个地方。
不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要知道怎么测试你的项目,只要运行npm run test即可。

可以利用 npm 提供的很多辅助功能。
复制代码
npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。
这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。
通配符
表示任意文件名,
表示任意一层子目录。

"lint": "jshint *.js"
"lint": "jshint */.js"

复制代码如果要将通配符传入原始命令,防止被 Shell 转义,要将星号转义。
"test": "tap test/*.js"
复制代码脚本传参符号: --
"server": "webpack-dev-server --mode=development --open --iframe=true ",
复制代码脚本执行顺序
并行执行(即同时的平行执行),可以使用&符号
npm run script1.js & npm run script2.js 复制代码继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号 npm run script1.js && npm run script2.js
复制代码脚本钩子
npm 脚本有pre和post两个钩子, 可以在这两个钩子里面,完成一些准备工作和清理工作
eg:
"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"
复制代码npm 默认提供下面这些钩子:
prepublish,postpublish
preinstall,postinstall
preuninstall,postuninstall
preversion,postversion
pretest,posttest
prestop,poststop
prestart,poststart
prerestart,postrestart
复制代码拿到package.json的变量
npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。
首先,通过npm_package_前缀,npm 脚本可以拿到package.json里面的字段。比如,下面是一个package.json。
// package.json
{
"name": "foo",
"version": "1.2.5",
"scripts": {
"view": "node view.js"
}
}

复制代码我们可以在自己的js中这样:
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5
复制代码常用脚本

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

复制代码介绍几个在npm脚本中好用的模块
cpx全局复制
一个很好用的模块, 可以监视全局文件变化, 并将其复制到我们想要的目录
我们使用npm安装就可以在npm的脚本中使用了:
"copy": "cpx ".conf.json" "config/" "
复制代码这样我们运行npm run copy就可以将根目录下的.conf.json文件拷贝到config文件夹下了, 如果没有config文件夹就会新建一个。
cpx "src/*/.{html,png,jpg}" app --watch
复制代码当src目录下的任意.html, .png, .jpg等文件发生变化就拷贝到app目录下。
cross-env能跨平台地设置及使用环境变量
大多数情况下,在windows平台下使用类似于: NODE_ENV=production的命令行指令会卡住,windows平台与POSIX在使用命令行时有许多区别(例如在POSIX,使用$ENV_VAR,在windows,使用%ENV_VAR%。。。)
cross-env让这一切变得简单,不同平台使用唯一指令,无需担心跨平台问题:
"start": "cross-env NODE_ENV=production node server/index.js",
复制代码dependencies和devDependencies
这两个主要就是存放我们项目依赖的库的地方了, devDependencies主要是存放用于本地开发的, dependencies会在我们开发的时候带到线上。
通过npm i xxx -S会放在dependencies, npm i xxx -D会放在devDependencies。所以我们在装包的时候一定要考虑这个包在线上是否用的到, 不要全都放到dependencies中,增加我们打包的体积和效率。
peerDependencies
我们在一些项目的package.json中看到这个属性, 它主要是考虑兼容问题,通俗点理解, 我们通过这个属性可以告诉要使用我们这个模块的人:
你要使用我, 最好把xxx1, xxx2也带上, 不然我可能会给你带来麻烦的。
"peerDependencies": {
"xxx1": "1.0.0",
"xxx2": "1.0.0",
}
复制代码这样在装包的时候同时也会, 带上xxx1和xxx2这两个包。
个人觉得比较重要的就是这几个了。还有一些, 像: author, version, keywords, description这些就很好理解了。
参考

作者:MasonEast
链接:https://juejin.im/post/5dea1095e51d4558083322e2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容