乐趣区

关于javascript:熬夜准备的一个React项目升级Vite的指南

写在结尾

  • 在之前,曾经很多敌人曾经降级到了 vite, 然而大部分都是 vue 的我的项目,那么明天咱们把之前webpackreact我的项目降级到vite!
  • 为此,为了让大家少踩坑,我先把 china-dev.cn 这个网站我的项目降级到了vite
  • 对于在线画图性能,可能没有什么影响,然而跟在线编写 javascript 这个性能影响挺大,因为之前应用的库,会跟 webpack 绑定,目前不反对 vite,于是我更换了技术栈,然而成果反而更好了~,这阐明,跟webpack 强绑定是一个伪命题,方法总比艰难多,构建工具只是一种抉择而已~

PS: 这个网站永远收费,外面还有大量前端收费学习材料,为此,我把这个我的项目抽离了业务局部,而后做成了一个简略的我的项目模板

正式开始

如果你没看过我之前写的:webpack 和 vite 的外围区别,倡议你先看一遍,再来看这篇文章

  • webpack 迁徙到 vite, 最先要解决的事件:

    • 把跟 webpack 强关联的插件 & 技术栈解耦,任何时候,跟一个第三方工具 & 环境强依赖,都不是一件坏事,这一点,做过重型零碎部署的架构师,置信都有这个感触
    • 将我的项目中除了 import 引入形式的,全副替换成通过 import 引入。能够这样说,esm就是一种趋势,因为它就是一个标准。vue3曾经不反对 ie11, 替换国内老旧零碎只是工夫而已,这是一个大趋势, 深圳官网的一些网站曾经开始举荐你应用新的浏览器了~
    • 标准你的代码,不能呈现 typescript 的类型谬误等和其余正告等,vite的热更新十分软弱,有可能你一个小的正告或不标准写法,就会导致热更新生效,而且报错定位不准,或者间接不报错,而是生效(上面会说这些坑)
  • 接下来 克隆我的脚手架到本地

    • 地址 https://github.com/JinJieTan/Peter-/tree/master/vite-react-ts-antd
    • 将你的 src 源码目录植入我的我的项目模板中
    • 我的项目根目录执行 yarn 装置依赖
    • index.hmtl入口文件,我这里默认是去加载 src/index.tsx 文件
    • 执行 yarn dev, 启动我的项目,如果此时你的代码没问题,曾经 run 起来了(我我的项目中默认是 react17.x,ts4.x 版本,如果须要降级,请你装置指定依赖)

脚手架阐明:

  • 通过 husky 在每次 git commit 时候应用 prettier 对立丑化代码,再通过 eslint 进行代码检测,最终应用 commitlint 提交信息是否符合要求,以此保障代码品质

    这几十条规定,都是我一条一条精挑细选进去的,因为我不喜爱用不分明他人细节的货色,这套规定我也心愿大家用上来,每一条都有正文

     rules: {semi: ['error', 'always'], // 该规定强制应用统一的分号
          'no-unused-vars': 'off', // 禁止未应用过的变量
          'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 生产环境禁用 debugger
          'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 生产环境禁用 console
          'default-case': ['warn', { commentPattern: '^no default$'}], // 要求 Switch 语句中有 Default
          'dot-location': ['warn', 'property'], // 强制在点号之前或之后换行
          eqeqeq: ['error', 'allow-null'], // 要求应用 === 和 !==
          'new-parens': 'warn', // 要求调用无参构造函数时带括号
          'no-caller': 'error', // 禁用 caller 或 callee
          'no-const-assign': 'error', // 不容许扭转用 const 申明的变量
          'no-dupe-args': 'error', // 禁止在 function 定义中呈现反复的参数
          'no-dupe-class-members': 'error', // 不容许类成员中有反复的名称
          'no-dupe-keys': 'warn', // 禁止在对象字面量中呈现反复的键
          'no-extend-native': 'warn', // 禁止扩大原生对象
          'no-extra-bind': 'warn', // 禁止不必要的函数绑定
          'no-fallthrough': 'error', // 禁止 case 语句落空
          'no-func-assign': 'warn', // 禁止对 function 申明从新赋值
          'no-implied-eval': 'error', // 禁用隐式的 eval()
          'no-label-var': 'error', // 禁用与变量同名的标签
          'no-loop-func': 'error', // 禁止循环中存在函数
          'no-mixed-operators': [
              'warn',
              {
                  groups: [['&', '|', '^', '~', '<<', '>>', '>>>'],
                      ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
                      ['&&', '||'],
                      ['in', 'instanceof'],
                  ],
                  allowSamePrecedence: false,
              },
          ], // 禁止混合应用不同的操作符
          'no-multi-str': 'warn', // 禁止多行字符串 (须要多行时用 \n)
          'no-native-reassign': 'warn', // 禁止重新分配本地对象
          'no-obj-calls': 'warn', // 禁止将全局对象当作函数进行调用
          'no-redeclare': 'error', // 禁止从新申明变量
          'no-script-url': 'warn', // 禁用 Script URL
          'no-shadow-restricted-names': 'warn', // 关键字不能被遮蔽
          'no-sparse-arrays': 'warn', // 禁用稠密数组
          'no-this-before-super': 'warn', // 在构造函数中禁止在调用 super()之前应用 this 或 super
          'no-undef': 'error', // 禁用未声明的变量
          'no-unexpected-multiline': 'warn', // 禁止应用令人困惑的多行表达式
          'no-use-before-define': [
              'warn',
              {
                  functions: false,
                  classes: false,
                  variables: false,
              },
          ], // 禁止定义前应用
          'no-with': 'error', // 禁用 with 语句
          radix: 'error', // 禁用函数内没有 yield 的 generator 函数
          'rest-spread-spacing': ['warn', 'never'], // 强制限度扩大运算符及其表达式之间的空格
          'react/jsx-no-undef': 'error', // 在 JSX 中禁止未声明的变量
          'react/no-direct-mutation-state': 'error', // 禁止 this.state 的间接变动
          'react/jsx-uses-react': 'warn', // 避免 React 被谬误地标记为未应用
          'no-alert': 0, // 禁止应用 alert confirm prompt
          'no-duplicate-case': 2, //switch 中的 case 标签不能反复
          'no-eq-null': 2, // 禁止对 null 应用 == 或!= 运算符
          'no-inner-declarations': [2, 'functions'], // 禁止在块语句中应用申明(变量或函数)'no-iterator': 2, // 禁止应用__iterator__ 属性
          'no-negated-in-lhs': 2, //in 操作符的右边不能有!
          'no-octal-escape': 2, // 禁止应用八进制转义序列
          'no-plusplus': 0, // 禁止应用 ++,--
          'no-self-compare': 2, // 不能比拟本身
          'no-undef-init': 2, // 变量初始化时不能间接给它赋值为 undefined
          'no-useless-call': 2, // 禁止不必要的 call 和 apply
          'init-declarations': 0, // 申明时必须赋初值
          'prefer-const': 0, // 首选 const
          'use-isnan': 2, // 禁止比拟时应用 NaN,只能用 isNaN()
          'vars-on-top': 2, //var 必须放在作用域顶部
      },
  • 反对 ant-design 按需加载

    import vitePluginImp from "vite-plugin-imp";
    plugins:[
    ...,
     vitePluginImp({
        libList: [
          {
            libName: "antd",
            style(name) {if (/CompWithoutStyleFile/i.test(name)) {return false;}
              return `antd/es/${name}/style/index.css`;
            },
          },
        ],
      }),
    ]
  • 执行无感知热更新:

    import reactRefresh from "@vitejs/plugin-react-refresh";
    plugins:[
    ...,
    reactRefresh(),]
  • 兼容不反对 esm 的浏览器

    import legacy from "@vitejs/plugin-legacy";
    
    plugins:[
    ...,
     legacy({targets: ["defaults", "not IE 11"],
      }),
    ]
  • 反对 ts 在 vite 中的 alias 配置

    vite.config.ts
    resolve: {
      alias: {"@": path.resolve(__dirname, "./src"),
        "@c": path.resolve(__dirname, "./src/components"),
        "@s": path.resolve(__dirname, "./src/service"),
        "@m": path.resolve(__dirname, "./src/model"),
      },
    },
    
    tsconfig.json 中
    "baseUrl": "./",
      "paths": {"@/*": ["./src/*"],
        "@c/*": ["./src/components/*"],
        "@m/*": ["./src/model/*"],
        "@s/*": ["./src/service/*"],
        "@t/*": ["./src/types/*"]
      }

遇到的问题

  • 第三方库之前跟 webpack 插件有绑定,而 vite 不反对,最初更换了技术栈
  • vite热更新问题,这个问题应该很多人都会遇到,然而我踩坑一天后,就没有再遇到了。viteprod 模式构建,是通过 tsc 转换成 js 后,再通过 rollup 进行打包,然而先 yarn build 后,就会在 tsx 左近产生 js 文件,例如:

在这个时候,无论是热更新模式,还是 prod 构建,都是会去打包 js 文件,前面我删除后就解决了这个问题。

  • 当然,vite热更新还有一个问题,就是你可能会因为一个正告,就热更新生效,而且报错定位也不精确,当零碎变得极度简单的时候,这个问题就很致命。
  • 原生不反对 less, 须要装置以下依赖,即可间接引入应用less, 这点我感觉优于webpack

    yarn add less less-loader -D

应用下来感触

  • 开发模式,比 webpack 好太多。基本上毫秒级别的启动和热更新速度
  • 配置也比较简单,没有 webpack 那一大堆货色
  • 纯正,洁净。没有 require.context 这种黑魔法,没有下面是import,上面代码外面是require。全部都是import

    有人会问,如果老的库不兼容esm,怎么办,例如dva

    module.exports = require('./lib');
    module.exports.connect = require('react-redux').connect;
  • 这就有一个问题,esm在生产模式中无奈间接引入 dva,这个时候能够做一个简略的解决, 能够优先取default 属性,如果取不到,就取默认的

    import dva from "dva";
    let tag = dva.default || dva;
    const app = test({history: createHistory(),
    });

写在最初

  • 看得再多,不如间接入手实际,克隆我这个模板下来试试把。别忘了给个star, 开源不易,外面还有其余的源码,https://github.com/JinJieTan/Peter-/tree/master/vite-react-ts-antd

退出移动版