记录一次由Vite生成的Vue模板使用 vite-plugin-dts 插件无法正常生成类型文件的问题
关于最新版Vite生成的Vue项目无法正常使用 vite-plugin-dts 插件的问题排查历程
本人想用 Vite+vue3+ts 写一个组件库,想着顺便生成类型文件便于引用该库的项目使用,看了一圈,感觉
vite-plugin-dts
插件很不错,故开始了探索之路
版本
版本 | |
---|---|
Vue | ^3.3.4 |
Vite | ^4.4.11 |
TypeScript | ~5.2.0 |
vite-plugin-dts | ^3.6.3 |
@vue/tsconfig | ^0.4.0 |
分析与解决
以下写下了我对于该问题的排查思路,解决办法可直接查看最下面
1.发现现象
当我根据官方文档在项目中引用后,发现生成的类型文件只有 index.d.ts
,这明显是不对的,我的组件和类型文件都没有生成,如下:
我反复检查了我的 tsconfig.app.json
文件:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "packages/**/*", "packages/**/*.vue", "packages/**/*.ts", "packages/**/*.tsx"],
"exclude": ["src/**/__tests__/*", "node_modules"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
以及 tsconfig.json
文件:
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
以及 vite.config.ts
文件:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import dts from 'vite-plugin-dts'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
dts(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build: {
outDir: 'statics',
lib: {
// Could also be a dictionary or array of multiple entry points
entry: resolve(__dirname, 'packages/index.ts'),
name: 'Package',
// the proper extensions will be added
fileName: 'index',
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ['vue'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue',
},
},
},
},
})
没有任何问题,且配置文件中内容都是脚手架默认生成的配置,插件官网也没有任何需要修改的地方,但是就是无法生成
2.找到症结
翻阅了 Github 中的issue,虽然类似的问题看见不少,但貌似都不是我这种现象,且类似问题出现的版本都比较低,开发者已在新版进行了修复
当我仔细尝试后发现,不管我在 packages
目录下新建 Vue 文件还是 TS 文件都无法生成,此时感觉并不是无法生成类型文件,感觉更像是 tsconfig
中的 include
作用域并没有生效,这是为什么呢?
翻阅 dts()
相关属性时,我发现了该属性:
翻译人话就是:指定 tsconfig
文件的路径并去处理 include
和 exclude
细心的人可能一开始也注意到了——我贴出的 tsconfig
配置的所在文件是 tsconfig.app.json
,不妨设置一下该属性看看?嘿,您猜怎么着,成了!
既然这样,不妨看看该插件中如何处理的,在该插件的源码中的 plugin.ts
文件中有这么一段:
async buildStart() {
...
configPath = tsconfigPath
? ensureAbsolute(tsconfigPath, root)
: ts.findConfigFile(root, ts.sys.fileExists)
const content = configPath
? createParsedCommandLine(ts as any, ts.sys, configPath)
: undefined
...
...
...
include = computeGlobs(options.include, content?.raw.include, '**/*')
exclude = computeGlobs(options.exclude, content?.raw.exclude, 'node_modules/**')
...
}
上面代码主要就是用于判断是否获取指定的 tsconfig
中的路径来加载配置文件,既然这样我们去除配置并在 node_modules
中修改下代码打印一下此时的配置内容是什么,打印如下:
{
options: {
configFilePath: 'E:/Package/tsconfig.json',
outDir: undefined
},
watchOptions: undefined,
fileNames: [],
projectReferences: [
{
path: 'E:/Package/tsconfig.node.json',
originalPath: './tsconfig.node.json',
prepend: undefined,
circular: undefined
},
{
path: 'E:/Package/tsconfig.app.json',
originalPath: './tsconfig.app.json',
prepend: undefined,
circular: undefined
}
],
typeAcquisition: { enable: false, include: [], exclude: [] },
// 注意这一行
raw: { files: [], references: [ [Object], [Object] ] },
errors: [],
wildcardDirectories: {},
compileOnSave: false,
vueOptions: { target: 3.3 }
}
好嘛,原因找到了,这里插件读取的是 tsconfig.json
中的数据,并没有 include
和 exclude
相关配置,因此无法生成对应目录下的类型文件
3.原因探明
因为今年才开始从 vue-cli
转向 vite
,所以我深刻的记得原来的 Vite 项目中是没有 tsconfig.app.json
文件的,但是 Vite 打包是没有问题的,那说明它是可以正常加载到该配置文件的
一开始我以为是 Vite 的锅,但一想不对,Vite 这么大的体量不应该出现这个问题,这样岂不是相关插件都会受到相关影响吗
最终我把目标瞄向了 Vue,毕竟是基于 Vite 生成的 Vue 项目模板,那会不会是 Vue 模板生成的问题呢?
在 create-vue 项目的issue中注意到了这么一点:
根据这里提供的链接跳转到 tsconfig 对应的issue 发现在0.3版本之后将配置文件进行了拆分:
这就能解释 tsconfig.app.json
文件是如何出现的了,基于此基本可以定位是属于该改动导致的插件读取的 tsconfig 配置不正确导致无法正常的生成对应的类型文件
4.解决办法
很难说这个应该是 create-vue
的问题还是 vite-plugin-dts
插件的问题,但解决办法也是很显然的,只要给当前插件指定正确的 tsconfig 配置文件即可,即:
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
dts({
// 指定 tsconfig 文件
tsconfigPath: 'tsconfig.app.json'
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
})
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)