一文总结前端工程化构建起步之初必要熟悉文件之package.json

161 阅读6分钟

前言

主要记录了 package.json 的常用字段及依赖、模块规范和files含义及各自的使用。

常用字段说明

字段说明类型示例
private是否私有Booleantrue
packageManager包管理工具String"pnpm@7.3.0"
workspaces多项目同一个仓库开发时用到Array["packages/*","play","docs"]
name包名String"js-yaml"
version版本号String"4.0.0"
keywords关键字Array[ "yaml", "parser", "serializer", "pyyaml"]
description项目描述String"YAML 1.2 parser and serializer"
repository仓库地址,可以找到该项目代码存放地址,通常是GithubString"nodeca/js-yaml"
license证书String"MIT"
scripts脚本命令的映射,借助包管理工具执行,例如在终端输入 pnpm run lintObject{"lint": "eslint ."}
bin自定义的命令,打开终端可以直接以该命令开头输入执行,例如在终端输入 js-yaml -vObject{"js-yaml": "bin/js-yaml.js"}
type本项目中所有涉及的 .js文件被视作哪种模块解析(ESModule OR CommonJS,默认是 CommonJS)String"module"
main该项目的入口文件地址String"index.js"
module如果type值是ESModule模块,指明入口文件String"./testSubPath.js"
exports导出文件模式[String, Object]{".": {"import": "./dist/js-yaml.mjs","require": "./index.js"},"./package.json": "./package.json"}
files如果发包到npm上,存储到npm服务器上的文件,如果未指定默认存储全部文件Object["index.js","lib/","bin/","dist/"]
dependencies项目运行时依赖Object{}
devDependencies项目开发时依赖,仅用在开发期间Object{}
peerDependencies主要用在依赖包中,表示安装该包时还需要安装哪些包Object{"gulp": ">=4"}

依赖 dependencies/devDependencies/peerDependencies 的各自使用及区别

dependencies 项目运行时所需依赖包

dependencies 项目运行时需要的依赖包,无论是在开发过程中还是在打包后项目运行中,都要用到的依赖包,npm install 包名 默认被添加到 dependenciesinstall 时该依赖会被下载。

devDependencies 项目开发过程中所需依赖包

devDependencies 项目开发过程中需要用到的依赖包,如果该项目被打包将不会使用到该依赖包,npm install 包名 --save-dev,该依赖被添加到 devDependenciesinstall 时该依赖会被下载。

peerDependencies 项目依赖的环境

peerDependencies 项目所需依赖的包,表示安装该包时还需要安装哪些包,在本身项目中是不起作用的,npm install 也不会被下载的,该项目的依赖主要在开发插件时用到,可以避免该依赖被重复安装。例如项目A中,用到了gulp构建,intall了gulp,但是也使用到了插件A和插件B,插件A和插件B就不需要再去安装gulp了,所有在插件A和插件B中设置该参数的依赖的gulp,这里的gulp类似于环境,如果环境被搭建好就无需重复搭建。Element-plus源码设置了vue的依赖。

{
    "peerDependencies": {
        "vue": "^3.2.0"
     }
}

例如,gulp插件 gulp-autoprefixer,指明peerDependencies环境依赖gulp": ">=4"即该插件需要依赖gulp的版本大于或等于4版本的,如果依赖gulp-autoprefixer的项目A,安装的gulp版本低于4即版本不匹配或未安装,引用该插件则会报错。

但是该插件设置了peerDependenciesMeta,设置了gulp为可选的,项目A中没有安装gulp将不会被报错:

{
    "peerDependencies": {
        "gulp": ">=4"
    },
    "peerDependenciesMeta": {
        "gulp": {
            "optional": true
        }
     }
}

main/module/exports的含义和区别

首先 type 指明了项目中的 .js文件 被当作什么规范处理(ESModule OR CommonJS,ESModule是ES模块规范,CommonJS是Node的模块规范,Node默认CommonJS规范,若使用ESModule,需手动指明type: "module")。

main/module 含义和区别

  • main:指明该包/项目的入口文件地址
  • module 指明该包/项目的入口文件地址,但是是项目ESModule的入口

例如,在项目A中使用了包A包A/package.json同时定义了main字段和module字段如下:

{
    "main": "./testSubPath2.js",
    "module": "./testSubPath.js",
}

项目A/package.json中,

  • 若是CommonJS,则导入包A的入口文件是项目A/node_modules/包A/testSubPath2.js
  • 若是ESmodule,则导入包A的入口文件是项目A/node_modules/包A/testSubPath.js

视项目使用的模块规范定位到相应的入口文件,可以自测下。

exports 更加高级了点,优先级也是最高

官方文档解释

exports,定义了该包的导出规则(用在该包被导入),可以理解为路径映射。 配置不同环境对应的模块入口文件,并且当他存在时,它的优先级最高,当package.json文件中存在exports字段,设置的main字段会失效。

测试main/type/module/exports的用途,在node_modules下创建一个依赖包,例如js-yaml, 定义相应的文件和指明pcakge.json文件内容如下:

{
    "main": "./testSubPath2.js",
    "module": "./testSubPath.js",
    "exports": {
    	".": {
      		"import": "./testIndex2.js",
      		"require": "./testIndex.js"
    	},
    	"./package.json": "./package.json",
    	"./testSubPath": "./testSubPath.js"
  },
}

如果整体项目的根目录下的 package.json(非node_modules定义的子包),如果指明type值为module,则该项目中的所有js文件被视作ESModule类型文件(import/export),在项目根目录创建一个文件,例如testModule.js,该文件引入js-yaml(引入的方式是由项目package.json里type字段决定的,因为我们将其指明为module,所以这里要通过import来引入),由于我们在js-yaml包里的package.json指明了exports字段,根据该字段,我们可以直到import jsyaml from 'js-yaml'被映射到ja-yaml/testIndex2.js(注意exports字段标明了路径映射,import表示ESModule类型的引入,require表示commonjs类型的引入),import jsyaml from 'js-yaml/testSubPath'会被映射到js-yaml/testSubPath.js文件。

main/module/exports的优先级顺序:如果是ESModule类型则exports->module,如果是commonjs类型则exports->main,module指明的是ESModule类型文件导入入口,main是commonjs入口。

npm install 下载包的内容

关于本地安装的npm包所展示的文件和文件夹的配置。

如果想在开发的npm包被下载后只能看见某些文件或文件夹,就需要在package.json文件进行相应的配置。

配置files字段,该值对应的是一个字符串数组,用来描述当把npm包发布时,files指定的文件会被推送到npm服务器中,如果指定的是文件夹,那么该文件夹下面所有的文件都会被提交,例如js-yaml源码中package.json文件里files字段这样指定:

{
    "files": [
    	"index.js",
    	"lib/",
    	"bin/",
    	"dist/"
    ],
}

那么我们使用npm install js-yaml -save-dev后,查看node_modules/js-yaml目录,便可看到有bin目录、dist目录、lib目录、index.js文件。当然还有配置文件package.json、README.md、LICENSE、CHANGELOG.md(我们并未指定,但下载包后也被下载了)呢?

files.png

如果有不想提交的文件,还可在项目根目录中新建一个 .npmignore文件,指明不需要被推送到npm服务器的文件或目录,防止垃圾文件推送到npm上,这个文件的形式和 .gitignore类似,写在这个文件中的文件,即使也被写在files属性里也会被排除在外。

总结

  • 三种依赖方式的区别:dependencies、devDependencies和peerDependencies
  • main/module/exports的使用规则;
  • 通过files字段指定被推送到npm服务器上的文件或目录;

若有出处,请留言哦~