如何用 TypeScript 来开发 npm 包

首先问一下自己,为什么要用 TypeScript 来开发 npm 包?

用 TypeScript 开发npm包,需要配置一堆东西,比如开发过程中需要使用ts-node或者esno这样的工具把 TS 转化为 JS后再执行,开发完成后也需要构建等等。

如果我的包比较简单,我直接用 JavaScript 不香吗?

之所以,建议使用 TypeScript 来开发 npm 包,首先最重要的一点,一定是对开发者与使用者的类型提示

无论你的包里是只有一个函数的导出,还是有零零总总大几十个函数,类型的存在都能让这个包的使用更加友好。如果你是包的使用者,你是更想"哦,这里类型报错了,我的入参类型不太对",还是"为什么这个地方一直报错呢...可恶啊,查了一通,原来是我的变量到这里的时候类型不对了"?

即使你是在 JavaScript 工程中引用 TypeScript 编写的包,只要配置了 TypeScript 开发环境,也一样能够享受到这些基于类型的辅助能力。

另外一个重要的原因则是,如果你使用了高阶的语法,此时你需要引入 Babel / Rollup 这样的编译工具来做一次语法降级,Babel 的配置略显繁琐,简单场景上 Rollup 又像高射炮打蚊子。

这个时候 TypeScript 自带的语法降级能力就香起来了:只需要简单的几行配置就够用,还带类型,还带简单的 Lint 能力...何乐而不为?

因此,本文将会从头演示如何基于 TypeScript 来编写 + 发布一个 npm 包,包括环境搭建、本地调试、编译配置以及发布等等。

本文内容分为开发阶段和打包阶段。

本地开发阶段

由于 NodeJs 不能直接执行 TS 文件,我们需要 esno 的帮助,它是一个基于 ESBuild 的执行工具,借助 ESBuild 闪电般的速度,首先编译 TS 文件然后再使用 Node 执行。

你可能会想,ESBuild 不支持类型检查吧?不用担心,VS Code 本地有类型检查,加上发布前仍然会使用 tsc 进行编译。

js 复制代码
$ npm i esno -D
$ npx esno ./src/index.ts

在日常开发时,往往会需要频繁地修改然后执行,不断查看代码的输出和表现。

在日常的网页开发中,Webpack Dev Server 已经帮我们很好地处理了这个需要,使用 JavaScript 开发 NodeJs 应用时你可能也习惯了 nodemon,那么 TypeScript 下应该怎么做?

首先,这里也是使用 nodemon,一般习惯的 nodemon index.js 只是它最基本的用法,你其实可以自由地配置文件的执行程序,以及监听哪些文件等等,在 package.json 中进行配置:

js 复制代码
{
  "nodemonConfig": {
    "delay": 500,
    "env": {
      "NODE_ENV": "development"
    },
    "execMap": {
      "ts": "esno",
      "js": "node"
    },
    "ignore": ["node_modules"],
    "verbose": true
  },
}

这样一来,在执行 nodemon index.ts 时,就能够自动使用 esno 来执行 ts 文件了。

编译配置方面,可以参考优雅的配置你的 tsconfig.json这篇文章,以模板中的配置文件为例:

js 复制代码
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ES2015",
    "types": [],
    "outDir": "dist", // 输出到 dist 目录下
    "skipLibCheck": true,
    "moduleResolution": "node",
    "strictNullChecks": true, // 开启严格检查
    "declaration": true, // 输出声明文件
    "declarationDir": "dist/type", // 声明文件放置位置
    "strict": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedParameters": false,
    "noUnusedLocals": false,
    "esModuleInterop": true, // ESM 与 CJS 相关,推荐开启来解决大部分问题
    "allowSyntheticDefaultImports": true, // ESM 与 CJS 相关,推荐开启来解决大部分问题
    "baseUrl": "."
  }
}

由于 npm 包需要手动指定入口,请确保 outDir 与 package.json 中的 main 指向是一致的

js 复制代码
// commonjs格式时入口文件
"main": "dist/index.umd.js",
// es格式时入口文件
"module": "dist/index.es.js",
// 声明文件入口
"types": "dist/types/index.d.ts",
// 这个参数是表面该包是es格式,这里的目的是为了引入rollup.config.js必须要加的
"type": "module"

rollup 打包

首先看一下rollup.config.js配置:

js 复制代码
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from 'rollup-plugin-typescript2'
import json from '@rollup/plugin-json'

export default {
  input: 'src/index.ts',
  output: [
    {
      file: './dist/index.umd.js',
      name: 'CrowllerTs',
      format: 'umd'
    },
    {
      file: './dist/index.es.js',
      format: 'es'
    }
  ],
  plugins: [
    json(),
    typescript({ useTsconfigDeclarationDir: true }),
    commonjs(),
    nodeResolve()
  ]
}
  • @rollup/plugin-node-resolve: 将编写的源码与源码依赖的第三方库进行合并,作为一个完整的包对外输出,不需要用户再去下载第三方库。
  • @rollup/plugin-commonjs:rollup 主要是用来打包es格式书写的模块,如果要打包commonjs格式书写的模块,需要使用这个插件。
  • rollup-plugin-typescript2: rollup-plugin-typescript2 插件在编译时底层也是调用typescript 把 ts 编译成 js,它也会使用tsconfig.json的配置。
  • @rollup/plugin-json: 对于json文件,比如 package.json,我们无法直接引用需要安装json插件。

最后在package.json中加上打包命令:

js 复制代码
"scripts": {
    "build": "rollup -c"
}

这里最重要的是使用rollup-plugin-typescript2来让rollup能够打包TypeScript代码。

另外,tsconfig.json中的"target": "ES5"可以帮我们将代码打包为ES5的语法,所以这里不用再使用babel来进行语法转换了。

关于 rollup 这一部分可以参考网上的资料,这里就不做详细介绍了。

相关推荐
叫我阿柒啊8 小时前
从Java全栈到前端框架:一次真实面试的深度复盘
java·spring boot·typescript·vue·database·testing·microservices
烛阴11 小时前
【TS 设计模式完全指南】用工厂方法模式打造你的“对象生产线”
javascript·设计模式·typescript
定栓11 小时前
Typescript入门-类型断言讲解
前端·javascript·typescript
Thetimezipsby14 小时前
基于Taro4打造的一款最新版微信小程序、H5的多端开发简单模板
前端·javascript·微信小程序·typescript·html5·taro
流影ng15 小时前
【TypeScript】闭包
typescript
葡萄城技术团队16 小时前
TypeScript 队列实战:从零实现简单、循环、双端、优先队列,附完整测试代码
typescript
烛阴1 天前
【TS 设计模式完全指南】从“入门”到“劝退”,彻底搞懂单例模式
javascript·设计模式·typescript
lypzcgf1 天前
Coze源码分析-资源库-删除插件-前端源码-核心组件实现
前端·typescript·前端框架·react·coze·coze插件·智能体平台
江拥羡橙2 天前
【目录-单选】鸿蒙HarmonyOS开发者基础
前端·ui·华为·typescript·harmonyos
叫我阿柒啊2 天前
从Java全栈到Vue3实战:一次真实面试中的技术探索
java·数据库·spring boot·微服务·typescript·vue3·restful