创建自己的TypeScript依赖库

1,883 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

前言

阅读本篇文章您将了解到如下内容:

  • npm package
  • 代码检查
  • 单元测试
  • 打包
  • Git Hooks

本文为应用型文章, 将不会阐述过多理论知识

需求分析

在系统架构层面, 应将不同的功能进行拆分

例如把接口调用客户端与系统接口分为两个依赖库:

  • 接口调用客户端: @houtaroy/api-client
  • 系统接口: @houtaroy/system-api

系统接口中安装依赖@houtaroy/api-client

使用系统接口的项目安装依赖@houtaroy/system-api

这么做的好处有:

  • 低耦合
  • 易于维护
  • 版本管理
  • 不容易产生魔改乱象

再来分析一个完整的依赖库应包含哪些功能:

  • 代码检查
  • 单元测试
  • 打包
  • 提交检查
  • 说明文档

前言中的内容基本相同

技术选型

根据上一节中的功能点, 网上冲浪后可以确定:

  • 包管理器: pnpm
  • 代码检查: eslint + prettier
  • 单元测试: jest
  • 打包: rollup
  • 提交检查: husky
  • 说明文档: vitepress

创建依赖库

初始化依赖库

在依赖库文件夹下运行:

pnpm init

根据情况自定义部分内容后, 生成package.json文件:

{
  "name": "@houtaroy/test",
  "version": "2022.0.0",
  "description": "Houtaroy Test",
  "main": "index.js",
  "author": "Houtaroy",
  "license": "MIT"
}

安装TypeScript

pnpm add typescript -D

安装完成后, 初始化配置文件tsconfig.json:

npx tsc --init

配置项可参考官方文档: TSConfig Reference

例如, 笔者的源码在目录src下, 打包后的文件在lib下, 则需要增加如下配置:

{
    "include": ["src/**/*"],
    "exclude": ["node_modules", "lib", "test"]
}

安装prettier与eslint

prettier负责代码风格检查

eslint负责代码语法检查

很多教程中都使用了二者, 但如何配置却讲的云里雾里, 像是vscode要装一堆插件/再抄一份配置文件等等

笔者给出一个自认为清晰的思路:

使用prettier/eslint/eslint prettier插件, 把代码风格与语法检查全部交给eslint

安装prettier:

pnpm add prettier -D

创建prettier配置文件.prettierrc.js:

export default {
  semi: true,
  singleQuote: false,
  trailingComma: 'none',
  printWidth: 120
}

具体配置内容参照官方文档: Options · Prettier 中文网

安装eslint:

pnpm add eslint -D

安装eslint typescript插件:

pnpm add @typescript-eslint/parser @typescript-eslint/eslint-plugin -D

安装eslint prettier插件:

pnpm add eslint-config-prettier eslint-plugin-prettier

创建eslint配置文件.eslintrc.js, 并使用相关插件:

export default {
  env: {
    browser: true,
    node: true,
    es2021: true
  },
  extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module"
  },
  plugins: ["prettier", "@typescript-eslint"],
  rules: {
    "prettier/prettier": "error"
  }
}

插件主页: prettier/eslint-plugin-prettier(看见没, 官方出的! )

修改package.json, 增加格式化脚本:

"scripts": {
    "lint": "eslint src/**"
}

IDE如何自动格式化请根据实际情况配置

单元测试

安装jest:

pnpm add jest -D

由于我们使用的是typescript, 安装支持插件ts-ject:

pnpm add ts-jest ts-node -D

生成配置文件并修改为jest.config.ts:

export default {
  preset: "ts-jest",
  testEnvironment: "node"
}

假设库的内容为:

import { Sum } from "../types";
​
export class SumClient implements Sum {
  public sum(one: number, two: number) {
    return one + two;
  }
}
​
export default SumClient;

编写测试文件test/sum.test.ts:

import SumClient from "../src";
​
const client = new SumClient();
​
test("测试加法", () => {
  expect(client.sum(1, 2)).toBe(3);
});

package.json增加测试脚本:

"scripts": {
    "test": "jest"
}

运行命令pnpm run test即可进行单元测试

打包

安装rollup:

pnpm add rollup -D

安装typescript插件:

pnpm add @rollup/plugin-typescript -D

因为项目引用了其它库, 需要安装node插件:

pnpm add @rollup/plugin-node-resolve -D

适配commonjs, 安装插件:

pnpm add @rollup/plugin-commonjs -D

创建打包配置文件rollup.config.ts:

import typescript from "@rollup/plugin-typescript";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
​
export default {
  input: "src/index.ts",
  output: [
    {
      file: "lib/index.cjs.js",
      format: "cjs"
    },
    {
      file: "lib/index.esm.js",
      format: "es"
    }
  ],
  plugins: [typescript(), nodeResolve(), commonjs()]
};

package.json中增加打包脚本:

"scripts": {
    "build": "rollup --config"
}

提交检查

安装husky:

pnpm add husky -D

执行初始化命令, 会生成目录.husky:

pnpm husky install

修改.husky/pre-commit, 增加上两节中的代码检查和单元测试:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
​
pnpm run lint
pnpm run test

至此为止, 一套较为完善的依赖库模块已完成

说明文档

说明文档有许多成熟的产品, 笔者这里推荐vitepress

如何使用不再赘述, 可参考官方文档: VitePress (vuejs.org)

总结

可能很多小伙伴在搭建自己的依赖库或脚手架时, 会觉得异常繁琐无从下手

其实我们只需要冷静下来, 一一列举出它的功能

随后寻找对应的开源解决方案, 并认真阅读官方文档

你纠结许久, 百度许久都不能解决的问题, 可能就是官方文档中的一句话或一个示例

最后动手实践

多经历几次你就会发现, 大部分困难都是纸老虎

所有代码已上传至模板仓库: ts-starter: TypeScript Package Starter

我是Houtaroy, 若有一行代码能为他人提供帮助, 便是在下的毕生荣幸