熬夜準備的一個React項目升級Vite的指南

寫在開頭

  • 在以前,已經不少朋友已經升級到了vite,可是大部分都是vue的項目,那麼今天咱們把以前webpackreact項目升級到vite!
  • 爲此,爲了讓你們少踩坑,我先把china-dev.cn這個網站項目升級到了vite
    image.png
  • 對於在線畫圖功能,可能沒有什麼影響,可是跟在線編寫javascript這個功能影響挺大,由於以前使用的庫,會跟webpack綁定,目前不支持vite,因而我更換了技術棧,可是效果反而更好了~,這說明,跟webpack強綁定是一個僞命題,辦法總比困難多,構建工具只是一種選擇而已~
    image.png
PS:這個網站永遠免費,裏面還有大量前端免費學習資料,爲此,我把這個項目抽離了業務部分,而後作成了一個簡單的項目模板

正式開始

若是你沒看過我以前寫的:webpack和vite的核心區別,建議你先看一遍,再來看這篇文章
  • webpack遷移到vite,最早要解決的事情:javascript

    • 把跟webpack強關聯的插件&技術棧解耦,任什麼時候候,跟一個第三方工具&環境強依賴,都不是一件好事,這一點,作太重型系統部署的架構師,相信都有這個感觸
    • 將項目中除了import引入方式的,所有替換成經過import引入。能夠這樣說,esm就是一種趨勢,由於它就是一個規範。vue3已經不支持ie11,替換國內老舊系統只是時間而已,這是一個大趨勢,深圳官方的一些網站已經開始推薦你使用新的瀏覽器了~
    • 規範你的代碼,不能出現typescript的類型錯誤等和其餘警告等,vite的熱更新很是脆弱,有可能你一個小的警告或不規範寫法,就會致使熱更新失效,並且報錯定位不許,或者直接不報錯,而是失效(下面會說這些坑)
  • 接下來 克隆個人腳手架到本地css

    • 地址 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按需加載vue

    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`;
            },
          },
        ],
      }),
    ]
  • 執行無感知熱更新:java

    import reactRefresh from "@vitejs/plugin-react-refresh";
    plugins:[
    ...,
    reactRefresh(),
    ]
  • 兼容不支持esm的瀏覽器react

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

    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文件,例如:

image.png

在這個時候,不管是熱更新模式,仍是prod構建,都是會去打包js文件,後面我刪除後就解決了這個問題。
  • 固然,vite熱更新還有一個問題,就是你可能會由於一個警告,就熱更新失效,並且報錯定位也不許確,當系統變得極度複雜的時候,這個問題就很致命。
  • 原生不支持less,須要安裝如下依賴,便可直接引入使用less,這點我以爲優於webpackgit

    yarn add less less-loader -D

使用下來感覺

  • 開發模式,比webpack好太多。基本上毫秒級別的啓動和熱更新速度
  • 配置也比較簡單,沒有webpack那一大堆東西
  • 純粹,乾淨。沒有require.context這種黑魔法,沒有上面是import,下面代碼裏面是require。所有都是importgithub

    有人會問,若是老的庫不兼容 esm,怎麼辦,例如 dva
    module.exports = require('./lib');
    module.exports.connect = require('react-redux').connect;
  • 這就有一個問題,esm在生產模式中沒法直接引入dva,這個時候能夠作一個簡單的處理,能夠優先取default屬性,若是取不到,就取默認的web

    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

image.png

相關文章
相關標籤/搜索