如何将Webpack项目中的Vite加速兼容模式改写为长尾关键词?

2026-03-31 17:261阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2230个文字,预计阅读时间需要9分钟。

如何将Webpack项目中的Vite加速兼容模式改写为长尾关键词?

目录 + 前言 + 目的 + 需要处理的难题 + 动手 + 共用 + index. + 共用配置 + 兼容环境变量 + 自动导入 + 资源引入 + svg-sprite-loader + 替代方案 + 其他 + 效果 + 前言 + 随着公司前端工程的不断扩大,启动是无限的等待,优化是永恒的追求。

目录
  • 前言
  • 目的
  • 要处理的问题
  • 动手
    • 共用 index.html
    • 共用配置
    • 兼容环境变量
    • 自动导入
    • 资源引入
    • svg-sprite-loader 替代方案
  • 其他
    • 效果

      前言

      随着公司前端工程越来越大,启动是无尽的等待,修改是焦急的等待。

      vite 到现在生态也起来了,就有了把项目改造成 vite 的想法,但是项目后面可能要依赖 qiankun 改造成微前端项目,现在 qiankun 对 vite 还没有好的解决方法,我就想采取一个折中的办法,保留 webpack,再兼容 vite,两条路都留着。

      目的

      • 可以用 vite 跑开发环境。
      • 可以用 webpack 跑开发环境。
      • 暂时用 webpack 打包,等后面有解决方案再全面转 vite。

      要处理的问题

      要走的是兼容模式,原来项目的代码能不动的尽量不动。

      • 共用 index.html(使用一个 index.html)。
      • 共用配置(让 webpack 和 vite 共用一些配置,减少每次配置都要两边看的情况)。
      • 兼容环境变量(环境变量 vite 是 import.meta.env,webpack 是 process.env,不修改原来的 process.env 写法还兼容 vite)。
      • 自动导入(自动导入在 webpack 里面用 require.context,vite 里面无法使用)。
      • 资源引入(原来使用 require 方式引入图片资源的需要改动,"~xxx/dist/xxx.css" 以 ~ 开头引入资源的方式兼容处理)。
      • svg-sprite-loader 替代方案。

      动手

      共用 index.html

      vite 中 index.html 是在根目录放的,webpack 在 public 下面放的,我们把 index.html 放到外面。

      下面是咱们 webpack 的开发模式和生产模式。

      "dev": "vue-cli-service serve", "build": "vue-cli-service build",

      我们可以利用 npm hook 做一点事情,这样每次在 dev,build 这两个命令运行之前我们都可以先执行自己的脚本。

      "predev": "node ./command/html.js", "prebuild": "node ./command/html.js", "dev": "vue-cli-service serve", "build": "vue-cli-service build",

      // ./command/html.js const path = require('path') const fs = require('fs') // 把 index.html 拷贝到 public 下 fs.copyFileSync(path.resolve('./index.html'), path.resolve('./public/index.html'))

      vite 中的 index.html 需要一个这样的标签来指定入口文件,但是我们在 webpack 中不需要,我们可以借助插件来处理。

      <script type="module" src="...">

      // vite.config.js import { defineConfig, loadEnv } from 'vite' import { createHtmlPlugin } from 'vite-plugin-html' export default defineConfig(({ mode }) => { // 加载环境变量,因为 vite 中不会加载以 VUE 开头的,我们得自己指定下 const envPrefix = ['VUE'] const env = loadEnv(mode, process.cwd(), envPrefix) return { plugins: [ createHtmlPlugin({ minify: true, template: './index.html', entry: '/src/main.js', // 这个会帮我们注入入口 js 文件 inject: { data: { // 这是我们 index.html 用到的环境变量 ...env } } }) ] } })

      共用配置

      例如我 webpack 中 devServer 和 vite 中的 server 配置就可以公用,但是 vite 使用的是 es module 引入,webpack 用的是 commonjs 规范,我们也可以用命令来处理。

      // config/index.js // server 配置文件 export default { host: '0.0.0.0', port: 12003, https: false, hotOnly: true, disableHostCheck: true, proxy: { '/v1': { target: 'xxx', changeOrigin: true } } }

      // vite.config.js import server from './config/index.js' import { defineConfig } from 'vite' export default defineConfig(({ mode }) => { return { server, } })

      // vue.config.js const path = require('path') const resolve = dir => path.join(__dirname, dir) // babel 编译过的 js包了一层 const devServer = require(resolve('config_cm')).default module.exports = { devServer }

      可以看到 vite 和 webpack 使用的 server 配置引入方式不一样,因为模块化规则不一样,我们下面利用下 npm hook,每次打包前也会把我们 config 文件夹转为 commonjs 规范,输出到 config_cm 下。

      "transformJs": "babel --plugins @babel/plugin-transform-modules-commonjs --presets=@vue/cli-plugin-babel/preset ./config -d ./config_cm",
      "predev": "node ./command/html.js && npm run transformJs",
      "prebuild": "node ./command/html.js && npm run transformJs",

      兼容环境变量

      我们项目中有很多 procsss.env.xxx 这种写法,我们要想这种写法在 vite 里面也生效,就得利用 vite 里面 define 这个配置,如下:

      // vite.config.js import server from './config/index.js' import { defineConfig, loadEnv } from 'vite' export default defineConfig(({ mode }) => { const envPrefix = ['VUE'] const env = loadEnv(mode, process.cwd(), envPrefix) const define = { 'process.env.NODE_ENV': '"development"', 'process.env.BASE_URL': '"/"', 'process.env.VITE': true } for (const [key, value] of Object.entries(env)) { define[`process.env.${key}`] = `"${value}"` } return { define, } })

      自动导入

      // vue.config.js // 需要安装 webpack-strip-block,作用是为了删除某段代码 module.exports = { configureWebpack() { return { module: { rules: [ { test: /\.(js|scss)$/, enforce: 'pre', exclude: /node_modules/, use: [ { loader: 'webpack-strip-block' } ] } ] } } } }

      // VITE 变量是在 vite.config.js 配置的,webpack 中是不存在的 // develblock 开头的注释是因为 webpack 中不存在 import.meta.globEager,编译会失败,所以我们 // 需要对这种做特殊处理 if (process.env.VITE) { /* develblock:start */ componentsContext = import.meta.globEager('./**/index.vue') /* develblock:end */ } else { componentsContext = require.context('./', true, /index\.vue$/) } // autoImport 是我们自己写的共用方法,主要根据 process.env.VITE 判断就可以实现两种环境中的导入方式 const components = autoImport(componentsContext, 'component') for (const c of components) { Vue.component(c.name, c) }

      资源引入

      require('./xx.png') // 这样 vite 和 webpack 中都可以使用 import xx from './xx.png'

      在 webpack 打包中,我们样式中可能会出现下面这种引入方式,引入某个包下面的文件,或者引入 @(src 的别名)下的资源文件。

      @import "~@[包名称]/dist/xx.css"; .xx { background-image: url("~@/views/integration/assets/images/btn_icon/stop_hover.png"); }

      修改一下

      // 下面得写两行引入,因为为了兼容 webpack 和 vite。 /* develblock:start */ @import "@[包名称]/dist/xx.css"; /* develblock:end */ @import "~@[包名称]/dist/xx.css"; // 这个不用动 .xx { background-image: url("~@/views/integration/assets/images/btn_icon/stop_hover.png"); }

      我们这个时候得去 vite 配置下别名,可以根据自己需求灵活配置。

      // vite.config.js import { defineConfig } from 'vite' export default defineConfig(({ mode }) => { resolve: { alias: [ // 针对以 ~@/[包名称]开头的,替换为 node_modules/@[包名称] { find: /^(~@)(?!\/)(.+)/, replacement: path.join('node_modules/@$2') }, // 针对以 ~@/ 开头,替换为 src/ { find: /^~@\//, replacement: path.join(__dirname, 'src/') }, // 针对以 @/ 开头的,替换为 src/ { find: /^@\//, replacement: path.join(__dirname, './src', '/') } ] }, })

      svg-sprite-loader 替代方案

      在 webpack 中使用了 svg-sprite-loader,vite 中需要使用 vite-plugin-svg-icons

      // 原来 webpack 下引入 svg 文件的 js // 假设 svg 文件夹下存放了我所有的 svg 文件,这样两种环境下都可以使用 if (!process.env.VITE) { const context = require.context('./svg', false, /\.svg$/) context.keys().forEach(context) }

      // vite.config.js import { defineConfig } from 'vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' export default defineConfig(({ mode }) => { createSvgIconsPlugin({ // 存放 svg 文件的文件夹 iconDirs: [path.resolve(process.cwd(), 'src/common/icons/svg')], // 和 webpack 保持一致就行 symbolId: 'icon-[name]' }), })

      其他

      • 我项目中使用的是 Vue2,所以用的是 vite-plugin-vue2 这个插件,Vue3 也同理。
      • 我之前调试的时候,根目录和 public 下同时存在 index.html 的时候出现过一些缓存问题,所以利用 npm hook 在用 vite 启动的时候把 public 下的 index.html 删掉了,原理和上面使用的方法一样。
      • 我项目中使用的是 antd 1.x 的包,会因为 moment 导致错误,有一个 vite-plugin-antdv1-momentjs-resolver 可以解决,不用重复造轮子。
      • 不升级为 Vue3 是觉得没必要,项目中也使用了 @vue/composition-api 这个包,可以使用 Vue3 的 composition-api 写法。

      效果

      左边是 vite,右边是 webpack,vite 命令启动前我做了一些操作,所以 vite 启动几乎是秒开,而 webpack,是分钟级别的。这还是在我的电脑上,公司机子更慢了去了。

      在热更新方面,webpack 大概几秒钟,vite 几乎无感知。

      vite 第一次启动因为没有缓存,进页面稍微慢点,后面就感觉不到了。

      以上就是webpack项目中使用vite加速的兼容模式详解的详细内容,更多关于webpack vite加速兼容模式的资料请关注易盾网络其它相关文章!

      如何将Webpack项目中的Vite加速兼容模式改写为长尾关键词?

      标签:兼容

      本文共计2230个文字,预计阅读时间需要9分钟。

      如何将Webpack项目中的Vite加速兼容模式改写为长尾关键词?

      目录 + 前言 + 目的 + 需要处理的难题 + 动手 + 共用 + index. + 共用配置 + 兼容环境变量 + 自动导入 + 资源引入 + svg-sprite-loader + 替代方案 + 其他 + 效果 + 前言 + 随着公司前端工程的不断扩大,启动是无限的等待,优化是永恒的追求。

      目录
      • 前言
      • 目的
      • 要处理的问题
      • 动手
        • 共用 index.html
        • 共用配置
        • 兼容环境变量
        • 自动导入
        • 资源引入
        • svg-sprite-loader 替代方案
      • 其他
        • 效果

          前言

          随着公司前端工程越来越大,启动是无尽的等待,修改是焦急的等待。

          vite 到现在生态也起来了,就有了把项目改造成 vite 的想法,但是项目后面可能要依赖 qiankun 改造成微前端项目,现在 qiankun 对 vite 还没有好的解决方法,我就想采取一个折中的办法,保留 webpack,再兼容 vite,两条路都留着。

          目的

          • 可以用 vite 跑开发环境。
          • 可以用 webpack 跑开发环境。
          • 暂时用 webpack 打包,等后面有解决方案再全面转 vite。

          要处理的问题

          要走的是兼容模式,原来项目的代码能不动的尽量不动。

          • 共用 index.html(使用一个 index.html)。
          • 共用配置(让 webpack 和 vite 共用一些配置,减少每次配置都要两边看的情况)。
          • 兼容环境变量(环境变量 vite 是 import.meta.env,webpack 是 process.env,不修改原来的 process.env 写法还兼容 vite)。
          • 自动导入(自动导入在 webpack 里面用 require.context,vite 里面无法使用)。
          • 资源引入(原来使用 require 方式引入图片资源的需要改动,"~xxx/dist/xxx.css" 以 ~ 开头引入资源的方式兼容处理)。
          • svg-sprite-loader 替代方案。

          动手

          共用 index.html

          vite 中 index.html 是在根目录放的,webpack 在 public 下面放的,我们把 index.html 放到外面。

          下面是咱们 webpack 的开发模式和生产模式。

          "dev": "vue-cli-service serve", "build": "vue-cli-service build",

          我们可以利用 npm hook 做一点事情,这样每次在 dev,build 这两个命令运行之前我们都可以先执行自己的脚本。

          "predev": "node ./command/html.js", "prebuild": "node ./command/html.js", "dev": "vue-cli-service serve", "build": "vue-cli-service build",

          // ./command/html.js const path = require('path') const fs = require('fs') // 把 index.html 拷贝到 public 下 fs.copyFileSync(path.resolve('./index.html'), path.resolve('./public/index.html'))

          vite 中的 index.html 需要一个这样的标签来指定入口文件,但是我们在 webpack 中不需要,我们可以借助插件来处理。

          <script type="module" src="...">

          // vite.config.js import { defineConfig, loadEnv } from 'vite' import { createHtmlPlugin } from 'vite-plugin-html' export default defineConfig(({ mode }) => { // 加载环境变量,因为 vite 中不会加载以 VUE 开头的,我们得自己指定下 const envPrefix = ['VUE'] const env = loadEnv(mode, process.cwd(), envPrefix) return { plugins: [ createHtmlPlugin({ minify: true, template: './index.html', entry: '/src/main.js', // 这个会帮我们注入入口 js 文件 inject: { data: { // 这是我们 index.html 用到的环境变量 ...env } } }) ] } })

          共用配置

          例如我 webpack 中 devServer 和 vite 中的 server 配置就可以公用,但是 vite 使用的是 es module 引入,webpack 用的是 commonjs 规范,我们也可以用命令来处理。

          // config/index.js // server 配置文件 export default { host: '0.0.0.0', port: 12003, https: false, hotOnly: true, disableHostCheck: true, proxy: { '/v1': { target: 'xxx', changeOrigin: true } } }

          // vite.config.js import server from './config/index.js' import { defineConfig } from 'vite' export default defineConfig(({ mode }) => { return { server, } })

          // vue.config.js const path = require('path') const resolve = dir => path.join(__dirname, dir) // babel 编译过的 js包了一层 const devServer = require(resolve('config_cm')).default module.exports = { devServer }

          可以看到 vite 和 webpack 使用的 server 配置引入方式不一样,因为模块化规则不一样,我们下面利用下 npm hook,每次打包前也会把我们 config 文件夹转为 commonjs 规范,输出到 config_cm 下。

          "transformJs": "babel --plugins @babel/plugin-transform-modules-commonjs --presets=@vue/cli-plugin-babel/preset ./config -d ./config_cm",
          "predev": "node ./command/html.js && npm run transformJs",
          "prebuild": "node ./command/html.js && npm run transformJs",

          兼容环境变量

          我们项目中有很多 procsss.env.xxx 这种写法,我们要想这种写法在 vite 里面也生效,就得利用 vite 里面 define 这个配置,如下:

          // vite.config.js import server from './config/index.js' import { defineConfig, loadEnv } from 'vite' export default defineConfig(({ mode }) => { const envPrefix = ['VUE'] const env = loadEnv(mode, process.cwd(), envPrefix) const define = { 'process.env.NODE_ENV': '"development"', 'process.env.BASE_URL': '"/"', 'process.env.VITE': true } for (const [key, value] of Object.entries(env)) { define[`process.env.${key}`] = `"${value}"` } return { define, } })

          自动导入

          // vue.config.js // 需要安装 webpack-strip-block,作用是为了删除某段代码 module.exports = { configureWebpack() { return { module: { rules: [ { test: /\.(js|scss)$/, enforce: 'pre', exclude: /node_modules/, use: [ { loader: 'webpack-strip-block' } ] } ] } } } }

          // VITE 变量是在 vite.config.js 配置的,webpack 中是不存在的 // develblock 开头的注释是因为 webpack 中不存在 import.meta.globEager,编译会失败,所以我们 // 需要对这种做特殊处理 if (process.env.VITE) { /* develblock:start */ componentsContext = import.meta.globEager('./**/index.vue') /* develblock:end */ } else { componentsContext = require.context('./', true, /index\.vue$/) } // autoImport 是我们自己写的共用方法,主要根据 process.env.VITE 判断就可以实现两种环境中的导入方式 const components = autoImport(componentsContext, 'component') for (const c of components) { Vue.component(c.name, c) }

          资源引入

          require('./xx.png') // 这样 vite 和 webpack 中都可以使用 import xx from './xx.png'

          在 webpack 打包中,我们样式中可能会出现下面这种引入方式,引入某个包下面的文件,或者引入 @(src 的别名)下的资源文件。

          @import "~@[包名称]/dist/xx.css"; .xx { background-image: url("~@/views/integration/assets/images/btn_icon/stop_hover.png"); }

          修改一下

          // 下面得写两行引入,因为为了兼容 webpack 和 vite。 /* develblock:start */ @import "@[包名称]/dist/xx.css"; /* develblock:end */ @import "~@[包名称]/dist/xx.css"; // 这个不用动 .xx { background-image: url("~@/views/integration/assets/images/btn_icon/stop_hover.png"); }

          我们这个时候得去 vite 配置下别名,可以根据自己需求灵活配置。

          // vite.config.js import { defineConfig } from 'vite' export default defineConfig(({ mode }) => { resolve: { alias: [ // 针对以 ~@/[包名称]开头的,替换为 node_modules/@[包名称] { find: /^(~@)(?!\/)(.+)/, replacement: path.join('node_modules/@$2') }, // 针对以 ~@/ 开头,替换为 src/ { find: /^~@\//, replacement: path.join(__dirname, 'src/') }, // 针对以 @/ 开头的,替换为 src/ { find: /^@\//, replacement: path.join(__dirname, './src', '/') } ] }, })

          svg-sprite-loader 替代方案

          在 webpack 中使用了 svg-sprite-loader,vite 中需要使用 vite-plugin-svg-icons

          // 原来 webpack 下引入 svg 文件的 js // 假设 svg 文件夹下存放了我所有的 svg 文件,这样两种环境下都可以使用 if (!process.env.VITE) { const context = require.context('./svg', false, /\.svg$/) context.keys().forEach(context) }

          // vite.config.js import { defineConfig } from 'vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' export default defineConfig(({ mode }) => { createSvgIconsPlugin({ // 存放 svg 文件的文件夹 iconDirs: [path.resolve(process.cwd(), 'src/common/icons/svg')], // 和 webpack 保持一致就行 symbolId: 'icon-[name]' }), })

          其他

          • 我项目中使用的是 Vue2,所以用的是 vite-plugin-vue2 这个插件,Vue3 也同理。
          • 我之前调试的时候,根目录和 public 下同时存在 index.html 的时候出现过一些缓存问题,所以利用 npm hook 在用 vite 启动的时候把 public 下的 index.html 删掉了,原理和上面使用的方法一样。
          • 我项目中使用的是 antd 1.x 的包,会因为 moment 导致错误,有一个 vite-plugin-antdv1-momentjs-resolver 可以解决,不用重复造轮子。
          • 不升级为 Vue3 是觉得没必要,项目中也使用了 @vue/composition-api 这个包,可以使用 Vue3 的 composition-api 写法。

          效果

          左边是 vite,右边是 webpack,vite 命令启动前我做了一些操作,所以 vite 启动几乎是秒开,而 webpack,是分钟级别的。这还是在我的电脑上,公司机子更慢了去了。

          在热更新方面,webpack 大概几秒钟,vite 几乎无感知。

          vite 第一次启动因为没有缓存,进页面稍微慢点,后面就感觉不到了。

          以上就是webpack项目中使用vite加速的兼容模式详解的详细内容,更多关于webpack vite加速兼容模式的资料请关注易盾网络其它相关文章!

          如何将Webpack项目中的Vite加速兼容模式改写为长尾关键词?

          标签:兼容