赞
踩
本人想用 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 |
以下写下了我对于该问题的排查思路,解决办法可直接查看最下面
当我根据官方文档在项目中引用后,发现生成的类型文件只有 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', }, }, }, }, })
没有任何问题,且配置文件中内容都是脚手架默认生成的配置,插件官网也没有任何需要修改的地方,但是就是无法生成
翻阅了 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
相关配置,因此无法生成对应目录下的类型文件
因为今年才开始从 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 配置不正确导致无法正常的生成对应的类型文件
很难说这个应该是 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)) } }, })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。