本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群最近公司的很多项目都用到相同功能的时间格式化函数,如果每次来一个项目都拷贝一份代码的话,就很麻烦,结合我们之前介绍的 Verdaccio 搭建 npm 私有服务器;本文我们通过 Vite 作为脚手架,封装一个时间函数的组件库。
封装时间函数,就绕不开强大的 Momentjs 库,但是 Momentjs 库又比较大,我们打包的时候不想将其打包进我们的库中,打包时需要将依赖包进行排除;因此本文我们主要来看下如何通过 Vite 封装一个纯工具库,并且发布到内部的 Verdaccio 上使用。
框架搭建
首先我们使用 pnpm 包管理器搭建一个 Vite 项目,选择库打包模式。
pnpm create vite输入我们项目的名称,然后选择框架,选择其他 Others:
选择框架
这一步是选择项目的模板,我们在这里选择库模式:
模板
最终我们生成项目模板的基本目录结构如下:
|- lib
|- main.ts
|- public
|- vite.svg
|- src
|- main.ts
|- style.css
|- typescript.svg
|- vite-env.d.ts
|- index.d.ts
|- index.html
|- package.json
|- tsconfig.json
|- vite.config.ts这里我们对主要的文件和文件夹进行使用的说明;lib 作为我们项目模块的主要存放目录,可以将我们不同的函数和模块等,放到它的下面,最后使用 index.ts 进行统一导出。
src 目录是调试目录,我们可以在 main.ts 中引入 lib 中的模块,进行调试,测试功能是否正常调用;因此这个文件夹下面的 style.css 和 svg 文件基本用不到。
❝
想要在局域网中开启调试,在 package.json 中修改 dev 添加
--host参数。❞
此外,还有两个文件夹是打包后出现,一个是 dist 文件夹,生成打包后的文件;另一个是 types 文件夹,存放生成的类型声明文件;因此我们调整后的目录结构大致如下:
|- dist
|-(打包后的文件)
|- lib
|- index.ts
|- (其他模块)
|- src
|- main.ts
| types
|- index.d.ts
|- (其他类型声明文件)
|- package.json
|- vite.config.ts使用块级注释
我们项目的主要结构基本定义完后,先来写两个工具函数尝试一下,在 lib 目录下新建一个 format.ts,导出两个函数,用来实现时间戳和时间字符串的相互转换:
import moment, { MomentInput } from "moment";
// 将时间戳转换成时间字符串
export function formatTimestampToDate(
timestamp: MomentInput,
formatter = "YYYY-MM-DD HH:mm:ss"
) {
return moment(timestamp).format(formatter);
}
/**
* 将时间字符串转换成时间戳
* @param {String} date 时间格式,例如2023-06-01 02:00:00
* @returns {Number} 返回时间戳,例如1689264000000
*/
export function formatDateToTimestamp(date: MomentInput) {
return moment(date).valueOf();
}接着我们需要在 lib/index.ts 中进行统一导出:
export { formatTimestampToDate, formatDateToTimestamp } from "./format";上面的两个函数,我们发现使用了两种注释方式,一个是我们常见的行内注释,也就是两个斜杠的方式;另一个是比较详细的块级注释,将入参和出参都详细的标注说明;块级注释的好处,让我们在src/main.ts中引入两个函数看下实际的效果就知道了。
行内注释
块级注释
很容易就发现,使用块级注释,在调用函数时具有很好的提示效果;这样别人在调用我们封装的函数时,就不用担心不知道函数的怎么调用,以及入参怎么传的问题了。
那么如何来生成这样的注释呢?VSCode 提供了一个插件 jsdoc,我们可以在商店中很方便的搜索并安装:
jsdoc
插件的使用也很简单,我们只要写前面/**,然后 VSCode 就会自动提示使用 jsdoc 的注释了。
使用 jsdoc
生成类型声明文件
我们在上面目录结构中说到,types 文件夹用来存放生成的类型声明文件;这些类型声明文件包括上面编写的函数注释以及入参出参的类型;它的作用,主要就是在我们安装项目依赖后,VSCode 就会从依赖中找到声明文件,进行提示操作,方便包的使用者来调用函数。
因此类型声明文件就相当于是我们项目提供给外部的一份说明书,其重要性自然不必多说,但是如果让我们一个函数一个函数的编写说明书,大家肯定是不乐意的;那么回到我们的项目上来,看下如何根据我们导出的函数,自动的生成类型声明文件呢?
❝
可以将项目根目录下初始化生成的
index.d.ts文件删除。❞
打开tsconfig.json文件,添加类型声明文件的配置,outDir属性设置输出的目录:
{
"compilerOptions": {
+ "declaration": true,
+ "outDir": "types",
+ "emitDeclarationOnly": true,
- "noEmit": true,
},
- "include": ["src"],
+ "include": ["lib"]
}这里 include 属性是设置生成类型声明文件需要包含的文件夹,我们上面定义了 src 作为调试目录,因此这里需要改为我们代码的主要目录 lib;修改后我们进行打包,可以看到我们的类型声明文件已经生成在 types 目录下了:
类型声明文件
此外,我们还需要将 package.json 中的types属性进行修改,告诉包的调用者,我们的类型声明文件放在哪:
{
- "types": "./index.d.ts",
+ "types": "./types/index.d.ts",
}依赖管理
在平时的开发中,相信大家对dependencies和devDependencies比较了解了,我们知道dependencies是我们项目运行所必须的依赖,比如我们正常开发一个项目,用到 vue、react、element-plus 等依赖,都可以放到这里;而devDependencies则是在开发过程中用到的依赖,比如 typescript、vite、webpack 等涉及编译打包等一些依赖,都是放到 devDependencies 字段。
那么如果别人在安装我们开发的包时,npm 会如何处理 devDependencies 字段里面的包呢?很明显,npm 不会去管这个字段,这个字段只是在我们包在开发中用到的依赖。
而另外一个peerDependencies这个字段我们在平时项目开发中接触的比较少,它的翻译过来的意思就是对等依赖;就像我们在包里封装时间函数时,需要用到 Momentjs 库,但是如果打包的时候将其打包进去,会导致整个包非常臃肿,如果调用我们包的项目也安装了 Momentjs 库,就会造成资源重复打包。
这时,我们就可以在 package.json 中,添加peerDependencies,告诉包的调用者,想要安装我,首先要安装这个字段下面所有的包;如果我们去看 vuex 和 vue-router 的包,我们会看到它们的 package.json 中都将 vue 设置为对等依赖:
{
"peerDependencies": {
"vue": "^3.2.0"
}
}那么回到我们的项目中来,我们在安装 Momentjs 时,可以添加--save-peer参数:
pnpm add moment --save-peer在 vite 打包时,还需要通过配置将其从打包中排除:
import { defineConfig } from "vite";
export default defineConfig({
build: {
// 其他配置
rollupOptions: {
external: ["moment"],
output: {
globals: {
moment: "moment",
},
},
},
},
});这样,后续当我们在项目中安装我们开发的包时,我们会看到提示安装了两个依赖包, 即包本身及其下面对等依赖的包;如果我们去查看 node_modules,目录下中也有了 moment。
npm install vite-library-demo
added 2 packages in 2s发包
写到这里,我们的包基本的功能已经都具备了,可以进行发包的操作了;这时我们又面临了一个问题,我们需要对哪些文件进行打包然后发布上去呢?
根据上面的项目结构,我们主要需要发布的就是 dist 和 types 文件夹,而 lib 和 src 文件夹都是需要排除的。和.gitignore一样,.npmignore文件是用来指定在发包时需要排除的目录;此外,下面这些文件是默认发布的,加不加到 ignore 都没有影响:
package.json
README.md
LICENSE
CHANGELOG
❝
当项目中没有指定
.npmignore时,默认使用.gitignore文件❞
因此,我们在项目根目录新建一个.npmignore文件,写入如下内容,将我们不需要的文件和文件夹进行发包时的排除:
node_modules
src
lib
vite.config.ts
tsconfig.json
index.html此外,如果我们项目下文件比较多,一个一个排除比较麻烦,我们可以参考 vuex 包的 package.json,将我们需要发布的文件,直接放到files属性下即可:
{
"files": [
"dist",
"types"
],
// 其他属性
}因此,我们可以发现,包文件的优先级从高到低如下顺序:
files属性 > .npmignore > .gitignore另外这里有一个非常实用的小技巧,我们不需要每次 publish 后再查看包的内容,可以通过npm pack先生成一个包进行预览,再通过tar -tf XXX.tgz就可以预览包了。
发布预览
最后,我们可以在这个包里添加一些发布信息,例如包作者和主页的信息:
{
"author": "",
"homepage": "",
// 其他属性
}当然别忘了,添加 READMD.md 说明,告诉大家你这个包是做什么用的;最后,在激动的输入npm pubsh命令后,我们的包就正式发布到 Verdaccio 上去了,快去告诉你的小伙伴来调用你的包把。
发布❞
聊了这么多 Vite 封装工具库的教程,你学会封装并发布它了吗?
Node 社群
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一波👍