react&webpack老项目开发环境增加vite

  • 在开发环境下,vite的启动时间远远高于webpack,特别是首次启动,做到了真正的按需加载,开发体验好于webpack;
    • 目的:开发环境加入vite,生产环境不变
  • react项目切webpack(开发环境增加vite)
    • 例子项目简介:
      • 技术栈:react-17,ts,react脚手架(内置webpack@5.73.0,customize-cra
      • 实现了一个记录时间的插件out-put-time-plugin,下面的时间记录基于该插件,已发布在npm包上
      • 非首次启动平均时间4秒(存在cache情况下)
      • 热更新2444毫秒
      • 首次构建时间100886ms,有cache情况下再次构建时间54402ms
    • 引入vite后
      • 构建时间: 20.928s,相比首次提升80%,有cache提升61%(生产环境下没有添加,所以只做参考)
      • 启动时间555ms,相对于非首次启动时间提升87%
      • 热更新时间500ms,相对提高了79%
    • 转化步骤
      1. 安装vite-npm i vite
      2. 根目录下新建vite.config.ts
复制代码
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path'
export default defineConfig({
  server: {
    port: 3001,
  },
    plugins: [react()],
      resolve: {
    // 路径相关配置项
    alias: [
      {
        find: '@',
        replacement: path.resolve(__dirname, 'src'),
      },
      {
        find: 'src',
        replacement: path.resolve(__dirname, 'src'),
      },
    ],
    extensions: ['.js', '.json', '.ts', '.tsx', '.jsx', '.less'],
  },
});
      1. 新建一个main.js文件,拷贝src里面的index.tsx的内容进去(不做也可以,引入的script标签src就为index.tsx)
      2. 拷贝public里面的index.html,放在最外层,文件中的%PUBLIC_URL%字段(公共URL路径)去掉, 加入<script type="module" src="src/index.tsx"></script>
        1. vite的入口文件index.html在最外层,并且index.html 中的 URL 将被自动转换,因此不再需要 %PUBLIC_URL% 占位符了(指向对应的public文件夹的绝对路径)
        2. 思考:可以实现一个方法,将public文件夹里面的文件拷贝并且经过处理后放置在目录最外层
复制代码
import fs from 'fs'
import path from 'path'


function createHtml() {
    var htmlPath = path.resolve(__dirname, 'public');
    // 目录最外层
    var outPath = path.resolve(__dirname);
    var webpackHtml = path.join(htmlPath, 'index.html');
    var viteHtml = path.join(outPath, 'index.html');


    // exists弃用,existsSync不使用回调
    // 存在的话就返回
    if (fs.existsSync(viteHtml)) return


    if (fs.existsSync(webpackHtml)) {
        var content = fs.readFileSync(webpackHtml, 'utf-8');


        content = content.replace(/%PUBLIC_URL%/g, '');


        var bq = '<script type="module" src="src/index.tsx"></script>';
        var bodyIndex = content.lastIndexOf('</body>');
        content = content.slice(0, bodyIndex)+bq+content.slice(bodyIndex)


        fs.writeFileSync(viteHtml, content, 'utf-8');
        console.log(`${outPath}成功创建外层html`);
    } else {
        console.error(`${htmlPath}路径没有html`);
    }
}


export default createHtml
      1. package.json文件里面的script,加入启动vite脚手架命令(保留webpack命令)

      2. 这个时候启动的话,会报下图错误

        1. 主要原因是开发环境,vite使用esbuild对代码进行转化(符合es),react文件的后缀结尾可以为js,jsx,ts,tsx,这些文件可能都包含jsx语法。

        2. esbuild对jsx语法文件要求是后缀结尾的为jsx或者tsx,对于js,ts里面包含jsx语法的文件会报错。可增加其对应的后缀结尾

          1. 解决方法,在vue.config里面加入上图代码

        3. 环境变量设置

          1. 上图报错为环境两个两个脚手架暴露和访问环境变量的方式不同

          2. react脚手架中环境变量访问通过process.env,且环境变量必须以 REACT_APP_ 为前缀,vite里面则为import.meta.env,所以需要替换(开发环境为import.meta.env)

          3. vite默认抛出以前缀开头为 VITE_的环境变量,REACT_APP_开头的环境变量使用import.meta.env是取不到的

          4. 可以在vite.config.ts中,加入选项envPrefix,并且加入前缀'REACT_APP_'即可,这样就不用改变原来的声明的环境变量

          5. import.meta.env,ts类型检查会有报错,在tsconfig.json里面加入"types": ["vite/client"]、

          6. 思考:可实现一个方法,在转译代码的时候,替换该process.env,并且设置前缀

复制代码
function vitePluginEnvTransform() {
  return {
    config: function () {
      return {
        //支持前缀REACT_APP_
        envPrefix: 'REACT_APP_'
    },
        // 对应webpack的loader,转译的时候将process.env转化为import.meta.env
    transform: function (code, id) {
      if (id.includes('node_modules')) return code;


      return code.replace(/process\.env\./g,'import.meta.env.');
    },
  };
}


export default vitePluginEnvTransform;
        1. 引入antd的css:无法识别~符号
          1. 解决方法:在vite.config里面配置对应路径

          2. 注意:vite不支持require语法

            1. 使用vite-plugin-require-transform插件
            2. import requireTransform from 'vite-plugin-require-transform'
            3. requireTransform({
            4. fileRegex: /src\/.*\.[tj]sx?$/,
            5. })
        2. 分支switchVite,脚手架vite和webpack并存
          1. 可以将vite.config.ts里面的配置写进vitePluginEnvTransform方法里面
          2. 然后将两个方法写进一个插件里面,这样实现了一个简单通用的react&webpack项目增加vite脚手架的插件react-webpack-to-vite-env
复制代码
import { defineConfig, PluginOption } from 'vite';
import react from '@vitejs/plugin-react';
import requireTransform from 'vite-plugin-require-transform'


import {createHtml,vitePluginEnvTransform} from 'react-webpack-to-vite-env'
export default defineConfig({
    plugins: [createHtml(),react(), vitePluginEnvTransform() as PluginOption, requireTransform({
        fileRegex: /src\/.*\.[tj]sx?$/,
    }),],
    });
相关推荐
T^T尚4 小时前
uniapp H5上传图片前压缩
前端·javascript·uni-app
出逃日志4 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
XIE3924 小时前
如何开发一个脚手架
前端·javascript·git·npm·node.js·github
GISer_Jing4 小时前
React渲染相关内容——渲染流程API、Fragment、渲染相关底层API
javascript·react.js·ecmascript
山猪打不过家猪4 小时前
React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo
前端·javascript·react.js
前端青山4 小时前
React事件处理机制详解
开发语言·前端·javascript·react.js
科技D人生4 小时前
Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
前端·vue.js·vue ref·vue ref 响应式·vue reactive
对卦卦上心4 小时前
React-useEffect的使用
前端·javascript·react.js
练习两年半的工程师5 小时前
React的基本知识:事件监听器、Props和State的区分、改变state的方法、使用回调函数改变state、使用三元运算符改变state
前端·javascript·react.js
啵咿傲5 小时前
在React中实践一些软件设计思想 ✅
前端·react.js·前端框架