vue3+vite配置 unplugin-vue-component 找不到 Vant 组件的问题

使用 vue3 + vite + Vant 搭建移动端项目,为了避免全量引入 vant 导致打包体积过大,又不想一个一个组件手动导入,所以就选择了 vant 官方推荐的方法,使用 unplugin-vue-components 插件自动引入组件,并按需引入组件的样式。
但是运行过程中遇到了报错:[vite] Internal server error: Failed to resolve import "vant/es" from "xxx"

vue3 + vite

项目依赖

  • package.json
{
  "name": "vue3-demo",
  "private": true,
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite --host",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "git": "tive git -c tive.git.config.cjs",
    "lint": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./src",
    "lint:stylelint": "stylelint --cache --fix \"src/**/*.{less,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
    "prepare": "husky install"
  },
  "dependencies": {
    "amfe-flexible": "^2.2.1",
    "axios": "^1.4.0",
    "lib-flexible": "^0.3.2",
    "pinia": "^2.0.35",
    "vant": "^4.3.1",
    "vue": "^3.2.47",
    "vue-router": "4.0.1"
  },
  "devDependencies": {
    "@types/node": "^20.1.0",
    "@typescript-eslint/eslint-plugin": "^5.59.2",
    "@typescript-eslint/parser": "^5.59.2",
    "@vitejs/plugin-vue": "^4.1.0",
    "typescript": "^5.0.2",
    "unplugin-vue-components": "^0.24.1",
    "vite": "^4.3.2",
    "vite-plugin-compression": "^0.5.1",
    "vite-plugin-eslint": "^1.8.1",
    "vite-plugin-style-import": "^2.0.0",
    "vue-eslint-parser": "^9.2.1",
    "vue-tsc": "^1.4.2"
  },
  "lint-staged": {
    "*.{js,jsx,tsx,ts}": [
      "npm run lint",
      "npm run lint:stylelint"
    ]
  }
}

完整报错

  Plugin: vite-plugin-eslint
  File: /Users/tiven/Desktop/dev/yc-chat-mbi/src/components/Footer.vue
2:47:05 PM [vite] Internal server error: Failed to resolve import "vant/es" from "src/components/Footer.vue". Does the file exist?
  Plugin: vite:import-analysis
  File: /Users/tiven/Desktop/dev/yc-chat-mbi/src/components/Footer.vue:1:89
  1  |  /* unplugin-vue-components disabled */import { Field as __unplugin_components_1 } from 'vant/es';import 'vant/es/field/style/index';
     |                                                                                          ^
  2  |  import { Button as __unplugin_components_0 } from 'vant/es';import 'vant/es/button/style/index';
  3  |  import { defineComponent as _defineComponent } from "vue";
  • vite.config.ts 配置如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'
import path from 'node:path'
import viteCompression from 'vite-plugin-compression'
import postCssPxToRem from 'postcss-pxtorem'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    // 在导入模块时,如果模块路径不包含文件扩展名,则会尝试添加下面这些扩展名
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    // 在导入模块时,如果模块路径以 / 开头,则会尝试在下面这些目录中查找该模块
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@img': path.resolve(__dirname, './src/assets/img'),
    },
  },
  build: {
    sourcemap: false,
    minify: 'terser',
    assetsInlineLimit: 4096,
    reportCompressedSize: false,
    rollupOptions: {
      output: {
        // 最小化拆分包
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString()
          }
        },
        chunkFileNames: 'assets/js/[name].[hash].js', // 用于命名代码拆分时创建的共享块的输出命名,[name]表示文件名,[hash]表示该文件内容hash值
      },
      // external: ['antd'],
    },
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
    },
  },
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],
    }),
    eslintPlugin({
      include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
    }),
    viteCompression({
      threshold: 1024 * 4,
    }),
  ],
  css: {
    postcss: {
      plugins: [
        postCssPxToRem({
          rootValue: 37.5, //1rem的大小
          propList: ['*'], //需要转换的属性
          selectorBlackList: ['.norem'], //过滤掉不需要转换的类名
        }),
      ],
    },
  },
})

解决办法

修改 vite.config.ts 下的 resolve.extensions 参数配置,加入 .mjs 拓展名即可解决。

export default defineConfig({
  resolve: {
    // 在导入模块时,如果模块路径不包含文件扩展名,则会尝试添加下面这些扩展名
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    // 在导入模块时,如果模块路径以 / 开头,则会尝试在下面这些目录中查找该模块
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@img': path.resolve(__dirname, './src/assets/img'),
    },
  },
})

欢迎访问:天问博客

<think>好的,用户想要寻关于在移动端使用Vue3Vite和Element-Plus的集成方案或示例,特别是教程、示例、项目结构和配置方面的内容。我需要根据提供的引用信息来组织答案。 首先,引用[1]和[2]提到使用Vite搭建Vue3项目并集成Element-Plus,引用[3]介绍了一个后台集成方案。但用户需要的是移动端的方案,可能需要调整Element-Plus的配置以适应移动端,比如按需导入和自动导入,以减少体积。同时,可能还需要引入移动端适配的组件库,比如结合Vant或Element-Plus的移动版。 接下来,项目结构方面,Vite默认生成的结构已经适合,但可能需要添加移动端相关的目录,如views、components等。配置方面,需要设置视口、rem适配,可能使用postcss-pxtorem插件,并配置Vite的别名和环境变量。 另外,Element-Plus默认是针对桌面端的,移动端可能需要额外的样式调整,比如使用媒体查询或修改主题变量。或者,用户可能更倾向于使用专为移动端设计的库,比如Vant,但用户明确提到Element-Plus,所以需要说明如何适配。 还要考虑移动端的路由和状态管理,引用[2]和[3]提到了vue-router和vuex,可以沿用这些配置。同时,axios的封装和代理配置对于移动端开发也是必要的,引用[2]有相关部分。 最后,需要提醒用户Element-Plus的移动端适配限制,并建议可能的替代方案,同时提供示例代码和参考资料,确保回答结构清晰,步骤明确。</think>### Vue3 Vite Element-Plus 移动端集成方案 #### 一、项目创建与基础配置 1. **使用 Vite 创建 Vue3 项目** ```bash npm create vite@latest vue3-mobile-demo -- --template vue-ts ``` 项目结构默认包含: ``` ├─src/ │ ├─assets/ │ ├─components/ │ ├─App.vue │ └─main.ts ├─vite.config.ts └─tsconfig.json ``` 2. **集成 Element-Plus** 通过按需自动导入优化移动端体积(引用[2]): ```bash npm install element-plus @element-plus/icons-vue npm install -D unplugin-vue-components unplugin-auto-import ``` 修改 `vite.config.ts`: ```typescript import AutoImport from &#39;unplugin-auto-import/vite&#39; import Components from &#39;unplugin-vue-components/vite&#39; import { ElementPlusResolver } from &#39;unplugin-vue-components/resolvers&#39; export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver({ importStyle: &#39;compressed&#39; })], // 压缩样式 }), ] }) ``` #### 二、移动端适配配置 1. **视口与 REM 适配** 安装 `postcss-pxtorem` 和 `amfe-flexible`: ```bash npm install postcss-pxtorem amfe-flexible -D ``` 在 `main.ts` 引入: ```typescript import &#39;amfe-flexible&#39; ``` 创建 `postcss.config.js`: ```javascript export default { plugins: { &#39;postcss-pxtorem&#39;: { rootValue: 37.5, // 1rem=37.5px(基于750px设计稿) propList: [&#39;*&#39;] } } } ``` 2. **移动端组件扩展** 推荐结合 `@element-plus/icons-vue` 优化图标加载: ```typescript // icons.ts import * as ElementPlusIconsVue from &#39;@element-plus/icons-vue&#39; export function registerIcons(app) { for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } } ``` #### 三、典型移动端项目结构 ``` src/ ├─adapters/ # 设备适配层 ├─services/ # API接口 ├─stores/ # Pinia状态管理 ├─views/ # 页面组件 ├─utils/ # 工具函数 └─app.less # 全局样式 ``` #### 四、移动端特殊配置 1. **触控优化** 在 `vite.config.ts` 添加触屏事件 polyfill: ```typescript import legacy from &#39;@vitejs/plugin-legacy&#39; export default defineConfig({ plugins: [ legacy({ targets: [&#39;defaults&#39;, &#39;not IE 11&#39;] }) ] }) ``` 2. **环境变量配置** 创建 `.env.mobile` 文件: ```env VITE_API_BASE = &#39;/mobile-api&#39; VITE_DEBUG = false ``` #### 五、示例组件 ```vue <!-- MobileButton.vue --> <template> <el-button size="small" @touchstart="handlePress"> <template #icon><Search /></template> 搜索 </el-button> </template> <script setup> import { Search } from &#39;@element-plus/icons-vue&#39; const handlePress = () => { // 触控反馈逻辑 } </script> ``` **注意事项**: 1. Element-Plus 的桌面组件需通过 CSS 媒体查询适配移动端: ```less @media (max-width: 768px) { .el-dialog { width: 90%!important; } } ``` 2. 对于复杂移动场景,建议结合 `vant` 等移动优先组件库(需额外集成)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值