用最懒的方法写一个属于自己的js工具库

用最懒的方法写一个属于自己的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-templatelibTemplate替换成你自己的库的名字。

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方法,这里举个使用例吧:

    ts 复制代码
    export 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三个方法。见下方伪代码:

    ts 复制代码
    A.then(a)
    B.then(b)
    C.then(c)

    但如果abc有顺序要求,就不能这样了,可以:

    ts 复制代码
    Promise.all([A,B,C]).then(() => { a(); b(); c(); })

    但这样还是不够完美。如果A首先完成请求,a也是第一个执行的方法,此时已经可以把他执行了,但他却要等待后面的完成,我们希望更进一步:

    ts 复制代码
    const 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

技术交流请加 : (并没有那样的群!)

更多其他文章见 : (并没有那样的其他文章!)

相关推荐
真的很上进4 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
噢,我明白了7 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__7 小时前
APIs-day2
javascript·css·css3
关你西红柿子7 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
济南小草根8 小时前
把一个Vue项目的页面打包后再另一个项目中使用
前端·javascript·vue.js
小木_.8 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析
Aphasia3118 小时前
一次搞懂 JS 对象转换,从此告别类型错误!
javascript·面试
m0_748256569 小时前
Vue - axios的使用
前端·javascript·vue.js
m0_748256349 小时前
QWebChannel实现与JS的交互
java·javascript·交互
胡西风_foxww9 小时前
【es6复习笔记】函数参数的默认值(6)
javascript·笔记·es6·参数·函数·默认值