关于vue按需引入ElMessage和ElMessageBox未被自动引入到auto-important的问题

发布时间 2023-07-13 16:05:57作者: 吃不棒的胖胖糖
相信关于按需引入大家应该都会了,不论是官网还是百度一大堆教程
我这边也是参照https://github.com/youlaitech/vue3-element-admin的写法去写的

这里复述一遍,作为笔记:
首先安装unplugin-vue-components 和 unplugin-auto-import这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
yarn add -D unplugin-vue-components unplugin-auto-import

 

// 自动导入配置   vite.config.ts

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";

plugins: [
  AutoImport({
    // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
    imports: ["vue"],
    eslintrc: {
      enabled: true, // 是否自动生成 eslint 规则,建议生成之后设置 false 
      filepath: "./.eslintrc-auto-import.json", // 指定自动导入函数 eslint 规则的文件
    },
    dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 指定自动导入函数TS类型声明文件路径
  }),
  Components({
    dts: path.resolve(pathSrc, "types", "components.d.ts"), // 指定自动导入组件TS类型声明文件路径
  }),
]


// .eslintrc.cjs 自动函数eslint规则引入

"extends": [
    "./.eslintrc-auto-import.json"
],


// tsconfig.json - 自动导入TS类型声明文件引入
教程是
{
  "include": ["src/**/*.d.ts"] // 关键点
}
这么点,看不起谁呢?-----------我直接爬你墙头全部覆盖0.0
{
    "compilerOptions": {
      "target": "esnext",
      "useDefineForClassFields": true,
      "module": "esnext",
      "moduleResolution": "node",
      "strict": true,
      "jsx": "preserve",
      "sourceMap": true,
      "resolveJsonModule": true,
      "esModuleInterop": true,
      "lib": ["esnext", "dom"],
      "baseUrl": ".",
      "allowJs": true,
      "paths": {
        "@/*": ["src/*"]
      },
      "types": ["vite/client", "unplugin-icons/types/vue"],
      "skipLibCheck": true /* Skip type checking all .d.ts files. */,
      "allowSyntheticDefaultImports": true /* 允许默认导入 */,
      "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */
    },
    // 这里多了个src/types/**/*.d.ts,因为我是放在src/types/目录下,不加的话默认根目录
    "include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts","**/*.d.ts",],
    "exclude": ["node_modules", "dist", "**/*.js"],
    "references": [{ "path": "./tsconfig.node.json" }]
  }

  

 还有一个整合版本

 不得不说整挺好0.0

安装 Element Plus
npm install element-plus
安装自动导入 Icon 依赖 npm i -D unplugin-icons

vite.config.ts 配置 

// 我直接上干货,我的完整配置经测试的没问题的版本,只多不少

import vue from '@vitejs/plugin-vue'

import { UserConfig, ConfigEnv, loadEnv, defineConfig } from 'vite'

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'

import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

import path from 'path'
const pathSrc = path.resolve(__dirname, 'src')

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
    const env = loadEnv(mode, process.cwd())
    return {
        resolve: {
            alias: {
                '@': pathSrc
            }
        },
        css: {
            // CSS 预处理器
            preprocessorOptions: {
                //define global scss variable
                scss: {
                    javascriptEnabled: true,
                    additionalData: `@use "@/styles/variables.scss" as *;`
                }
            }
        },
        server: {
            host: '0.0.0.0',
            port: Number(env.VITE_APP_PORT),
            open: true, // 运行是否自动打开浏览器
            proxy: {
                // 反向代理解决跨域
                [env.VITE_APP_BASE_API]: {
                    target: 'http://vapi.youlai.tech', // 线上接口地址
                    // target: 'http://localhost:8989',  // 本地接口地址 , 后端工程仓库地址:https://gitee.com/youlaiorg/youlai-boot
                    changeOrigin: true,
                    rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '') // 替换 /dev-api 为 target 接口地址
                }
            }
        },
        plugins: [
            vue(),
            AutoImport({
                // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
                imports: ['vue', '@vueuse/core'],
                eslintrc: {
                    enabled: true,
                    filepath: './.eslintrc-auto-import.json',
                    globalsPropValue: true
                },
                resolvers: [
                    // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
                    ElementPlusResolver(),
                    IconsResolver({})
                ],
                vueTemplate: true,
                // 配置文件生成位置(false:关闭自动生成)
                // dts: false,
                dts: path.resolve(pathSrc, 'types', 'auto-imports.d.ts') // 指定自动导入函数TS类型声明文件路径
            }),
            Components({
                resolvers: [
                    // 自动导入 Element Plus 组件
                    ElementPlusResolver(),
                    // 自动导入图标组件
                    IconsResolver({
                        // @iconify-json/ep 是 Element Plus 的图标库
                        enabledCollections: ['ep']
                    })
                ],
                dirs: ['src/**/components'],
                // 配置文件生成位置(false:关闭自动生成)
                dts:false,
                // dts: path.resolve(pathSrc, 'types', 'components.d.ts') // 指定自动导入组件TS类型声明文件路径
            }),
            Icons({
                // 自动安装图标库
                autoInstall: true
            }),
            createSvgIconsPlugin({
                // 指定需要缓存的图标文件夹
                iconDirs: [path.resolve(pathSrc, 'assets/icons')],
                // 指定symbolId格式
                symbolId: 'icon-[dir]-[name]'
            })
        ]
    }
})

如果你觉得这就结束了,那就大错特错,咱们的标题正题还未开始0.0

我做完这些操作后查看

 妈了跨的,没有messagebox提示弹窗

 瞬间炸了,探索欲望爆棚,一开始我都不知道这回事,后面在ts里面调用messagebox的时候发现还要引入,我寻思不是按需引入么,怎么还要引入,于是发生了刚刚一系列事件

网上找到这么一篇文章

vite + vue + ts 自动按需导入 Element Plus组件,并如何解决按需引入后ElMessage与ElLoading 的问题(找不到名称“ElMessage”问题。)

文章写的很好,也有解决方案,不过我比较轴,我非不这么干,我要和vue3-element-admin大佬靠齐,人家那么写都没事,到我这就不行了?必须搞定他

最终,终于让我找到问题所在,

答案:按需引入的原理是监听vue页面,ts页面先行使用的话不会被监听到,只有vue页面使用了,后面再刷新按需引入,则auto-import才会更新内容

发现原因:在创建项目初期,搭框架的时候,谁去在vue里面写弹窗啊,弹窗一般只有做提示信息的时候才能用到,也就是ts文件,而我一般会先把框架搭完才会写页面,像pinia,router,axios拦截器,svg,多语言之类的先搞完,正好写到拦截器,需要弹窗,于是发现了这个问题,并记录下来。

警醒后面的学习者,踏入此途搜到我,也算有个善终0.0

想看看有多少遇到这个问题的兄弟,遇到了的话,咱们点个收藏,我看看有多少轴子在我这里的到了解脱0.0

最后放张我解决后的截图,让大家放心,我不是在胡扯