package.json持续解剖

这个文件用来描述项目及项目所依赖的模块信息,可以称得上是前端项目的大管家,从这个文件中,你可以看到很多有用的信息.可做到的事情如下

  • 版本控制
  • 依赖管理
  • 运行的任务
  • 等等

下面是一个字段信息比较全的package.json文件

perl 复制代码
{
    "name": "package-test-demo",
    "version":"0.0.1",
    "description": "this is a demo",
    "keywords":["node.js","vue", "js"],
    "homepage": "https://baidu.com",
    "bugs":{"url":"http://path/to/bug","email":"xx@xxxx.com"},
    "license": "ISC",
    "author": "zpp",
    "contributors":[{"name":"zpp","email":"xx@xxxx.com"}],
    "files": "",
    "main": "./dist/default.js",
    "bin": "",
    "man": "",
    "directories": "",
    "repository": {
    "type": "git",
    "url": "https://path/to/url"
  },
    "scripts": {
      "start": "webpack serve --config webpack.config.dev.js --progress"
    },
    "config": { "port" : "8080" },
    "dependencies": {},
    "devDependencies": {
        "@babel/core": "^7.14.3",
        "@babel/preset-env": "^7.14.4",
        "@babel/preset-react": "^7.13.13",
        "babel-loader": "^8.2.2",
        "babel-plugin-import": "^1.13.3",
        "glob": "^7.1.7",
        "less": "^3.9.0",
        "less-loader": "^9.0.0",
        "style-loader": "^2.0.0",
        "webpack": "^5.38.1",
        "webpack-cli": "^4.7.0",
        "webpack-dev-server": "^3.11.2"
    },
    "peerDependencies": {
        "tea": "2.x"
    },
    "bundledDependencies": [
        "renderized", "super-streams"
    ],
    "engines": {"node": "0.10.x"},
    "os" : [ "win32", "darwin", "linux" ],
    "cpu" : [ "x64", "ia32" ],
    "private": false,
    "publishConfig": {}
  }
 

配置说明脑图

配置解析

必须属性和描述信息

name

就是项目的名称

规则

  • name必须小于等于214个字符

  • 不能以._开头,不能有大写字母

  • 因为名称最终成为URL的一部分因此不能包含任何非URL安全字符

    不安全的URL字符

    • 空格" "
    • 大于小于号<>
    • 方括号[]
    • 花括号{}
    • 竖线|
    • 反斜杠``
    • 插入号^
    • 百分比%

实际上,我们平时开发的很多项目并不会发布在npm上,所以这个名称是否标准可能就不是那么重要,它不会影响项目的正常运行。如果需要发布在npm上,name字段一定要符合要求。

version

version字段用于定义版本号。一般的格式是x.x.x, 并且需要遵循该规则

该标识符被认为是完全唯一的。每次发布时version不能与已存在的一致。

description

它是一个字符串, 用于描述当前项目的概况,方便用户直接了解包的功能。

keywords

keywords是标签,是一个字符串组成的数组, 用于标记当前项目的重点词汇。同时,可以作为搜索关键词,提供给资源平台使用,进行索引。

和description一样, 作用类似于做seo的时候增加权重,曝光率的

author

作者信息,支持两种形式,一种是字符串,一种是对象

json 复制代码
"author": "you name"
// or
"author": {
  "name" : "you name",
  "email" : "xxxxx@xx.com",
  "url" : "xxxx"
}

contributors

表示该项目包的贡献者,是一个数组,数组字符串或者数据对象,描述贡献者信息

homepage

homepage就是项目的主页地址了,它是一个字符串。

bugs

bugs表示项目提交问题的地址,该字段是一个对象,可以添加一个提交问题的地址和反馈的邮箱:

"bugs": {

perl 复制代码
"url" : "[https://github.com/facebook/react/issues](https://github.com/facebook/react/issues)",

"email" : "[xxxxx@xx.com](mailto:xxxxx@xx.com)"

}

最常见的bugs就是Github中的issues页面,如上就是react的issues页面地址。

依赖配置

一般情况, 我们开发项目都会依赖多个外部依赖包,根据依赖包的不同用途,可以给他们配置到不同的属性下面,有五个相关属性, 它们的值都是一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。

dependencies

声明的是项目的生产环境中所必须的依赖包

通常在安装依赖的时候 使用---save或者-S则表述将该依赖写入dependencies属性中

json 复制代码
"dependencies": {
   "react": "^17.0.2",
   "react-dom": "^17.0.2",
   "react-scripts": "4.0.3",
},

版本号再后面会说到,此处先不讲

devDependencies

devDependencies中声明的是开发阶段需要的依赖包,如Webpack、Eslint、Babel等,用于辅助开发。它们不同于 dependencies,因为它们只需安装在开发设备上,而无需在生产环境中运行代码。当打包上线时并不需要这些包,所以可以把这些依赖添加到 devDependencies 中,这些依赖依然会在本地指定 npm install 时被安装和管理,但是不会被安装到生产环境中。

使用---save--dev或者-D则表述将该依赖写入devDependencies属性中

peerDependencies

直观表述。如果你安装我,那么你最好也安装X,Y和Z.

最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。

peerDependencies字段就是用来供插件指定其所需要的主工具的版本。

例子:下方是一个myless库的package.json文件, 表示使用myless模块必须依赖less模块的3.9.x版本.

json 复制代码
"name": "myless",
"peerDependencies": {
  "less": "3.9.x"

}

然后,你宿主环境的node_modules里面 其实是

arduino 复制代码
YouProject
|- node_modules
   |- myless
   |- less

// 而不是这样
YouProject
|- node_modules
   |- myless
      |- node_modules
         |- less

peerDependencies的目的是提示宿主环境去安装满足插件peerDependencies所指定依赖的包,然后在插件import或者require所依赖的包的时候,永远都是引用宿主环境统一安装的npm包,最终解决插件与所依赖包不一致的问题。

注意,从npm 3.0版开始,peerDependencies不再会默认安装了。就是初始化的时候不会默认带出。

比如,在npm3.0的时候,你安装myless, 宿主环境下他不会强制强制安装less, 而是会给你一个警告, 大致如下

复制代码
less是一个需要的依赖,但是没有被安装。  

还有个问题, 就是如果myless的peerDependencies所依赖的less升级版本了, 你需要手动去更新, 这个时候 启动项目的时候在控制台会有警告, 大概说是

css 复制代码
npm Error.  myless requires a peer xxx.@xxx. ...之类的

optionalDependencies

如果需要在找不到包或者安装包失败时,npm仍然能够继续运行,则可以将该包放在optionalDependencies对象中,optionalDependencies对象中的包会覆盖dependencies中同名的包,所以只需在一个地方进行设置即可。 需要注意,由于optionalDependencies中的依赖可能并为安装成功,所以一定要做异常处理,否则当获取这个依赖时,如果获取不到就会报错

bundledDependencies

上面的几个依赖相关的配置项都是一个对象,而bundledDependencies配置项是一个数组,数组里可以指定一些模块,这些模块将在这个包发布时被一起打包。

需要注意,这个字段数组中的值必须是在dependencies, devDependencies两个里面声明过的包才行。

engines

engines字段指明了该模块运行的平台,比如Node或者npm的某个版本或者浏览器。

json 复制代码
{ "engines" : { "node" : ">=0.10.3 <0.12", "npm" : "~1.0.20" } }

脚本配置

scripts

是 package.json中内置的脚本入口,用来执行脚本命令,简化输入,提高开发效率

config

config字段用来配置scripts运行时的配置参数,如下所示:

yaml 复制代码
"config": {
  "port": 3000
}

钩子

npm钩子

npm run 为每条命令提供了 pre- 和 post- 两个钩子(hook)。以 npm run test 为例,如果我们的 scripts 字段规定了 pretest 和 posttest,两个钩子的含义分别是预执行、后执行

复制代码
 prepublish:在打包和发布包之前运行,在npm install没有任何参数的本地运行
 postpublish:发布包后运行
 preinstall:包安装之前运行
 postinstall:包安装后运行
 preuninstall:在包卸载之前运行
 postuninstall:在包卸载之后运行
 preversion:在升级包版本之前运行
 postversion:在升级包版本之后,提交之后运行
 pretest:单元测试之前
 posttest:测试之后
 prestop:项目停止前
 poststop:停止运行后
 prestart:启动前
 poststart:启动后
 prerestart:重启前
 postrestart:重启后

脚本执行顺序

arduino 复制代码
 //并行执行 &
 npm run hello.js & npm run world.js
 //串行执行,前一个成功才能执行后一个 &&
 npm run hello.js && npm run world.js

通过npm_package_前缀,npm 脚本可以拿到package.json里面的字段

arduino 复制代码
{
  "name": "package.json",
  "version": "1.0.0", 
  "repostitory":{
     "type":"git"
  }
   "script":{
       "view":"echo $npm_package_repository_type"//bash获得打印出来
    }
}
//通过环境变量procss.env对象,拿到package.json的字段值
console.log(process.env.npm_package_name) //packages.json
console.log(process.env.npm_package_version) //1.0.0
console.log(process.env.npm_package_repository_type) // git

文件&目录

main

main 字段用来指定加载的入口文件,在 browser 和 Node 环境中都可以使用。如果我们将项目发布为npm包,那么当使用 require 导入npm包时,返回的就是main字段所列出的文件的module.exports 属性。如果不指定该字段,默认是项目根目录下的index.js。如果没找到,就会报错。

值是一个字符串

browser

browser字段可以定义 npm 包在 browser 环境下的入口文件。如果 npm 包只在 web 端使用,并且严禁在 server 端使用,使用 browser 来定义入口文件。

"module": "./src/index.js"

module

module字段可以定义 npm 包的 ESM 规范的入口文件,browser 环境和 node 环境均可使用。如果 npm 包导出的是 ESM 规范的包,使用 module 来定义入口文件。

"module": "./src/index.mjs"

需要注意, .js 文件是使用 commonJS 规范的语法(require('xxx')), .mjs 是用 ESM 规范的语法(import 'xxx')。

上面三个的入口入口文件相关的配置是有差别的,特别是在不同的使用场景下。在Web环境中,如果使用loader加载ESM(ES module),那么这三个配置的加载顺序是browser→module→main,如果使用require加载CommonJS模块,则加载的顺序为main→module→browser。

Webpack在进行项目构建时,有一个target选项,默认为Web,即构建Web应用。如果需要编译一些同构项目,如node项目,则只需将webpack.config.js的target选项设置为node进行构建即可。如果在Node环境中加载CommonJS模块,或者ESM,则只有main字段有效。

bin

bin字段用来指定各个内部命令对应的可执行文件的位置:

json 复制代码
"bin": {
  "someTool": "./bin/someTool.js"
}

主要适用于开发脚手架或者开发包的时候,用于命令指令的配置

files

files配置是一个数组,用来描述当把npm包作为依赖包安装时需要说明的文件列表。当npm包发布时,files指定的文件会被推送到npm服务器中,如果指定的是文件夹,那么该文件夹下面所有的文件都会被提交。

相关推荐
FungLeo几秒前
成为全栈·Node 后端篇·全文搜索:从 LIKE 到全文索引
node.js·全文索引·模糊搜索·全文搜索·成为全栈·like 搜索
mldong2 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排3 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角5 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!5 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰5 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi6 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen7 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端