vue 2.x + @vue/cli 4.x开发阶段使用Vite

news2024/9/23 23:24:54

项目用的是vue 2.x + @vue/cli 4.x(webpack 4.x)。冷启动项目时耗时较长,达到了2分钟以上。热更新时间也达到了10s以上。严重影响了开发体验和效率。

解决问题的过程中遵循2个原则:

  1. 不对会影响原构建流程的代码进行改动,向原Webpack构建兼容。
  2. 只引入开发阶段的构建服务。

安装vite

vue需要2.7.X
vue-template-compiler需与vue版本一致

相关依赖

package.json对比
在这里插入图片描述
在这里插入图片描述
相关依赖

//package.json
  "scripts":{
    "serve:vite": "IS_IN_VITE=true vite",
  },
  "dependencies": {
    "vue": "2.7.16",
  },
  "devDependencies": {
    "@vitejs/plugin-vue2": "^2.3.1",
    "@vitejs/plugin-vue2-jsx": "^1.1.1",
    "speed-measure-webpack-plugin": "^1.5.0",
    "unplugin-auto-import": "^0.18.0",
    "vite": "^5.3.3",
    "vite-plugin-antdv-fix": "^1.0.3",
    "vite-plugin-commonjs": "^0.10.1",
    "vite-plugin-html": "^3.2.2",
    "vite-plugin-lang-jsx": "^1.5.3",
    "vite-plugin-require-transform": "^1.0.21",
    "vue-template-compiler": "2.7.16",
    "webpack-strip-block": "^0.3.0",
  }

新建vite.config.js

主要处理vue-cli的

//vite.config.js
import path from 'node:path'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue2'
import { createHtmlPlugin } from 'vite-plugin-html'
import vueJsx from '@vitejs/plugin-vue2-jsx'
import langJsx from 'vite-plugin-lang-jsx'
import commonjs from 'vite-plugin-commonjs'
import antdvFix from 'vite-plugin-antdv-fix'

const assetsCDN = {
  // webpack build externals
  externals: {
    vue: 'Vue',
    'vue-router': 'VueRouter',
    vuex: 'Vuex',
    './cptable': 'var cptable',
    axios: 'axios'
  },
  css: [],
  js: [
    '/js/vue.min.js',
    '/js/vue-router.min.js',
    '/js/vuex.min.js',
    '/js/axios.min.js'
  ]
}

// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
  const env = loadEnv(mode, process.cwd())
  const isPro = mode === 'production'

  function getEnv(key) {
    return loadEnv(mode, process.cwd(), '')[key]
}
  return {
    // 部署生产环境和开发环境下的URL。
    // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
    // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
    base: '/',
    define: {
      'process.env': process.env,
      IS_IN_VITE: true,
    },
    plugins: [
      langJsx(),
      vue(),
      vueJsx(),
      antdvFix(),//解决ant-design-vue的date-picker组件在使用时报错
      createHtmlPlugin({
        minify: true,
        /**
         * 在这里写entry后,你将不需要在`index.html`内添加 script 标签,原有标签需要删除
         * @default
         */
        entry: '/src/main.js',
        /**
         * 如果你想将 `index.html`存放在指定文件夹,可以修改它,否则不需要配置
         * @default index.html
         */
        template: 'public/index.html',
        inject: {
          data: {
            htmlWebpackPlugin: {
              options: {}
            }
          }
        },
      }),
      
      commonjs({
        filter(id) {
          // `node_modules` is exclude by default, so we need to include it explicitly
          // https://github.com/vite-plugin/vite-plugin-commonjs/blob/v0.7.0/src/index.ts#L125-L127
          if (
            id.includes('node_modules/@jiaminghi') ||
            id.includes('node_modules/viser') ||
            id.includes('node_modules/@antv')
            // id.includes('node_modules/@babel/runtime')
          ) {
            return true
          }
        },
        dynamic: {
          loose: false,
        }
      }),
    ],
    optimizeDeps: {
      // include: ['viser-vue'],
      // exclude: ['@jiaminghi/c-render'],
    },
    resolve: {
      // https://cn.vitejs.dev/config/#resolve-alias
      alias: [
        // 设置别名
        { find: /^~(?!@)/, replacement: '' }, // 将 ~ 替换为空字符串,以支持直接从 node_modules 导入
        { find: /^~@/, replacement: path.resolve(__dirname, './src') }, // 将 ~@ 替换为项目中的 src 目录
        { find: '@', replacement: path.resolve(__dirname, './src') }, // 将 @ 替换为项目中的 src 目录
      ],
      // https://cn.vitejs.dev/config/#resolve-extensions
      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
    },
    // vite 相关配置 代理
    server: {
      port: 9001,
      host: true,
      open: true,
      proxy: {
        '/api': {
          target:getEnv('VUE_APP_API_BASE_URL'),
          ws: false,
          changeOrigin: true,
          pathRewrite: {
            // 需要rewrite的path
          }
        },
        '/epros': {
          target: 'http://dopeprostest.pipechina.com.cn:30080/api',
          ws: false,
          changeOrigin: true,
          pathRewrite: {
            '^/epros': ''
            // 需要rewrite的path
          }
        }
      }
    },
    // fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
    css: {
      preprocessorOptions: {
        less: {
          modifyVars: {
            'primary-color': '#1890FF',
            'layout-color': '#1890FF',
            'border-radius-base': '2px'
          },
          // DO NOT REMOVE THIS LINE
          javascriptEnabled: true
        }
      },
      postcss: {
        plugins: [
          {
            postcssPlugin: 'internal:charset-removal',
            AtRule: {
              charset: (atRule) => {
                if (atRule.name === 'charset') { atRule.remove() }
              },
            },
          },
        ],
      },
    },
  }
})

vue 动态路由vite处理

let route_modules = null
/* develblock:start */
if (window.IS_IN_VITE) {
  route_modules = import.meta.glob('@/views/**/*.vue')
  let _routeModules = {}
  Object.keys(route_modules).forEach(key => {
    const dir = key.split('views/')[1].split('.vue')[0];
    _routeModules[dir] = route_modules[key]
  })
  route_modules = _routeModules
}
/* develblock:end */
/**
 * 将后台返回的动态路由配置组件字符串,转换为动态导入语句
 * 用于本地开发环境使用Vite打包的动态路由
 */
export const loadView = (view) => {
  let res;
  for (const path in route_modules) {
    // const dir = path.split('views/')[1].split('.vue')[0];
    if (path === view) {
      res = () => route_modules[path]();
    }
  }
  return res;
}
// 格式化菜单数据
export const generator = (routerMap, parent) => {
  return routerMap.map(item => {
    // eslint-disable-next-line no-unused-vars
    const { title, show, hideChildren, hiddenHeaderContent, target, icon, link } = item.meta || {}
    const menuComponent = item.component
    const currentRouter = {
      path: item.path || `${(parent && parent.path) || ''}/${item.key}`,
      // 路由名称,建议唯一
      name: item.name || item.key || '',
      // 该路由对应页面的 组件 :方案2 (动态加载)
      component: constantRouterComponents[item.component || item.key] || (route_modules ? loadView(item.component) : (() => import(`@/views/${item.component}`))),
      // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
      meta: {
        title: title,
        icon: icon || undefined,
        // hiddenHeaderContent: hiddenHeaderContent,
        target: target,
        link: link
      }
    }
    ....

由于在Webpack编译时import.meta.glob语法无效会导致编译出错,所以引入webpack-strip-block,在Webpack编译时删除掉模块中指定注释块中的代码,避免编译错误。

//vue.config.js

  chainWebpack: config => {
    config.module.rule('strip-block')
      .test(/\.js$/)
      .pre()
      .exclude.add(/(node_modules|bower_components|\.spec\.js)/)
      .end()
      .use('webpack-strip-block')
      .loader('webpack-strip-block')
      ....
      }

~@assets处理

 <img src="~@/assets/index/refresh.svg">
 改为
  <img src="@/assets/index/refresh.svg">

诡异报错

报错1

[图片]

解决方法:
[图片]

报错2

在这里插入图片描述
解决方法:

  @import "../index";

运行

vite和vue/cli均支持,页面正常加载
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

加密创投周期进化论:未来或黯淡,但流动性是那道光

加密创投领域的风起云涌&#xff0c;而在2022年后&#xff0c;加密市场逐渐进入“行业阵痛期”&#xff0c;面对熊市的寒冬&#xff0c;整个行业的流动性急剧减少&#xff0c;市场的发展被迫寄希望于“板块轮动”的交替炒作。尽管如此&#xff0c;比特币生态和L2生态的兴起&…

树莓派开发笔记03-树莓派的GPIO口输入检测

github主页&#xff1a;https://github.com/snqx-lqh gitee主页&#xff1a;https://gitee.com/snqx-lqh 本项目github地址&#xff1a;https://github.com/snqx-lqh/RaspberryPiLearningNotes 本项目gitee地址&#xff1a;https://gitee.com/snqx-lqh/RaspberryPiLearningNote…

LLAMA 3.1 论文的见解

这有什么大不了的&#xff1f; LLAMA 3.1 的发布标志着 AI 开发的一个重要里程碑。开源模型首次接近领先的闭源模型的性能水平。这一转变预示着未来开源模型同样有效&#xff0c;任何人都可以灵活地修改和调整它们。马克扎克伯格将此与 Linux 的开源性质进行了比较&#xff0c;…

Mysql原理与调优-如何进行sql优化

1.绪论 本文主要讲解我们如何优化一个sql。优化的过程主要分为3个步骤&#xff0c;找到哪些sql需要被优化&#xff0c;这就需要用到慢sql日志。然后发现慢SQL为什么慢&#xff0c;即当前sql是如何执行的&#xff0c;这就需要用到执行计划。最后才是对sql进行优化&#xff0c;对…

作业帮 TiDB 7.5.x 使用经验

作者&#xff1a; 是我的海 原文来源&#xff1a; https://tidb.net/blog/5f9784d3 近期在使用 TiDB 时遇到的一些小问题的梳理总结&#xff0c;大部分版本都在6.5.6和7.5.2 1、limit 导致的扫描量过大的优化 研发定时任务每天需要扫描大量数据&#xff0c;到时机器网卡被…

26.10 Django Ajax异步提交

1. 表单提交 1.1 表单的作用 表单是Web开发中常见的数据收集方式, 它允许用户通过表单输入数据, 并通过提交操作将这些数据发送到服务器进行处理.表单提交方式主要分为两大类: 传统的同步提交(也称为标准提交)和异步提交(主要通过Ajax实现). 它们在工作方式, 用户体验和数据传…

语音助手Verbi:科技创新的未来

今天&#xff0c;我要向大家介绍一个名为Verbi的语音助手项目。这是一个结合了多种先进技术的模块化语音助手应用程序&#xff0c;能够实现语音到文本、文本生成和文本到语音的全流程处理。通过这个项目&#xff0c;我们可以体验到尖端科技如何改变我们的日常生活。 Verbi的诞…

PHP安全开发

安全开发 PHP 基础 增&#xff1a;insert into 表名(列名 1, 列名 2) value(‘列 1 值 1’, ‘列 2 值 2’); 删&#xff1a;delete from 表名 where 列名 ‘条件’; 改&#xff1a;update 表名 set 列名 数据 where 列名 ‘条件’; 查&#xff1a;select * from 表名 wher…

【STM32 Blue Pill编程】-外部中断配置及使用

外部中断配置及使用 文章目录 外部中断配置及使用1、中断介绍2、STM32中的中断3、硬件准备及接线4、GPIO配置5、代码实现在本文中,我们将介绍如何使用 STM32Cube IDE 中的 HAL 库配置和处理外部中断。 我们将通过一个带有按钮和 LED 的示例来演示这一点。 读完本文后,您将能够…

简单了解JVM执行Java程序的基本流程 | 一次编译,到处运行

前言&#xff1a; Java代码怎么做到一次编译&#xff0c;到处运行的呢&#xff1f;靠JVM&#xff0c;那JVM的执行流程是什么呢&#xff1f; 简单来说&#xff1a;通过Javac编译器将Java源代码编译成字节码&#xff0c;JVM通过类加载器将字节码加载到运行时数据区中&#xff0c;…

C++学习笔记之数据结构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、二叉树1.1 二叉树的遍历1.1.1 深度优先搜索&#xff08;DFS&#xff09;1.1.2 广度优先搜索&#xff08;BFS&#xff09; 1.2 对称性&#xff08;递归法&#x…

【论文笔记】LION: Linear Group RNN for 3D Object Detection in Point Clouds

原文链接&#xff1a;https://arxiv.org/abs/2407.18232 简介&#xff1a;Transformer在3D点云感知任务中有二次复杂度&#xff0c;难以进行长距离关系建模。线性RNN则计算复杂度较低&#xff0c;适合进行长距离关系建模。本文提出基于窗口的网络线性组RNN&#xff08;即对分组…

Android 上下滑隐藏显示状态栏

一、DisplayPolicy类中监听滑动事件&#xff0c;然后发送广播事件 Android12类路径&#xff1a; frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.javamSystemGestures new SystemGesturesPointerEventListener(mUiContext, mHandler,new SystemGest…

《机器学习》周志华-CH1(绪论)

1.1引言 机器学习&#xff08;Matchine-Learning&#xff09;所研究的主要内容是关于在计算机上从数据中产生“模型”&#xff08;model&#xff09;的算法&#xff0c;即“学习算法”&#xff08;learning algorithm&#xff09;。可以说机器学习&#xff08;Matchine-Learni…

2024最新最全面一线大厂面试Tips丨接口测试面试题

面试Tips# 面试是求职过程中至关重要的环节。在如今竞争激烈的就业市场&#xff0c;拥有优秀的面试技巧和良好的面试礼仪显得尤为重要&#xff0c;同样掌握这个的行业面试题也不可或缺。 01 你们公司的接口测试流程 是怎样的&#xff1f; &#xff08;有没有感觉熟悉&#…

[Linux][OS][信号的捕捉] 可重入函数 | volatile | SIGCHLD信号

回顾&#xff1a;[Linux][OS][信号的保存和处理] 信号捕捉 1.sigaction int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); 参数&#xff1a; signo&#xff1a;指定信号的编号act&#xff1a;输入型参数&#xff0c;根据act修改该信号的处…

水果甜度个人手持设备检测-(题外:为啥会选型这个课题)

系列:水果甜度个人手持设备检测 -- 题外&#xff1a;为啥会选型这个课题 写在前面的话 这段时间一直也在思考&#xff0c;在主业之外哪些方向和产业成熟度较高、技术复杂度又不是很离谱&#xff0c;比较容易出成果的方向&#xff0c;能够有空去试着做一做。这几年AI智能化正…

Java方法02:方法的定义和调用

本节内容视频链接&#xff1a;Java方法03&#xff1a;方法的重载_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV12J41137hu?p47&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 在Java中&#xff0c;‌‌方法的定义是创建一段可重复使用的代码块的过程‌。‌它…

Java 开发者 LLM 实战:利用 LangChain4j 打造高效本地 RAG 系统

1、引言 由于目前比较火的chatGPT是预训练模型&#xff0c;而训练一个大模型是需要较长时间&#xff08;参数越多学习时间越长&#xff0c;保守估计一般是几个月&#xff0c;不差钱的可以多用点GPU缩短这个时间&#xff09;&#xff0c;这就导致了它所学习的知识不会是最新的&…

代码随想录DAY17 - 二叉树 - 08/16

最大二叉树 题干 题目&#xff1a;给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组…