你真的懂package.json吗

前言

在Node.js中,模块是一个库或框架,也是一个Node.js项目。Node.js项目遵循模块化的架构,当咱们建立了一个Node.js项目,意味着建立了一个模块,这个模块的描述文件,被称为package.json。css

我以前看别人项目中package.json文件的scripts这样写:html

"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有不少地方被咱们忽略了呀, 若是有道友和我同样有点懵的话, 本文不容错过。vue

bin

它是一个命令名和本地文件名的映射。在安装时,若是是全局安装,npm将会使用符号连接把这些文件连接到prefix/bin,若是是本地安装,会连接到./node_modules/.bin/。node

通俗点理解就是咱们全局安装, 咱们就能够在命令行中执行这个文件, 本地安装咱们能够在当前工程目录的命令行中执行该文件。react

"bin": {
    "gynpm": "./bin/index.js"
}
复制代码

要注意: 这个index.js文件的头部必须有这个#!/usr/bin/env node节点, 不然脚本将在没有节点可执行文件的状况下启动。webpack

小实验

经过npm init -y建立一个package.json文件。web

{
    "name": "cc",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "bin": {
        "mason": "./index.js"
    },
    "scripts": {},
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {}
}
复制代码

在package.json的同级目录新建index.js文件vue-cli

#!/usr/bin/env node

console.log('cool')
复制代码

而后在项目目录下执行: mac下: sudo npm i -g, window下: npm i -gnpm

接下来你在任意目录新开一个命令行, 输入mason, 你讲看到json

cool字段。

不知道经过这个小实验能不能帮助你们更好的理解这个bin的做用。像咱们经常使用的vue-clicreate-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这些就很好理解了。

参考

npmjs

阮一峰博客

相关文章
相关标签/搜索