不输Lodash的前端函数库我是怎么做的

337 阅读7分钟

image.png

npm 地址 robinson - npm
git 地址 An-Lijun/Robinson: A Simple Web Utils to implement functionality

引言

在前端开发的世界里,Lodash 无疑是一个家喻户晓的工具库,它提供了丰富且实用的函数,大大提高了开发者的效率。然而,有时候我们可能会有一些特殊的需求,或者想要尝试自己打造一个类似的函数库,于是就有了 Robinson 这个前端函数库。今天,我就来分享一下,我是如何打造一个不输 Lodash 的前端函数库的。PS,可能有点标题党,但是我真认为我这个项目做的还不错,虽然现在还不完善也没多少人使用

项目背景与目标

Robinson 是一个简单的 Web 工具库,旨在为前端开发者提供一系列实用的函数,帮助他们更高效地完成日常开发任务。我们的目标是在功能上尽可能地接近甚至超越 Lodash,同时保持代码的简洁性和易用性。

技术选型与工具

1. 使用 edar-cli 构建

Robinson 是基于 edar-cli(SDK)构建的。edar-cli 为项目提供了强大的开发和构建能力,它可以帮助我们快速搭建项目结构,管理依赖,以及进行代码的编译和打包。通过使用 edar-cli,我们能够更加专注于函数库的核心功能开发,而不必过多担心项目的构建和部署问题。

image.png

注意:这个脚手架也是我自己搭建的不过目前还不完善

2. 选择合适的编程语言

我们选择使用 JavaScript 作为主要的开发语言,因为它是前端开发的基石,几乎所有的前端开发者都熟悉它。同时,为了提高代码的可维护性和类型安全性,我们也会逐渐引入 TypeScript 的支持。

项目结构与组织

一个良好的项目结构对于函数库的开发和维护至关重要。Robinson 的项目结构大致如下:

Robinson/
├── src/
│   ├── core/         # 核心函数模块
│   ├── utils/        # 辅助工具函数模块
│   ├── index.js      # 入口文件,导出所有公共 API
├── test/             # 测试文件目录
├── docs/             # 文档目录
├── package.json      # 项目配置文件
├── README.md         # 项目说明文档

image.png

核心模块设计

在 src/core 目录下,我们会放置一些核心的函数模块,这些函数是 Robinson 的核心功能,例如数组操作、对象操作、字符串处理等。每个模块都会有一个单独的文件,并且会进行详细的注释,以便于其他开发者理解和使用。

辅助工具模块

src/utils 目录下的文件主要是一些辅助工具函数,它们可能会被核心模块调用,或者为开发者提供一些额外的功能。例如,我们可以在这个目录下实现一些日期处理函数、文件操作函数等。

开发规范化

ESLint

在开发过程中保证每个人提交的代码风格一致(虽然只有自己在开发)这里使用eslint进行帮助开发团队保持代码的一致性,遵循特定的编码风格和最佳实践,同时也能发现潜在的错误和安全漏洞。注意这里我配置的Eslint 是会格式化代码的,我这里并没有使用Prettier,实在是不想配置两个工具做兼容了太累了,希望前端赶快出大一同构建工具,@尤雨溪 @bun加油啊我真的不想再配置工具了。

image.png

Husky

Husky 是一个 Git hooks 工具,它可以帮助你在特定的 Git 事件(如 commitpush 等)发生时自动执行一些脚本。在前端项目中,Husky 通常用于在代码提交前执行代码检查、格式化、测试等任务,以确保代码的质量和一致性。(ps:虽然用了但是由于自己开发就比较随性了配置完了几乎没怎么用过)

image.png

函数设计与实现

1. 功能覆盖

为了不输于 Lodash,我们需要尽可能地覆盖 Lodash 的常用功能。例如,Lodash 中有很多数组操作函数,如 mapfilterreduce 等,我们在 Robinson 中也会实现这些函数,并且会根据实际需求进行一些扩展和优化。

2. 性能优化

性能是一个优秀函数库的关键指标之一。在实现每个函数时,我们都会考虑其性能问题,尽量使用最优的算法和数据结构。例如,在实现数组排序函数时,我们会选择合适的排序算法,以提高排序的效率。

3. 错误处理

在函数设计中,我们会充分考虑各种可能的错误情况,并进行相应的错误处理。例如,当用户传入的参数不符合要求时,函数会抛出明确的错误信息,帮助用户快速定位问题。

举个例子 每一个函数都采用 typedoc对文档添加注释 typescript进行类型修饰尽量覆盖全部类型

/**
 * @beta
 * @description `chunkArray` 函数接受一个数组和一个大小参数,并返回一个新数组,其中原始数组被分割成指定大小的较小数组。
 * @param {Array} - `array` 参数是任何类型的数组。它是需要被分成更小的数组的数组。
 * @param {number} [size=1] - “size”参数指定数组每个块中应包含的元素数量。默认情况下,它设置为 1,这意味着每个元素将位于其自己的单独块中。
 * @returns {[Array]} 数组的数组。每个内部数组都包含原始数组中的一块元素。每个块的大小由“size”参数确定。
 * @example
 * ```JavaScript
 * let a=[1,2,3,4,5,6]
 *  getChunkArray(a,2) // [[1,2],[3,4],[5,6]]
 * let a=[1,2,3,4,5,6]
 *  getChunkArray(a,3) // [[1,2,3],[4,5,6]]
 * let a={}
 *  getChunkArray(a,3) // params is not a array
 * ```
 */
export function getChunkArray (array:Array<any>, size:number = 1):Array<Array<any>> {
  if (!isArray(array)) {throw new TypeError('params is not a array');}
  let newArr:Array<any> = [];
  array.forEach((element, index) => {
    if (index % size === 0) {
      return newArr.push([element]);
    }
    return newArr.at(-1).push(element);
  });
  return newArr;
}

文件目录导出设计

这里将函数分为arraybooleancolorcommondatefileformatfunctionmaskmathnumberobjectstringsymbolweb这几个模块,使用export *语法用于重新导出一个模块的所有内容最终从入口文件将所有模块的函数进行导出。

image.png

模块设计

这里有ESM CJS IIFE 和dts

image.png

测试与质量保证

1. 单元测试

为了确保每个函数的正确性,我们会为每个函数编写单元测试。使用 Jest 等测试框架,我们可以方便地编写和运行测试用例,并且可以对测试结果进行可视化展示。

2. 代码覆盖率

代码覆盖率是衡量测试质量的一个重要指标。我们会努力提高代码的覆盖率,确保每个函数的每个分支都被测试到。

image.png

image.png

文档编写与发布

image.png

image.png

1. 文档生成

Robinson 的文档是通过自动化工具生成的。我们可以使用一些文档生成工具,TypeDoc,根据代码中的注释自动生成文档。同时,我们也会手动编写一些详细的使用说明和示例,帮助用户更好地理解和使用函数库。 这里使用 api-extractor 将dts生成json文件 api-documenter 将json文件转为md文件然后引入到vitepress中,使用自己开发的插件+函数脚本将文档目录进行生成出来,后面会合并为一个插件

2. 文档发布

由于文档发布需要先build dts 然后 api-extractor 将dts生成json文件 api-documenter 将json文件转为md文件然后引入到vitepress中所以需要跑很多条命令,这里使用node脚本进行统一发布

image.png image.png 生成的文档会发布到 GitHub Pages 上,方便用户在线查看。同时,我们也会在 NPM 包的 README 文件中提供文档的链接,让用户可以方便地找到文档。

npm 发布

这里跟文档发布一样也是使用node脚本进行发布

image.png image.png

社区支持与反馈

虽然目前 Robinson 主要是为个人使用,但我们也非常欢迎社区的反馈和贡献。用户可以通过 GitHub 的 Issue 系统提交问题和建议,我们会及时回复和处理。同时,我们也鼓励开发者参与到项目的开发中来,共同打造一个更好的前端函数库。