制作npm包目录
本文是系列文章, 作者一个橙子pro,本系列文章大纲如下。转载或者商业修改必须注明文章出处
一、申请npm账号、个人包和组织包区别
二、了解 package.json 相关配置
三、 了解 tsconfig.json 相关配置
四、 api-extractor 学习
五、npm
包制作完整教程,我的第一个npm包
学习 package.json
各大项目的根目录都可以看到package.json
这个文件,这个文件到底有什么作用了。对于这个文件的配置项很多,其中最常配置的name
、version
,在平时开发种,大多数配置项可能非常没用。但是对于制作一个安装包而言,太重要了,这里必须解释一番。
这个json 大致是我的npm
项目当中用到的配置,其它的
{
"name": "@v3p/npm-pkg-by-vite",
"version": "1.0.5-0",
"description": "基于vite的npm包模板",
"type": "module",
"files": [
"dist"
],
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"dev:demo": "cd example && vite",
"build:demo": "cd example && vite build",
"build": "vite build",
"build-types": "vue-tsc -p ./tsconfig.types.json && api-extractor run -c api-extractor.json && node scripts/cleanup.js",
"build-all": "npm run build && npm run build-types"
},
"keywords": [
"一个橙子pro",
"vue",
"vite",
"typescript"
],
"repository": {
"type": "git",
"url": "git+https://github.com/vue3plugin/npm-pkg-by-rollup.git"
},
"author": "biancangming",
"license": "MIT",
"bugs": {
"url": "https://github.com/vue3plugin/npm-pkg-by-rollup/issues"
},
"homepage": "https://github.com/vue3plugin/npm-pkg-by-rollup#readme",
"devDependencies": {
"@microsoft/api-extractor": "^7.36.4",
"@types/node": "^20.4.8",
"@vitejs/plugin-vue": "^4.2.3",
"tslib": "^2.6.1",
"typescript": "^5.1.6",
"vite": "^4.4.9",
"vue": "^3.3.4",
"vue-tsc": "^1.8.8"
},
"dependencies": {
"@tsconfig/node18": "^18.2.0",
"@vue/tsconfig": "^0.4.0"
}
}
name
仓库的名字,这个名字可能在开发项目的时候没放在心上。对于npm
包而言,当我们发布一个插件之后,使用npm install xx
命令时,npm网站就会查找这个名字,下载到本地的node_modules
文件夹里面。
以@
开头的就是组织的命名方式了。
一般在项目使用第三方包的时候,无论是require
还是import
实际上是调用的这里的名字。这点,在制作包的章节会重点介绍。
version
当我们在项目根目录执行npm version xxx
命令时,这个版本号会随之变动。这块建议反复练习,自行观察。
version 的格式是major.minor.patch-prerelease
, 并且需要遵循该规则。这个字段是一个包当中十分必要的字段,该字段由四位组成,分别是主要版本号、次要版本号、补丁版本号、最后存在短杠连接的表示预览版本,且存在一个预览的版本号
版本号的主要操作命令是,npm version
,我们可以直接执行类似,npm version 1.0.0
的命令修改当前的版本号,如果只是这样的话,还不如在 package.json
文件当中手动修改。
在官方的解释当中,它的命令是这样的。
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
下面是对该命令用法上的一些举例
npm version major
执行该命令修改主要版本号+1,同时清除预览版本号(如果存在)
npm version minor
执行该命令修改次要版本号+1,同时清除预览版本号(如果存在)
npm version patch
执行该命令修改补丁版本号+1,同时清除预览版本号(如果存在)
npm version premajor
执行该命令修改主要版本号+1,同时添加预览版本号(如果不存在)
npm version preminor
执行该命令修改次要版本号+1,同时添加预览版本号(如果不存在)
npm version prepatch
执行该命令修改补丁版本号+1,同时添加预览版本号(如果不存在)
npm version prerelease
执行该命令预览版本号+1
npm version from-git
执行该命令拉取git版本号,同步为npm版本
在使用一个安装包的时候,通常会看到安装包的每个版本前有类似^
、~
这种符号。
"vue": "^3.3.4" //
一旦有了符号的存在,则表示我们在执行npm install
的时候,安装的并非看到的版本。
^
表示锁定主版本,后边的版本是不会锁定的,在执行npm i
的时候,也可能安装的是3.4.x
的版本。
~
表示锁住主版本和次要版本,只更新补丁版本
之前就有vue从2.6 升级2.7直接支持了
composition-api
的语法,导致我司大量项目翻车,只好逐个把项目当中^
改为~
。如果项目长时间搁置的话,建议将package-lock.json
文件甚至node_modules
一直做保留,血泪教训😥
type
用于指定 npm 包的类型,这个字段比较特殊,它影响的是开发阶段。目前对于新版的node
来说有两种导包方式,目前可取值 commonjs
和module
。设置为module
,在根目录的配置文件就可以直接使用import
方式导入包,而不需要module.exports
的形式
files
在发布包的时候特别有用,用于控制推送到npm
仓库包不包含多余的文件。
files 的值是一个数组,值是文件名或者文件夹名,如果是文件夹名,则文件夹下所有的文件也会被包含进来(除非文件被另一些配置排除了)
根目录下创建一个.npmignore文件,这个文件当中可以写入文件名或者文件夹名,用于排除某些文件。
文件示例如下
.vscode
demo/
etc/
main
main 字段指定了模块的入口文件,它的值是一个相对于项目根目录的路径。一般提供给commonjs
模块系统使用,在项目当中使用require
导入则使用这个字段
module
这个字段指定了用于 ES6 模块的入口文件。如果你的模块使用了 ES6 模块语法,并且想要在支持该语法的环境中使用该模块,就需要指定 module 字段。
一般提供给es
模块系统使用,在项目当中使用import .. from ..
导入则使用这个字段
types
这个字段指定了 typeScript
类型定义文件的入口,用于ts
项目当中类型推断使用
exports
在 package.json
中,exports
字段是一个对象。表示可以定义多种类型的导入形式。例如:
{
"exports": {
".": "./index.js",
"./utils": "./lib/utils.js"
}
}
这种方式的导入默认是es
的导出方式,下面还有一种写法
"exports": {
".": {
"import": "./dist/mjs/index.mjs",
"require": "./dist/cjs/index.cjs",
"types": "./dist/npm-pkg-by-rollup.d.ts"
}
},
这种方式则支持多种方式导出,对我们来说更加通用。后边在介绍npm
制作时,对这里会进行一些拓展。
exports 可以替代上边几种类型,但是我们一般这四个字段都需要定义。毕竟旧版的node并不是全部能够支持这些字段,例如node12版本,可能还不识别exports
。如果了解前端的模块化历史,就知道前端的模块化统一有多艰难,不过目前来说,一直向es
模块化归一了。
author
指明项目的作者,网站上在keywords
下方显示
keywords
这个关键词是一个字符串数组,描述安装包的关键词。关键字在搜索包的时候,随着搜索结果出现在列表下方。
description
一个描述当前项目的简短说明,描述同样显示在搜索结果当中。这个和keywords
关键字一样重要,要不然别人在搜索包的时候没有任何描述,难免有些苍白。
scripts
可运行于命令行的脚本命令的对象,它们用来执行项目中特定的任务。
repository
指向项目代码的 Git 存储库的 URL 的对象。
homepage
当前项目的主页 URL,和上方的repository
在网站显示在如图位置。
license
一个字符串,指明当前项目的开源许可证。
bugs
指定对项目有疑问时,去哪里进行提问。
dependencies
一个包含当前项目的生产环境所需的所有第三方包和模块的对象。
devDependencies
当前项目里面的开发依赖包,开发依赖包和上边的dependencies
,很多人难以区分作用。的确,在日常开发的时候作用不是很明显,但是当制作安装包时就体现出作用了。当我们的依赖包被别人安装时, devDependencies
里面的东西是不会被安装的。
通常使用npm i xx -D
安装此类依赖包
peerDependencies
用于指导npm安装正确的依赖版本。
例如:某项目依赖vue 3.2.1
这个版本,当我们安装当前包时,会根据peerDependencies的配置,寻找响应依赖版本是否已经被安装,如果依赖包没有被安装,或者安装版和已经安装的版本存在冲突,则会终止安装过程。
可以使用–legacy-peer-deps
参数,绕过这种机制。