文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue 2 系统如何快速迁移 Vite 作为开发工具

2024-12-03 02:13

关注

当前版本 vite@2.3.7

一. 适合什么项目迁移

  1. 使用 vue2 的系统
  2. 内部系统 - 无需大型流量场景:因为 vite 更迭较快,导致系统需要定期改动基础功能,造成不稳定
  3. 非 SSR 系统 - SSR 还有很多问题,暂且等社区丰富起来
  4. 定期有人维护的系统
  5. 对开发有痛点而想要改进:比如打包慢,冷启动慢,HMR 更新慢。。。。
  6. vite 生产环境用 rollup,但是改造成本大,提效不高,风险大,暂不建议使用。【本人愚见,大佬轻喷】

二.迁移步骤

将会以内部系统作为案例改造, 开发用 vite,生产依旧保持 webpack。

  1. 简单了解 vite 特性。有问题优先看vite 官网排查是否有更新或解决方案!!
  2. npm i vite@2.3.7 vite-plugin-vue2@1.6.2 vite-plugin-html@2.0.7 -D
  3. package.json 添加一个 script -- "vite": "NODE_ENV=development vite"
  4. 关键在于配置 vite.config.js【默认叫做这个文件名,你可配置成其他的。。】
  1. import { defineConfig } from 'vite'
  2. import path from 'path'
  3. import fs from 'fs'
  4.  
  5. import { createVuePlugin } from 'vite-plugin-vue2'
  6. import { injectHtml, minifyHtml } from 'vite-plugin-html'
  7. import { cjs2esmVitePlugin } from 'cjs2esmodule' 
  8. import dotenv from 'dotenv' 
  9. const config = require('./config'
  10.  
  11. try { 
  12.   // 根据环境变量加载环境变量文件 
  13.   const file = dotenv.parse(fs.readFileSync(`./config/.env.${process.env.NODE_ENV}`), { 
  14.     debug: true 
  15.   }) 
  16.   console.log(file) 
  17.   // 根据获取的 key 给对应的环境变量赋值 
  18.   for (const key in file) { 
  19.     process.env[key] = file[key
  20.   } 
  21. } catch (e) { 
  22.   console.error(e) 
  23. const API_LOCATION = process.env.API_LOCATION || '/api' 
  24.  
  25. function resolve(dir) { 
  26.   return path.join(__dirname, './', dir) 
  27. export default defineConfig({ 
  28.   root: './', // 项目根目录(index.html 文件所在的位置)可以是一个绝对路径,或者一个相对于该配置文件本身的相对路径。 
  29.   publicDir: 'public', // 作为静态资源服务的文件夹.该值可以是文件系统的绝对路径,也可以是相对于项目的根目录的相对路径。 
  30.   base: './', // 公共基础路径。改值可以是绝对路径或空字符串 
  31.   mode: 'development'
  32.   optimizeDeps: { // 要预构建的第三方依赖 
  33.     include: [] 
  34.   }, 
  35.   resolve: { 
  36.     alias: { 
  37.       // 'vue''vue/dist/vue.esm.js', // 如果是模板解析的 - 使用这个 vue:内部为正则表达式  vue 结尾的 
  38.       'vendor': resolve('src/vendor'), 
  39.       '@': resolve('src'), 
  40.       '~@': resolve('src'), 
  41.       '~component': resolve('src/components'), 
  42.       '~config': resolve('config'), 
  43.     } 
  44.   }, 
  45.   plugins: [ 
  46.     cjs2esmVitePlugin(), // 将 commonjs 转化为 es module: 有报错 
  47.     createVuePlugin({ 
  48.       jsx: true
  49.       jsxOptions: { 
  50.         injectH: false
  51.       }, 
  52.     }), 
  53.     minifyHtml(), // 压缩 HTML 
  54.     injectHtml({ // 入口文件 index.html 的模板注入 
  55.       injectData: { // 模板注入的数据 
  56.         htmlWebpackPlugin: { 
  57.           options: { 
  58.             isVite: true
  59.             shotcut: '/static/img/favicon.png'
  60.           } 
  61.         }, 
  62.         title: 'HMO 运营后台'
  63.       }, 
  64.     }), 
  65.   ], 
  66.   define: { 
  67.     'process.env': process.env 
  68.   }, 
  69.   server: { 
  70.     host: 'liang.myweb.com'
  71.     opentrue, // 是否自动打开浏览器 
  72.     port: process.env.PORT || config.dev.port, 
  73.     proxy: { 
  74.       [API_LOCATION]: { 
  75.         target: 'http://127.0.0.1:8001'
  76.         rewrite: (path) => path.replace(API_LOCATION, ''
  77.       } 
  78.        
  79.     } 
  80.   }, 
  81. }); 

三.常用问题【踩坑日记😄】

vite 目前要求入口文件必须是根目录下的 index.html,如果之前的 webpack 入口文件同名,需要更改。解决方案:vite.config.js:

  1. import { injectHtml } from 'vite-plugin-html'
  2. export default defineConfig({ 
  3.   plugins:[ 
  4.     injectHtml({ // 入口文件 index.html 的模板注入 
  5.       injectData: { // 模板注入的数据 
  6.         htmlWebpackPlugin: { // 取和 webpack 插件同名的对象 key,即可 
  7.           options: { 
  8.             isVite: true
  9.             shotcut: '/static/img/favicon.png'
  10.           } 
  11.         }, 
  12.         title: 'HMO 运营后台' 
  13.       }, 
  14.     }) 
  15.   ] 
  16. }) 

webpack.xxx.js

  1. new HtmlWebpackPlugin({ 
  2.   template: 'index.html'
  3.   inject: true
  4.   isVite: false // 添加标识 
  5. }) 

根目录入口文件 index.html - ejs 模板

  1. <% if (htmlWebpackPlugin.options.isVite) { %> 
  2.   "module" src="/src/main.js"
  3.   <%}%> 

新版本报 xx 错:可切换旧版本,如 vite@2.2.3

没有导出命名?

  1. Uncaught SyntaxError: The requested module '/config/index.js' does not provide an export named 'default'Uncaught SyntaxError: The requested module '/config/index.js' does not provide an export named 'default' 

错误原因:浏览器仅支持 esm,不支持 cjs vite.config.js

  1. import { cjs2esmVitePlugin } from 'cjs2esmodule' 
  2. export default defineConfig({ 
  3.   plugins: [ 
  4.    cjs2esmVitePlugin(), // 将 commonjs 转化为 es module 
  5.   ] 
  6. }) 

如果有 require.xx 的按需加载写法还可以修改成 import 的,案例如下:

  1. const subjectList = r => require.ensure( [], () => r(require('@/pages/xxx/subject/list.vue')), 'subject' ); 
  2.  
  3. // 改为:Vue 动态组件 component: ()=>import() 
  4.  
  5. const subjectList = () => import( '@/pages/xxx/subject/list.vue'
  6. const arr = [ 
  7.   { 
  8.     path: '/subject/list'
  9.     name'subject/list'
  10.     component: subjectList 
  11.     meta: {...} 
  12.   } 
  13. ]; 
  14. export default arr; 

proxy 使用 http-proxy。完整选项详见 此处.案例:

  1. proxy: { 
  2.       '/rest': { 
  3.         target: 'http://my.web.com/'
  4.         changeOrigin: true
  5.         bypass: (req, res, proxyOption) => { 
  6.           console.log(`当前请求代理:${req.url} -> ${proxyOption.target}`); 
  7.         }, 
  8.       }, 
  9.     } 

ts 文件报错?验证是否配置了 vite 的 ts 处理

  1. "compilerOptions": { 
  2.   "types": ["vite/client"

全局环境变量报错?

  1. // const isProd = ENV === 'production'; // webpack - dev 环境变量 
  2. // const isProd = import.meta.env.PROD; // vite - dev 环境变量 
  3. // 可以避开上面👆🏻的,采用 NODE_ENV 来区分: 
  4. const isProd = process.env.NODE_ENV === 'production'
  5.  
  6. 那么我们启动的时候:"dev""NODE_ENV=development vite" 

或者可以探索一下社区的 babel 插件:babel-preset-vite【包含以下两个功能】babel-plugin-transform-vite-meta-envbabel-plugin-transform-vite-meta-glob

看一些打印出来的日志&错误等?

cli --debug,或者 vite.config.js 配置打印相关参数

引入文件,比如.vue 的时候,不可以省略扩展名?

是的!!!不是他们不会做,是他们不想做😭,就是这么设计的,具体请戳这里, 尤大佬推特解释然后加上 resolve.extensions: ['.vue'] 直接在控制台报错:所以没用。。。

  1. error: No loader is configured for ".vue" 

害!老老实实加上扩展名!【在线🐶】 方便的全局加上扩展名方法如下:链接


less 文件找不到?

  1. [vite] Internal server error: '~@/styles/var.less' wasn't found. 

(1)确定已经支持 less:npm install -D less(2)别忘了 resolve.alias 也加上一个:'~@': resolve('src')

如何支持 jsx?

vite.config.js

  1. import { createVuePlugin } from 'vite-plugin-vue2'
  2. createVuePlugin({ 
  3.   jsx: true, // 配置 jsx 
  4.   jsxOptions: { 
  5.     injectH: false
  6.   }, 
  7. }) 
  1. Vue.component('my-component',{ 
  2.  render () { 
  3.    return (
    my template
  4.   } 
  5. }) 

根据环境变量配置代理?

(1)cross-env 来跨平台设置环境变量

安装 cross-envnpm i cross-env -D

(2)加载环境变量文件。它能将环境变量中的变量从 .env 文件加载到 process.env 中

安装 dotenvnpm i dotenv -D

(3)config/.env.development 配置变量

  1. NODE_ENV = development 
  2. API_LOCATION = /api 
  3. LOGOUT_PC_LOCATION = http://user.myweb.com/login 
  4. CRM_ADDRESS = http://crm.myweb.com 

(4)配置 vite.config.ts

  1. try { 
  2.   // 根据环境变量加载环境变量文件 
  3.   const file = dotenv.parse(fs.readFileSync(`./config/.env.${process.env.NODE_ENV}`), { 
  4.     debug: true 
  5.   }) 
  6.   console.log(file) 
  7.   // 根据获取的 key 给对应的环境变量赋值 
  8.   for (const key in file) { 
  9.     process.env[key] = file[key
  10.   } 
  11. } catch (e) { 
  12.   console.error(e) 
  13. const API_LOCATION = process.env.API_LOCATION || '/api' 
  14. ..... 此处省略 
  15.  
  16. export default defineConfig({ 
  17.   server: { 
  18.     proxy: { 
  19.       [API_LOCATION]: { 
  20.         target: 'http://127.0.0.1:8001'
  21.         rewrite: (path) => path.replace(API_LOCATION, '') // 根据环境变量配置代理 
  22.       } 
  23.  
  24.     } 
  25.   } 
  26. }) 

(5)package.json 启动 script

  1. "vite""cross-env NODE_ENV=development vite" 

环境变量报错?

原来 webpack 使用的环境变量 process.env,vite 没有这个,所以报错

  1. Uncaught ReferenceError: process is not defined 

vite 使用的时候import.meta.env, 但是我们老的代码不想动怎么办?其实 vite 也还是留了口子给我们定义全局变量[类型不能是 function]

  1. export default defineConfig({ 
  2.   // ... 
  3.   define: { 
  4.     'process.env': {} 
  5.   } 
  6. }) 

anything else?

..... bug 无止境,很多都是非通用问题,都是引入 vite 后发现的系统本身的一些问题,这里就不一一举例了。后续会追踪更多通用问题

 

来源:微医大前端技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯