npm(二):剖析 package.json

系列文章:

npm(一):从npm CLI说起

npm(二):剖析 package.json

npm(三):npm包发布、更新、废弃

npm(四):剖析npm包版本管理机制

npm(五):组件发布npm包全流程 (使用rollup打包工具)

npm(六):使用Vue CLI构建 lib 发布npm包

剖析npm依赖管理


目录

1.必备属性 

1.1 name: 

1.2 version

2. 描述信息

2.1 description用于添加模块的的描述信息,方便别人了解你的模块。字符串

2.2 keywords用于给你的模块添加关键字。数组、字符串

2.3 开发人员 author 和 contributors

2.4 地址 homepage、bugs、repository

3. 依赖配置

3.1 dependencies

3.2 devDependencies

3.3 peerDependencies

3.4 optionalDependencies

3.5 bundledDependencies

 4. 协议 license

5. 目录、文件相关

5.1 程序入口 main

5.2 命令行工具入口 bin

5.3 发布文件配置 files

6. 脚本配置 script、config

6.1 script

6.2 config


1.必备属性 

package.json 中有非常多的属性,其中必须填写的只有两个:name 和 version ,这两个属性组成一个 npm 模块的唯一标识。

1.1 name: 

name 即模块名称,其命名时需要遵循官方的一些规范和建议:

  • 包名会成为模块url、命令行中的一个参数或者一个文件夹名称,任何非url安全的字符在包名中都不能使用,可以使用 validate-npm-package-name 包来检测包名是否合法。

  • 语义化包名,可以帮助开发者更快的找到需要的包,并且避免意外获取错误的包。

  • 若包名称中存在一些符号,将符号去除后不得与现有包名重复

        例如:由于react-native已经存在,react.nativereactnative都不可以再创建。

  • 如果你的包名与现有的包名太相近导致你不能发布这个包,那么推荐将这个包发布到你的作用域下。

        例如:用户名 conard,那么作用域为 @conard,发布的包可以是@conard/react

查看包是否被占用

name 是一个包的唯一标识,不得和其他包名重复,我们可以执行 npm view packageName 查看包是否被占用,并可以查看它的一些基本信息:

若包名称从未被使用过,则会抛出 404 错误:

 另外,你还可以去 https://www.npmjs.com/ 查询更多更详细的包信息。 

注意:包发布后不可以修改名字,但是可以给提示信息,指定到新发布的包上,详见

1.2 version

查看这里npm教程(一):从npm CLI说起_五虎战画戟-CSDN博客

2. 描述信息

2.1 description用于添加模块的的描述信息,方便别人了解你的模块。字符串

2.2 keywords用于给你的模块添加关键字。数组、字符串

当然,他们的还有一个非常重要的作用,就是利于模块检索。当你使用 npm search 检索模块时,会到description 和 keywords 中进行匹配。写好 description 和 keywords 有利于你的模块获得更多更精准的曝光:

2.3 开发人员 author 和 contributors

描述开发人员的字段有两个:author 和 contributors, author 指包的主要作者,一个 author 对应一个人。contributors 指贡献者信息,一个 contributors 对应多个贡献者,值为数组,对人的描述可以是一个字符串,也可以是json:

"Barney Rubble <[email protected]> (http://barnyrubble.tumblr.com/)
{
  "name" : "LearningLog",
  "email" : "[email protected]",
  "url" : "https://github.com/LearningLog"
}

email和url在两种形式中都是可选的。

也可以在你的npm用户信息中设置一个顶级的maintainers字段。

2.4 地址 homepage、bugs、repository

homepage 用于指定该模块的主页。

repository 用于指定模块的代码仓库。

bugs 指定一个地址或者一个邮箱,对你的模块存在疑问的人可以到这里提出问题issues。

{
 "url": "http://github.com/owner/project/issues",
 "email": "[email protected]"
}

3. 依赖配置剖析npm依赖管理_五虎战画戟-CSDN博客

我们的项目可能依赖一个或多个外部依赖包,根据依赖包的不同用途,我们将他们配置在下面几个属性下:dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependencies

3.1 dependencies

dependencies 指定了项目运行所依赖的模块,开发环境和生产环境的依赖模块都可以配置到这里,例如

"dependencies": {
    "lodash": "^4.17.13",
    "moment": "^2.24.0",
  }

3.2 devDependencies

有一些包有可能你只是在开发环境中用到,例如你用于检测代码规范的 eslint ,用于进行测试的 jest ,用户使用你的包时即使不安装这些依赖也可以正常运行,反而安装他们会耗费更多的时间和资源,所以你可以把这些依赖添加到 devDependencies 中,这些依赖照样会在你本地进行 npm install 时被安装和管理,但是不会被安装到生产环境:

"devDependencies": {
    "jest": "^24.3.1",
    "eslint": "^6.1.0",
  }

3.3 peerDependencies

peerDependencies 用于指定你正在开发的模块所依赖的版本以及用户安装的依赖包版本的兼容性。

更多情况用在指定外部依赖

上面的说法可能有点太抽象,我们直接拿 ant-design 来举个例子,ant-design 的 package.json 中有如下配置:

"peerDependencies": {
    "react": ">=16.0.0",
    "react-dom": ">=16.0.0"
  }

当你正在开发一个项目,使用了 ant-design ,所以也肯定需要依赖 React。同时, ant-design 也是需要依赖 React 的,它要保持稳定运行所需要的 React 版本是16.0.0,而你开发时依赖的 React 版本是 15.x:

这时,ant-design 要使用 React,并将其引入:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

 这时取到的是宿主环境也就是你的环境中的 React 版本,这就可能造成一些问题。

在 npm2 的时候,指定上面的 peerDependencies 将意味着强制宿主环境安装 react@>=16.0.0和react-dom@>=16.0.0 的版本。

npm3 以后不会再要求 peerDependencies 所指定的依赖包被强制安装,相反 npm3 会在安装结束后检查本次安装是否正确,如果不正确会给用户打印警告提示。

例如,我在项目中依赖了 antd 的最新版本,然后依赖了 react 的 15.6.0版本,在进行依赖安装时将给出以下警告:

"dependencies": {
    "react": "15.6.0",
    "antd": "^3.22.0"
  }

peerDependencies 在npm3及其之后的版本起到的作用只是提示作用

因此我们总结下在插件使用 dependencies 声明依赖库的特点:

  • 如果用户显式依赖了核心库,则可以忽略各插件的 peerDependency 声明;
  • 如果用户没有显式依赖核心库,则会提示用户按照peerDependency自行安装依赖;
  • 当用户依赖的版本、各插件依赖的版本之间不相互兼容,会报错让用户自行修复;
warning " > [email protected]" has unmet peer dependency "css-loader@*".
warning "@nuxtjs/eslint-module > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "@nuxtjs/eslint-config > eslint-plugin-vue > [email protected]" has incorrect peer dependency "eslint@^5.0.0".

>表示哪个项目中引入的插件

例如第一行就表名是根项目本身引用的vue-loader插件中要求根项目有安装css-loader

但跟项目没有安装css-loader, 所以就会有这个问题

has unmet peer dependency表示peerDependency声明的依赖没安装

has incorrect peer dependency 表示peerDependency声明的依赖安装了 但是版本没对上

3.4 optionalDependencies

某些场景下,依赖包可能不是强依赖的,这个依赖包的功能可有可无,当这个依赖包无法被获取到时,你希望 npm install 继续运行,而不会导致失败,你可以将这个依赖放到 optionalDependencies 中,注意 optionalDependencies 中的配置将会覆盖掉 dependencies 所以只需在一个地方进行配置。

当然,引用 optionalDependencies 中安装的依赖时,一定要做好异常处理,否则在模块获取不到时会导致报错。

3.5 bundledDependencies

和以上几个不同,bundledDependencies 的值是一个数组,数组里可以指定一些模块,这些模块将在这个包发布时被一起打包。

  "bundledDependencies": ["package1" , "package2"]

 4. 协议 license

license 字段用于指定软件的开源协议,开源协议里面详尽表述了其他人获得你代码后拥有的权利,可以对你的的代码进行何种操作,何种操作又是被禁止的。同一款协议有很多变种,协议太宽松会导致作者丧失对作品的很多权利,太严格又不便于使用者使用及作品的传播,所以开源作者要考虑自己对作品想保留哪些权利,放开哪些限制。

软件协议可分为开源和商业两类,对于商业协议,或者叫法律声明、许可协议,每个软件会有自己的一套行文,由软件作者或专门律师撰写,对于大多数人来说不必自己花时间和精力去写繁长的许可协议,选择一份广为流传的开源协议就是个不错的选择。

以下就是几种主流的开源协议:

  • MIT:只要用户在项目副本中包含了版权声明和许可声明,他们就可以拿你的代码做任何想做的事情,你也无需承担任何责任。

  • Apache:类似于 MIT,同时还包含了贡献者向用户提供专利授权相关的条款。

  • GPL:修改项目代码的用户再次分发源码或二进制代码时,必须公布他的相关修改。

如果你对开源协议有更详细的要求,可以到 Choose an open source license | Choose a License 获取更详细的开源协议说明。

5. 目录、文件相关

5.1 程序入口 main

{
  "main": "lib/index.js",
}

main 属性可以指定程序的主入口文件,例如,上面 antd 指定的模块入口 lib/index.js ,当我们在代码用引入 antd时:import { notification } from 'antd'; 实际上引入的就是 lib/index.js 中暴露出去的模块。

5.2 命令行工具入口 bin

当你的模块是一个命令行工具时,你需要为命令行工具指定一个入口,即指定你的命令名称和本地可指定文件的对应关系。如果是全局安装,npm 将会使用符号链接把可执行文件链接到 /usr/local/bin,如果是本地安装,会链接到 ./node_modules/.bin/

{
  "bin": {
    "conard": "./bin/index.js"
  }
}

例如上面的配置:当你的包安装到全局时:npm 会在 /usr/local/bin下创建一个以 conard 为名字的软链接,指向全局安装下来的 conard 包下面的 "./bin/index.js"。这时你在命令行执行 conard 则会调用链接到的这个js文件。

5.3 发布文件配置 files

{
  "files": [
    "dist",
    "lib",
    "es"
  ]
}

files 属性用于描述你 npm publish 后推送到 npm 服务器的文件列表,如果指定文件夹,则文件夹内的所有内容都会包含进来。我们可以看到下载后的包是下面的目录结构:

另外,你还可以通过配置一个 .npmignore 或者 .yarnignore 文件来排除一些文件, 防止大量的垃圾文件推送到 npm, 规则上和你用的 .gitignore是一样的。.gitignore 文件也可以充当.npmignore 文件。 

6. 脚本配置 script、config

6.1 script

{

  "scripts": {
    "test": "jest --config .jest.js --no-cache",
    "dist": "antd-tools run dist",
    "compile": "antd-tools run compile",
    "build": "npm run compile && npm run dist"
  }
}

scripts 用于配置一些脚本命令的缩写,各个脚本可以互相组合使用,这些脚本可以覆盖整个项目的生命周期,配置后可使用 npm run command 进行调用。如果是 npm 关键字,则可以直接调用。例如,上面的配置制定了以下几个命令:npm run testnpm run distnpm run compilenpm run build

6.2 config

config 字段用于配置脚本中使用的环境变量,例如下面的配置,可以在脚本中使用process.env.npm_package_config_port进行获取。

{
  "config": { "port" : "8080" }
}

欢迎 关注、点赞、评论!━(*`∀´*)ノ亻!

猜你喜欢

转载自blog.csdn.net/qq_41887214/article/details/120433558