京东快递H5项目接入vite实战
字数 1105 2025-08-11 08:36:04

Vite 接入 Vue 2.x 工程实战指南

前言

随着 H5 项目迭代,传统打包工具(如 Webpack)的启动时间和热更新速度逐渐成为开发效率的瓶颈。Vite 作为一种新型的 bundless 打包工具,能够显著提升开发体验。本文将以京东快递 H5 项目为例,详细介绍如何将 Vite 无缝接入现有的 Vue 2.x 工程。

一、准备工作

1.1 必要依赖安装

首先需要安装以下依赖包:

npm install --save-dev vite vite-plugin-vue2 @vitejs/plugin-legacy vite-plugin-html vue-template-compiler @rollup/plugin-babel sass

各依赖包的作用:

  • vite: 核心打包工具
  • vite-plugin-vue2: 官方提供的 Vue 2.x 兼容插件
  • @vitejs/plugin-legacy: 低版本浏览器兼容插件
  • vite-plugin-html: 模板文件代码注入插件(注意使用 2.0.7 版本)
  • vue-template-compiler: Vue 单文件组件编译器(版本需与 Vue 一致)
  • @rollup/plugin-babel: Babel 相关配置
  • sass: CSS 预处理语言基础库

二、项目结构调整

2.1 模板文件处理

  1. 在项目根目录创建 index.html 文件
  2. 模板文件需要主动导入项目入口文件:
<script type="module" src="/src/main.js"></script>

三、常见问题及解决方案

3.1 样式相关兼容

  1. 深度选择器语法

    • /deep/ 替换为 ::v-deep
  2. 路径别名处理

    resolve: {
      alias: {
        '~@': resolve(__dirname, 'src')
      }
    }
    

3.2 全局变量兼容

  1. global 变量缺失
    在模板文件中添加:

    <script>
      global = globalThis
    </script>
    

    或使用 vite-plugin-global-polyfill 插件

  2. process 变量缺失

    // 环境变量读取配置
    const dotenv = require('dotenv')
    const { expand } = require('dotenv-expand')
    const minimist = require('minimist')
    
    function loadEnv(mode) {
      const basePath = resolve(__dirname, `.env${mode ? `.${mode}` : ''}`)
      const localPath = `${basePath}.local`
    
      const load = envPath => {
        const env = dotenv.config({ path: envPath, debug: process.env.DEBUG })
        expand(env)
      }
    
      load(localPath)
      load(basePath)
    }
    
    const parmas = minimist(process.argv.slice(2))
    loadEnv(parmas.mode)
    
    // Vite 配置
    define: {
      'process.env': process.env
    }
    

3.3 动态 require 问题

由于 Rollup 不支持动态 require,解决方案:

<script>
  function require() {
    return {
      default: {
        init: () => {},
        scanCode: () => new Promise((resolve, reject) => {}),
        // 其他方法实现...
      }
    }
  }
</script>

3.4 组件库兼容问题

  1. 组件库导出方式不兼容

    resolve: {
      alias: {
        '@jd/pandora-mobile': resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.js')
      },
      mainFields: ['main', 'module', 'jsnext:main', 'jsnext']
    }
    
  2. 组件库样式问题

    import { createStyleImportPlugin } from 'vite-plugin-style-import'
    
    createStyleImportPlugin({
      libs: [{
        libraryName: "@jd/pandora-mobile",
        esModule: true,
        resolveStyle: (name) => {
          return `@jd/pandora-mobile/es/components/${name}/style/index.css`
        }
      }]
    })
    

3.5 Sass 兼容问题

解决 node-sass 与 dart-sass 冲突:

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        // 优先使用 node-sass
        implementation: require("node-sass"),
      }
    }
  }
}

四、完整 Vite 配置示例

import { defineConfig } from 'vite'
import legacy from '@vitejs/plugin-legacy'
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
import html from 'vite-plugin-html'
import { createVuePlugin } from 'vite-plugin-vue2'
import { createStyleImportPlugin } from 'vite-plugin-style-import'
import { envSwitchPlugin } from 'vite-plugin-env-switch'
import { globalPolyfill } from 'vite-plugin-global-polyfill'
import { resolve } from 'path'

// 环境变量配置...
// ...

export default defineConfig({
  base: '/express-vite/',
  publicDir: 'public',
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
      '~@': resolve(__dirname, 'src'),
    },
    mainFields: ['main', 'module', 'jsnext:main', 'jsnext']
  },
  server: {
    host: 'xxx.jd.com',
    https: true,
    port: 443,
    open: true,
  },
  plugins: [
    envSwitchPlugin({
      wsProtocol: 'vite-hmr',
      envs: ['prepare', 'development', 'production'],
      wsPath: 'wss://xxx.jd.com/express-vite/',
      root: __dirname,
      eventName: 'env-check'
    }),
    globalPolyfill(),
    createStyleImportPlugin({
      libs: [{
        libraryName: "@jd/pandora-mobile",
        esModule: true,
        resolveStyle: (name) => {
          return `@jd/pandora-mobile/es/components/${name}/style/index.css`
        }
      }]
    }),
    createVuePlugin({}),
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),
    getBabelOutputPlugin({
      configFile: resolve(__dirname, 'babel.config.js'),
    }),
    html({
      inject: {
        injectData: {
          title: '京东快递'
        }
      },
      minify: true,
    })
  ],
  css: {
    preprocessorOptions: {
      // 可在此添加全局样式
    }
  },
  build: {
    outDir: 'dist',
    target: 'es2015',
    minify: 'terser',
  },
  define: {
    'process.env': process.env,
  }
})

五、效果对比

  1. 启动时间

    • Vite: 极快(毫秒级)
    • Vue CLI: 约 1 分钟
  2. 开发体验

    • Vite 的热更新速度显著提升
    • 首次页面交互可能略有卡顿(运行时打包特性)

六、总结

通过本文的配置方案,可以实现:

  1. Vite 与现有 Vue CLI 项目的无缝兼容
  2. 环境变量的完整支持
  3. 第三方组件库的兼容处理
  4. 样式预处理器的正确配置
  5. 全局变量的多方案兼容

虽然 Vite 在开发阶段带来了显著的效率提升,但仍需注意:

  1. 生产环境仍需使用原有打包方案(如 Webpack)
  2. 运行时打包特性可能影响首次交互体验
  3. 部分特殊场景(如动态 require)需要额外处理

建议团队在接入前充分测试,确保各项功能正常运作。

Vite 接入 Vue 2.x 工程实战指南 前言 随着 H5 项目迭代,传统打包工具(如 Webpack)的启动时间和热更新速度逐渐成为开发效率的瓶颈。Vite 作为一种新型的 bundless 打包工具,能够显著提升开发体验。本文将以京东快递 H5 项目为例,详细介绍如何将 Vite 无缝接入现有的 Vue 2.x 工程。 一、准备工作 1.1 必要依赖安装 首先需要安装以下依赖包: 各依赖包的作用: vite : 核心打包工具 vite-plugin-vue2 : 官方提供的 Vue 2.x 兼容插件 @vitejs/plugin-legacy : 低版本浏览器兼容插件 vite-plugin-html : 模板文件代码注入插件(注意使用 2.0.7 版本) vue-template-compiler : Vue 单文件组件编译器(版本需与 Vue 一致) @rollup/plugin-babel : Babel 相关配置 sass : CSS 预处理语言基础库 二、项目结构调整 2.1 模板文件处理 在项目根目录创建 index.html 文件 模板文件需要主动导入项目入口文件: 三、常见问题及解决方案 3.1 样式相关兼容 深度选择器语法 : 将 /deep/ 替换为 ::v-deep 路径别名处理 : 3.2 全局变量兼容 global 变量缺失 : 在模板文件中添加: 或使用 vite-plugin-global-polyfill 插件 process 变量缺失 : 3.3 动态 require 问题 由于 Rollup 不支持动态 require,解决方案: 3.4 组件库兼容问题 组件库导出方式不兼容 : 组件库样式问题 : 3.5 Sass 兼容问题 解决 node-sass 与 dart-sass 冲突: 四、完整 Vite 配置示例 五、效果对比 启动时间 : Vite: 极快(毫秒级) Vue CLI: 约 1 分钟 开发体验 : Vite 的热更新速度显著提升 首次页面交互可能略有卡顿(运行时打包特性) 六、总结 通过本文的配置方案,可以实现: Vite 与现有 Vue CLI 项目的无缝兼容 环境变量的完整支持 第三方组件库的兼容处理 样式预处理器的正确配置 全局变量的多方案兼容 虽然 Vite 在开发阶段带来了显著的效率提升,但仍需注意: 生产环境仍需使用原有打包方案(如 Webpack) 运行时打包特性可能影响首次交互体验 部分特殊场景(如动态 require)需要额外处理 建议团队在接入前充分测试,确保各项功能正常运作。