用最懒的方法写一个属于自己的js工具库
示例项目在github开源,这也是我的个人工具库:@s3xysteak/utils
这个文章主题是创作一个js工具库,包括准备,开发,构建,分发的全部流程。
准备
这里可以直接使用我的 lib-template 为基础进行开发。为了方便下面的开发,这里简单对lib-template
这个库做个介绍:
- 开发 -
ts
没什么好说的。eslint
使用@antfu/eslint-config
。 - 测试 -
vitest
- 构建 -
unbuild
- 分发 -
export-collector
(这也是我的另一个库) 用于收集导出,方便使用时集成unplugin-auto-import
。使用github workflow发布并上传到npm
sh
$ degit https://github.com/s3xysteak/lib-template
下载lib-template
,也可以直接克隆仓库手动删除.git
文件夹。 把项目中所有lib-template
和libTemplate
替换成你自己的库的名字。
sh
$ pnpm i
$ pnpm build
你应该能成功打包,到这一步,模板是没有问题的。在vscode把他发布到github仓库。
开发
这其实是可以直接跳过的,因为开发没啥好说的,看你想要搓什么库。这里就介绍一下我的 @s3xysteak/utils
,不怎么感兴趣的可以直接跳过到下一章构建章节。这同样是使用 lib-template
为基础开发的我个人使用的库,你可以打开这个库的仓库页面,跟着文章一起看。
package.json
最外层目录都是些几乎不需要动的配置项,这里稍微讲下 package.json
,因为这个自定义程度比较高,可能根据你的需求会有比较大的变动。
name
项目名字,你应该在准备章节改成你的库名了。version
这里不需要手动修改,这会在分发章节讲到。private
如果你不想公开给所有人使用,你应该改为true,这在上传到npm后其他人无法使用。repository
你需要设定成自己的仓库地址,否则分发章节会出错。publishConfig
不设定这个的话,如果你在用npmmirror国内镜像,他会只上传到镜像而不上传到npmjs。scripts
一些脚本build-only
这会在构建章节讲到,这里是直接调用了一个脚本。esno是一个插件,esno xxx.ts
相当于node xxx.js
,他能自动识别ts和js并正确执行。test
启动vitest,这会自动在测试模块更新时重新测试,这在你开发库时非常有用。test-once
只测试一次。release
发布,这会在分发章节讲到,同样是执行了一个脚本。lint:fix
使用eslint修复你的代码。
src
接下来到src
文件夹内
src/index.ts
这是入口文件,导出了所有核心代码,第一行重导出了@antfu/utils
这个库,因为有些造过的轮子就没必要造了。下面有一段奇怪的内容被注释包裹住,这里是export-collector
自动生成的,这里先忽略,这会在构建
章节讲到。
src/core
接下来到src/core
文件夹内
这里就是一些核心代码了,感兴趣的可以看看我常用的工具,都是比较简短且浅显易懂的,有几个比较复杂的提一下吧。
-
fp.ts - flow
从左往右的函数管道,这是一个函数式编程的概念。其实已有的库中已经有不少这样的轮子的,但是都不尽人意,要么类型有问题,要么重导出有问题,所以自己搓了一个。 -
base.ts - onDevFactory
这是一个工厂函数,用于创造一个onDev方法,这里举个使用例吧:tsexport const onDev = onDevFactory(import.meta.env.DEV) /* eslint-disable no-console */ export const Console = { log: (...args) => onDev(() => console.log(...args)), warn: (...args) => onDev(() => console.warn(...args)), error: (...args) => onDev(() => console.error(...args)), }
这样你就可以使用
Console.log
替代console.log
,因为Console.log
只会在开发环境执行,生产环境下不执行。 -
promise.ts - createPromiseQueue
这个方法会让promise并行执行,但是其resolve会同步按顺序执行。假如我有ABC三个请求,请求结束后要进行abc三个方法。见下方伪代码:tsA.then(a) B.then(b) C.then(c)
但如果abc有顺序要求,就不能这样了,可以:
tsPromise.all([A,B,C]).then(() => { a(); b(); c(); })
但这样还是不够完美。如果A首先完成请求,a也是第一个执行的方法,此时已经可以把他执行了,但他却要等待后面的完成,我们希望更进一步:
tsconst queue = createPromiseQueue() queue.run(A,a).run(B,b).run(C,c)
如果A先完成请求,则立即执行a;如果B先完成请求,他会等待a执行结束后再执行b;C同理。
-
defineRequest/axiosFactory.ts - defineRequestAxiosFactory
这是一个方便收集后端接口的工厂方法。这里不多废话了,可以看注释和test文件。
构建
使用unjs的 unbuild
进行构建。
sh
$ pnpm build
这会进行 tsc
类型检查,然后执行 scripts/build.ts
脚本。 export-collector
是我另一个库 ( 参见同名github仓库 ),这里的 expGenerator
作用是递归的获取所有具名导出的名字,然后生成一段代码,见src/index.ts
下面用注释包裹的部分。这是用于方便 unplugin-auto-import
的,发布后可以像这样使用:
ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import { autoImport as AutoImUtils } from '@s3xysteak/utils'
export default defineConfig(() => {
plugins: [
AutoImport({ imports: [ AutoImUtils() ] })
]
})
这样就能直接进行自动引入了。
完成这一步脚本后,下面会运行 unbuild
指令,更多细节见 unbuild.config.ts
,这里一般不需要改,我就不废话了。
构建完成后会出现 index.mjs, index.cjs, index.d.ts, index.d.cts, index.d.mts
,其中包含打包后的源码和类型文件。
分发
在此之前,你首先需要有个自己的npm账号,获取你的npm token,应该是一个以 npm_
开头的秘钥,把他放进你的仓库的secret里,取名为 NPM_TOKEN
。
执行 pnpm release patch
,这会执行 scirpts/release.ts
脚本。
这会将你的包提升一个小版本,并且上传到github。同时这个行为还会触发 github workflow
中的 release
脚本,见 .github/workflows/release.yml
他会在github发布你的包,并且上传到npm。
这个脚本在提升版本上和 npm version
行为类似,他还接受 minor major 两个参数:
pnpm release patch
pnpm release minor
pnpm release major
尾声
我的github主页:github.com/s3xysteak 。内有大量垃圾包,欢迎交流与贡献!
我的库 :
vite-plugin-cesium-build
cesium的Vite插件,一键完成各种准备工作。cesium-use
非侵入式的基于vue的轻量cesium库,有配套文档网站。tauri-version
tauri的版本升级ci,提供类似于npm version的行为。export-collector
收集具名导出的名字,基于@swc
。
技术交流请加 : (并没有那样的群!)
更多其他文章见 : (并没有那样的其他文章!)