最近在尝试做一个自己的前端组件库,build 打包构建的时候要输出 .d.ts
类型文件,用到 vite-plugin-dts 这个 vite 插件,这里记录自己的使用和踩坑记录,会逐步分析解决问题,跟着思路相信会比较清晰。
安装 vite-plugin-dts
pnpm i vite-plugin-dts -D
简单使用
先 import 导入一下,然后直接作为插件引入即可,例如:
import { resolve } from "path";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, "src/index.ts"),
name: "MyLib",
formats: ["es"],
fileName: "my-lib"
}
},
plugins: [dts()] //在这里作为插件引入
});
处理踩坑
引入插件之前 build 是正常的,引入之后 build 报错如下:
src/index.ts:1:26 - error TS2792: Cannot find module 'vue'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
1 import type { App } from 'vue';
~~~~~
src/index.ts:2:20 - error TS2792: Cannot find module './components/Button'. Did you mean to set the 'moduleResolution'
option to 'nodenext', or to add aliases to the 'paths' option?
2 import Button from './components/Button';
先直接讲解决方案,有耐心的看后续分析
- 在根目录下新建 tsconfig.build.json 文件,写入内容如下:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["src/index.ts", "src/components/**/*", "src/hooks/**/*"],
//include内容根据具体情况自己定制,我是根据组件库自己修改的,如果没动过原来的应该是,下面这个:
//"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
- 然后把
tsconfig.build.json
导入到 vite.config.ts 的插件 dts()中:
dts({ tsconfigPath: "./tsconfig.build.json" });
- 先 build 一下,看看找不到 Vue 的报错有没有消失,如果消失了说明问题已经解决了,其他的报警应该是路径的问题,把相对路径改成以
@/*
这种形式的绝对路径,因为tsconfig.build.json
中配置了baseUrl
和paths
,所以要使用绝对路径,而不能使用相对路径,不然插件会找不到。
这样重新 build 就可以了,错误应该会消失。有耐心的朋友可以看看我是怎么一步一步分析和解决的哈。
先说明我的报错的环境
我的项目是 vite 5,vue 3.4, TS 5.4,使用 Vue 官方的推荐安装方式安装的项目环境。安装完成后根目录中有三个 tsconfig 相关的文件,分别是 tsconfig.json,tsconfig.node.json,tsconfig.app.json,其中 tsconfig.json 的内容如下:
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
分析报错以及初步尝试修改
报错的位置:src/index.ts
。
报错的类型: TS 报错
报错的结果:找不到相关模块。如’vue’,‘./components/Button’
报错修改建议:尝试修改 'moduleResolution'
为 nodenext
,或者给 paths 添加别名。
初步尝试:
尝试一:全局搜索'moduleResolution'
发现他在tsconfig.node.json
中,修改后并没有消除错误。
尝试二:我发现 tsconfig.app.json 中"compilerOptions"
的paths
中已经添加了@/*
,如下,于是我尝试把'./components/Button'
这种相对路径的写法改成带'@/*'
的方式,结果 build 还是报错,错误几乎没变。
"paths": {
"@/*": ["./src/*"]
}
后续又去各个国内外知名论坛社区搜了搜,问了AI 发现好多根社区答案重复,尝试了好多方案还是没解决,真是痛苦。
分析和解决
自己根据报错提示和社区没有找到正确的方式,然后就去 vite-plugin-dts官方 github 仓库,看看 issues(找到了一个跟我类似的但是还没解决,我后续解决了之后还给他写了一大篇英文 comment,我见不得别人受苦哈哈哈),看看源码和文档说明。结果看到了关于 options 的接口说明,其中有这么一个属性字段:
/**
* Specify tsconfig.json path
*
* Plugin resolves `include` and `exclude` globs from tsconfig.json
*
* If not specified, plugin will find config file from root
*/
tsconfigPath?: string,
这段代码就是说的,tsconfigPath 是可选的,如果指定了路径,插件会从指定的路径中读取配置文件,然后根据 include 和 exclude 选项来解析 glob 表达式,如果没有指定就从项目根目录找 tsconfig.json 文件。
这就提示我了,默认不传参,插件会从项目根目录开始搜索 tsconfig.json 文件,然后根据 include 和 exclude 选项来解析 glob 表达式。
但是我自己的 tsconfig.json 文件内部是 references 的其他两个文件,除了这两个里面自己并没有 include 和 exclude 选项,所以插件很可能没有解析到 include 和 exclude,这样的效果就是:插件就相当于没有找到任何文件,所以没有生成类型文件。
为了验证我自己的想法,我去 dist 目录一看果然一个都没有生成.d.ts
类型文件,稍微看一下源码 getTsConfig 函数的实现,发现确实是进行文件读取再解构得出的 include 和 exclude 一系列配置的,更加验证了我的猜想。
于是我尝试把 tsconfig.app.json 中的 include 和"compilerOptions"
的内容复制到 tsconfig.json 中,但是直接就报警告了,说可能会让后续 references 的内容失效,但是我就是想确认一下,所以就没管报警直接 build 的了一下,直接就成功了,现在就只差消除警告了。
上文说过tsconfigPath
可以传进去一个配置,用来代替tsconfig.json
,所以只需要新建一个tsconfig.build.json
把tsconfig.json
的内容复制一份进去,然后把这个路径传给vite-plugin-dts
插件,就可以了。
我自己的tsconfig.build.json
内容如下:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["src/index.ts", "src/components/**/*", "src/hooks/**/*"],
//include内容根据具体情况自己定制,我是根据组件库自己修改的,如果没动过原来的应该是,下面这个:
//"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
vite.config.ts 的 plugins 配置内容:
plugins: [
vue(),
vueJsx(),
dts({
tsconfigPath: './tsconfig.build.json',
}),
],
这样就可以通过 build 生成类型文件了。
总结
本文介绍了 vite-plugin-dts 插件的安装和使用,以及如何解决报错使用插件时遇到的找不到相关模块的问题,层层分析错误,并最终找到解决方案,授之以鱼,且授之以渔,学会这个思路,下次你也行。有收获的话可以点个赞哟。