前端 Vite 项目使用 vite-plugin-dts 打包输出类型文件,处理踩坑:Cannot find module 'vue'. Did you ...

最近在尝试做一个自己的前端组件库,build 打包构建的时候要输出 .d.ts类型文件,用到 vite-plugin-dts 这个 vite 插件,这里记录自己的使用和踩坑记录,会逐步分析解决问题,跟着思路相信会比较清晰。

安装 vite-plugin-dts

bash 复制代码
pnpm i vite-plugin-dts -D

简单使用

先 import 导入一下,然后直接作为插件引入即可,例如:

ts 复制代码
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 报错如下:

bash 复制代码
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';

先直接讲解决方案,有耐心的看后续分析

  1. 在根目录下新建 tsconfig.build.json 文件,写入内容如下:
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"
    }
  ]
}
  1. 然后把tsconfig.build.json导入到 vite.config.ts 的插件 dts()中:
ts 复制代码
dts({ tsconfigPath: "./tsconfig.build.json" });
  1. 先 build 一下,看看找不到 Vue 的报错有没有消失,如果消失了说明问题已经解决了,其他的报警应该是路径的问题,把相对路径改成以@/*这种形式的绝对路径,因为tsconfig.build.json中配置了baseUrlpaths,所以要使用绝对路径,而不能使用相对路径,不然插件会找不到。

这样重新 build 就可以了,错误应该会消失。有耐心的朋友可以看看我是怎么一步一步分析和解决的哈。

先说明我的报错的环境

我的项目是 vite 5,vue 3.4, TS 5.4,使用 Vue 官方的推荐安装方式安装的项目环境。安装完成后根目录中有三个 tsconfig 相关的文件,分别是 tsconfig.json,tsconfig.node.json,tsconfig.app.json,其中 tsconfig.json 的内容如下:

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 还是报错,错误几乎没变。

json 复制代码
"paths": {
    "@/*": ["./src/*"]
}

后续又去各个国内外知名论坛社区搜了搜,结果尝试了好多方案还是没解决,真是痛苦。

分析和解决

自己根据报错提示和社区没有找到正确的方式,然后就去 vite-plugin-dts官方 github 仓库,看看 issues(找到了一个跟我类似的但是还没解决,我后续解决了之后还给他写了一大篇英文 comment,我见不得别人受苦哈哈哈),看看源码和文档说明。结果看到了关于 options 的接口说明,其中有这么一个属性字段:

ts 复制代码
/**
   * 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.jsontsconfig.json的内容复制一份进去,然后把这个路径传给vite-plugin-dts插件,就可以了。 我自己的tsconfig.build.json内容如下:

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 配置内容:

ts 复制代码
plugins: [
    vue(),
    vueJsx(),
    dts({
      tsconfigPath: './tsconfig.build.json',
    }),
  ],

这样就可以通过 build 生成类型文件了。

总结

本文介绍了 vite-plugin-dts 插件的安装和使用,以及如何解决报错使用插件时遇到的找不到相关模块的问题,层层分析错误,并最终找到解决方案,授之以鱼,且授之以渔,学会这个思路,下次你也行。有收获的话可以点个赞哟。

相关推荐
别拿曾经看以后~35 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死38 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍