1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Vite 2.0 + React + Ant Design 4.0 搭建開發(fā)環(huán)境

        共 15750字,需瀏覽 32分鐘

         ·

        2021-03-20 16:24


        關(guān)注公眾號 前端人,回復“加群

        添加無廣告優(yōu)質(zhì)學習群

        前言

        最近公司要做一個小項目,我問老大能不能用 Vue 寫,因為公司一直用 React, 主要是想嘗試一下 ViteVite 又是祖師爺出的,所以我想試試用 Vue 作為技術(shù)棧。老大問我:“屎吃不吃。” 我隱約覺得老大是在罵祖師爺,但又沒法反駁,于是就嘗試用 Vite + React 的形式整一個項目架子。

        這里默認大家都裝了 Node 環(huán)境了。

        知識點

        • Vite 初始化 React 項目
        • 引入路由插件 react-router-dom
        • 引入 Ant Design 組件庫
        • 配置 Ant Design 按需引入
        • 配置 Ant Design 主題色
        • 配置打包時和運行時的環(huán)境變量 env
        • axios 二次封裝
        • 打包靜態(tài)資源的路徑
        • Vite 的一些配置如開發(fā)端口、 proxy 代理、 alias 別名等

        開動

        初始化 Vite + React 項目

        這里不得不感慨,年前還是 Vite 1.x,年后就變成 2.x 了。說明兩個問題,祖師爺對這個項目很積極,還有就是不確定因素比較多。但這不妨礙我們?nèi)W習它,因為真的又香又快。放個官方中文文檔,有興趣的可以看看文檔。

        Vite 官方提供兩種初始化項目的方式,一種是:

        npm init @vitejs/app 

        可以自由選擇配置。還有一種是直接用官方提供的模板,一鍵生成:

        # npm 6.x
        npm init @vitejs/app vite-react-app --template react

        # npm 7+, 需要額外的雙橫線:
        npm init @vitejs/app vite-react-app -- --template react 

        本教程采用第二種形式,生成項目如下:

        按照上述步驟,進入 vite-react-app ,安裝完包之后,啟動項目:

        image.png

        此時你已經(jīng)成功搭建出 Vite + React 的開發(fā)環(huán)境。?? ?? ??

        引入路由插件 react-router-dom

        首選安裝 react-router-dom,指令如下:

        npm i react-router-dom -S 

        在項目 src 目錄下新增 container 目錄用于放置頁面組件,再在 container 下新增兩個目錄分別是 Index 和 About ,添加如下內(nèi)容:

        // Index/index.jsx
        import React from 'react'

        export default function Index({
          return <div>
            Index
          </div>

        }

        // About/index.jsx
        import React from 'react'

        export default function About({
          return <div>
            About
          </div>


        image.png

        再來新建 src/router/index.js 配置路由數(shù)組,添加如下內(nèi)容:

        // router/index.js
        import Index from '../container/Index'
        import About from '../container/About'

        const routes = [
          {
            path"/",
            component: Index
          },
          {
            path"/about",
            component: About
          }
        ];

        export default routes 

        App.jsx 引入路由配置,實現(xiàn)切換瀏覽器路徑,顯示相應的組件:

        // App.jsx
        import React, { useState } from 'react'
        import {
          BrowserRouter as Router,
          Switch,
          Route
        from "react-router-dom"
        import routes from '../src/router'
        function App({
          return <Router>
            <Switch>
              {
                routes.map(route => <Route exact key={route.path} path={route.path}>
                  <route.component />
                </Route>)
              }
            </Switch>
          </Router>

        }

        export default App 

        啟動項目 npm run dev,如下圖所示:

        引入 Ant Design UI 組件庫

        Ant Design 的官網(wǎng)沒有給出 Vite 的配置方法,這邊是我自己摸索的。首先我們下載安裝包:

        npm i antd @ant-design/icons -S 

        目前最新版本 icon 包是分開的,所以這邊順帶就把 @ant-design/icons 也安裝了。

        安裝成功之后,我們先通過全局引入的方式,測試是否能成功跑通。打開 main.jsx 添加樣式:

        ...
        import 'antd/dist/antd.css'
        ... 

        再回到 Index/index.jsx 修改如下:

        import React from 'react'
        import { Button } from 'antd'

        export default function Index({
          return <div>
            <Button type='primary'>Index</Button>
          </div>


        重新啟動項目,瀏覽器如下所示,代表引入 Ant Design 成功:

        image.png

        此時我們可以嘗試著做一些優(yōu)化,我們先看看,就目前現(xiàn)在這個情況,打完包之后,靜態(tài)資源有多大。運行指令 npm run build ,如下所示:

        image.png

        腚眼一看,全局引入樣式的形式,直接打完包, css 靜態(tài)資源就 587.96k 了,我們嘗試 按需加載 樣式。

        首先我們安裝一個插件:

        npm i vite-plugin-imp -D 

        然后在 vite.config.js 配置文件內(nèi)添加如下內(nèi)容:

        import { defineConfig } from 'vite'
        import reactRefresh from '@vitejs/plugin-react-refresh'
        import vitePluginImp from 'vite-plugin-imp'

        // https://vitejs.dev/config/
        export default defineConfig({
          plugins: [
            reactRefresh(),
            vitePluginImp({
              libList: [
                {
                  libName"antd",
                  style(name) => `antd/lib/${name}/style/index.less`,
                },
              ],
            })
          ],
          css: {
            preprocessorOptions: {
              less: {
                // 支持內(nèi)聯(lián) JavaScript
                javascriptEnabledtrue,
              }
            }
          },
        }) 

        再安裝 less 插件包, npm i less -D,因為上述配置我們使用的是 less,并且我們需要配置 javascriptEnabled 為 true,支持 less 內(nèi)聯(lián) JS。

        這里我們將 main.jsx 的 import 'antd/dist/antd.css' 去掉,再次啟動 npm run dev,你會發(fā)現(xiàn)樣式被按需引入了。我們看看插件 vite-plugin-imp 做了什么工作:

        image.png

        嚯喔~,這邊在 index.jsx 內(nèi)單獨引入了按鈕的樣式組件。我們再看看打包后的靜態(tài)資源大小:

        image.png

        css 樣式包直接變成 40.29kb,好香啊~~

        有些同學可能會擔心,在不同的頁面都引入了 Button 組件,那么樣式會不會重復引入。答案是不會的,打包構(gòu)建的時候,會合并同類項,所以最后只會引入一次 Button 的樣式文件。

        自定義 Ant Design 主題色

        開發(fā)時,會按照項目的需要,設計師的設計(瞎畫),來定制一套主題樣式,包括邊距、文字大小、borderColor等等規(guī)則??赡芤郧坝?webpack 那套的同學知道怎么玩,但是現(xiàn)在用 Vite,我們需要做如下操作。

        首先打開 vite.config.js,添加如下代碼:

        ...
        import path from 'path'
        import fs from 'fs'
        import lessToJS from 'less-vars-to-js'

        const themeVariables = lessToJS(
          fs.readFileSync(path.resolve(__dirname, './config/variables.less'), 'utf8')
        )

        ...
        css: {
          preprocessorOptions: {
            less: {
              // 支持內(nèi)聯(lián) JavaScript
              javascriptEnabledtrue,
              // 重寫 less 變量,定制樣式
              modifyVars: themeVariables
            }
          }
        }
        ... 

        less-vars-to-js 是將 less 樣式轉(zhuǎn)化為 json 鍵值對的形式,當然你也可以直接在 modifyVars 屬性后寫 json 鍵值對。

        然后在根目錄新建 config 目錄,添加 variables.less 內(nèi)容如下:

        // 自定義覆蓋 =============================================================
        @primary-color: green; // 全局主色
        // 下面你可以各種寫一些覆蓋的樣式,這里就簡單覆蓋一個主題色的樣式,我們改為綠色 

        重新運行下面如下所示:

        image.png

        這樣主題色就改造好了。

        環(huán)境變量如何獲取

        我搜了很多資料,但是以目前 Vite 的生態(tài),還是沒能找到我需要的答案,我把最后的希望寄托在 Vite 的倉庫 issue,還真搜出了一些東西。這里插一句題外話,有什么問題,先自己解決,去相應的倉庫里瞅瞅,有沒有已經(jīng)解決掉的類似問題。不要動不動就去群里問大佬,大佬不忙啊,免費給你解決問題?

        好,我們圓規(guī)正轉(zhuǎn)。咱們平時開發(fā)項目的時候,基本上有三個環(huán)境,開發(fā)環(huán)境、測試環(huán)境、正式環(huán)境,這三個環(huán)境需要配置三種不同的資源,如圖片、接口地址、埋點、百度統(tǒng)計等等。

        打包時 那么我們?nèi)绾卧诖虬鼤r,在 vite.config.js 中拿到環(huán)境變量呢?首先我們先修改 package.json 的 scripts 屬性,如下所示:

        scripts: {
         "dev""vite --mode development",
          "build:beta""vite build --mode beta",
          "build:release""vite build --mode release",
          "serve""vite preview"

        --mode 后代表的是各個環(huán)境對應的環(huán)境變量值,這里為什么一定要用 --mode 呢?官方定的,后續(xù)可以在頁面中拿到這個變量值。

        我們在 vite.config.js 打印如下所示:

        console.log('process:::env', process.argv) 

        重新運行 npm run dev 如下所示:

        image.png

        最后一個參數(shù),便是我們設置好的環(huán)境變量。所以我們可以通過如下獲取環(huán)境變量:

        const env = process.argv[process.argv.length - 1] 

        我們可以在 vite.config.js 里配置 index.html 內(nèi),靜態(tài)資源的路徑前綴。改動如下:

        ...
        const env = process.argv[process.argv.length - 1]
        const base = config[env]
        ...
        export default defineConfig({
         base: base.cdn
        }) 

        在根目錄的 config 目錄內(nèi),添加 index.js 文件,添加如下內(nèi)容:

        export default {
          development: {
            cdn'./',
            apiBaseUrl'/api' // 開發(fā)環(huán)境接口請求,后用于 proxy 代理配置
          },
          beta: {
            cdn'//s.xxx.com/vite-react-app/beta'// 測試環(huán)境 cdn 路徑
            apiBaseUrl'//www.beta.xxx.com/v1' // 測試環(huán)境接口地址
          },
          release: {
            cdn'//s.xxx.com/vite-react-app/release'// 正式環(huán)境 cdn 路徑
            apiBaseUrl'//www.xxx.com/v1' // 正式環(huán)境接口地址
          }

        我們來打個測試包試試,運行如下指令:

        npm run build:beta 

        結(jié)果如下所示: 同理可得正式環(huán)境的鳥樣。

        運行時 那么運行代碼的時候,我們?nèi)绾潍@取到相應的環(huán)境變量呢?答案是 import.meta.env 。我們在 Index/index.jsx 里打印一下便可知曉:

        import React from 'react'
        import { Button } from 'antd'

        export default function Index({
          console.log('import.meta.env'import.meta.env)
          return <div>
            <Button type='primary'>Index</Button>
          </div>


        image.png

        返回了一個對象,對象內(nèi)分別是相應的參數(shù),我們這里我們需要的是 MODE 屬性對應的參數(shù),便是我們要的當前環(huán)境變量。

        二次封裝 axios

        開發(fā)項目時,服務端會為我們提供測試接口和正式接口,這里我們需要配置相應的變量來動態(tài)的獲取請求地址。首先我們先安裝 axios 和 qs :

        npm i axios qs -S 

        然后在 src 目錄下新建 utils 目錄,專門用于存放各種工具方法。在 utils 下新建 index.js,添加如下代碼:

        import axios from 'axios'
        import { message } from 'antd'
        import { stringify } from 'qs'
        import config from '../../config'

        const MODE = import.meta.env.MODE // 環(huán)境變量

        const getRequest = (method) => {
          return (url, data, options = {}) => {
            let base = config[MODE] // 獲取環(huán)境變量相對應的屬性值
            return axios({
              baseURL: base.apiBaseUrl, // 請求域名地址
              method,
              url,
              ...(method === 'POST'
                ? {
                    data: options.string ? stringify(data) : data,
                  }
                : {}),
              params: method === 'GET' ? data : options.params,
              headers: {
                'X-Requested-With''XMLHttpRequest',
                'Content-Type': options.string
                  ? 'application/x-www-form-urlencoded'
                  : 'application/json',
                ...options.headers,
              },
              withCredentialstrue,
            })
              .then((res) => {
                if (typeof res.data !== 'object') {
                  console.error('數(shù)據(jù)格式響應錯誤:', res.data)
                  message.error('前方擁擠,請刷新再試')
                  return Promise.reject(res)
                }

                if (res.data.errcode) {
                  if (res.data.errcode == 401) {
                    window.location.href = 'login' // 登錄失效跳轉(zhuǎn)登錄頁
                    return
                  }
                  // silent 選項,錯誤不提示
                  if (res.data.message && !options.silent)
                    message.error(res.data.message)
                  return Promise.reject(res.data)
                }

                return res.data
              })
              .catch((err) => {
                message.error('系統(tǒng)錯誤'2)
                return Promise.reject(err)
              })
          }
        }

        export const get = getRequest('GET')

        export const post = getRequest('POST') 

        這里通過 config[MODE] 獲取開發(fā)、測試、正式相對應的屬性值,從而拿到 apiBaseUrl 變量值。

        順帶我們把開發(fā)環(huán)境的請求代理也添加一下,我們打開 vite.config.js ,添加如下屬性:

        ...
        export default defineConfig({
         ...
         server: {
            port3001// 開發(fā)環(huán)境啟動的端口
            proxy: {
              '/api': {
                // 當遇到 /api 路徑時,將其轉(zhuǎn)換成 target 的值,這里我們?yōu)榱藴y試,寫了新蜂商城的請求地址
                target'http://47.99.134.126:28019/api/v1',
                changeOrigintrue,
                rewritepath => path.replace(/^\/api/''// 將 /api 重寫為空
              }
            }
          }
        }) 

        測試接口是否請求成功,我們在 Index/index.jsx 內(nèi)添加如下代碼:

        import React, { useEffect } from 'react'
        import { Button } from 'antd'
        import { get } from '../../utils'

        export default function Index() {
          useEffect(() => {
            get('/index-infos').then(() => {
              
            })
          }, [])
          return <div>
            <Button type='primary'>Index</Button>
          </div>


        重新啟動項目,結(jié)果如下圖所示:

        image.png

        resolve.alias 別名設置

        和大多數(shù)的配置項類似,別名的配置也在 vite.config.js 中,我們打開它,添加如下代碼:

        export default defineConfig({
         ...
          resolve: {
            alias: {
              '~': path.resolve(__dirname, './'), // 根路徑
              '@': path.resolve(__dirname, 'src'// src 路徑
            }
          }
          ...
        }) 

        配置完后,我們重寫上述代碼中的一些路徑如下:

        // router/index.js
        import Index from '@/container/Index'
        import About from '@/container/About'

        // utils/index.js
        import config from '~/config'

        // App.jsx
        import routes from '@/router' 

        方便又簡介,后續(xù)還能繼續(xù)增加一些路徑,少些幾個字,提高開發(fā)效率。

        總結(jié)

        這篇文章到此就告一段落了。什么?你還要 TSCSS Module、 Eslint,別鬧了,自己去倉庫下載代碼,慢慢玩耍吧,我都寫吐了,求贊啊兄弟萌~~~。破 500 贊,我再碼一篇 Vite + Vue + element-plus 的。溜溜球~~~

        原文地址:juejin.cn/user/4019470243991799


        • 回復資料包領(lǐng)取我整理的進階資料包
        • 回復加群,加入前端進階群
        • console.log("點贊===看===你我都快樂")
        • Bug離我更遠了,下班離我更近了


        瀏覽 67
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久久久久亚洲AV无码网影音先锋 | 久久久久毛片国产多多水 | 婷综合开心 | 日本草逼| 免费做人爱高潮1000视频 | 午夜成人福利剧场 | 日韩三级片一区二区 | 古代喂奶肉多荤文高h | 奴役支配性狂虐xxxxx在线 | 国产片婬乱一级毛片影片乱叫 |