Vite 2.0 + React + TypeScript + Antd 搭建簡單腳手架

JackySummer發表於2022-01-05

前言

Vite 出來好一段時間了,最開始支援 Vue,而現在已經不受框架限制了。而 Vite 解決的是對於專案每次啟動與打包構建等待時間長的問題,Vite 就是解決了該問題,提高開發效率與體驗,本文作個簡單的學習記錄。

初始化

通過 Vite 官方命令列選項直接指定專案名稱和想要使用的模板。例如,要構建一個 Vite + TypeScript 專案

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

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

建立完安裝依賴後,執行專案如圖:

image.png

配置路由

npm i react-router-dom@5.3.0

由於v6目前試用ts提示等有一些問題,避免講解複雜還是直接簡單點用v5版本,用法不變。

首先新建三個頁面檔案,在 src/pages資料夾下新建三個頁面

// home
const Home = () => {
  return <div>home page</div>
}

export default Home

// about
const About = () => {
  return <div>about page</div>
}

export default About

// not found
const NotFound = () => {
  return <div>404 page</div>
}

export default NotFound

src/config目錄下新建檔案 routes.ts

import { lazy } from 'react'

const Home = lazy(() => import('../pages/home'))
const About = lazy(() => import('../pages/about'))
const NotFound = lazy(() => import('../pages/not_found'))

const routes = [
  {
    path:'/',
    exact: true,
    component: Home,
    name:'Home'
  },
  {
    path:'/home',
    component: Home,
    name:'Home'
  },
  {
    path:'/about',
    component: About,
    name:'About'
  },
  {
    path: '/404',
    component: NotFound,
  },
]
export default routes

新建檔案src/router.tsx,路由檔案入口

import { Suspense } from 'react'
import { Route, Switch } from 'react-router-dom'
import routes from './config/routes'

const Router = () => {
  const myRoutes = routes.map((item) => {
    return <Route key={item.path} {...item} component={item.component} />
  })
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>{myRoutes}</Switch>
    </Suspense>
  )
}

export default Router

App.tsx

import Router from './router'
// 這裡我封裝了,其實就使用react-router-dom的Link
import { Link } from './components' 

function App() {
  return (
    <div className="App">
      <Link to="/">Home Page</Link>
      <Link to="/about">About Page</Link>
      <Router />
    </div>
  )
}

export default App

進入http://localhost:3000,此時就可以切換路由了

image.png

支援 Antd

在寫該文章的時候,antd最新版本為4.18.1,使用vite打包會有錯誤,然後回退到antd的4.17.1就可以了,具體見 https://github.com/ant-design...
 npm i antd@4.17.1 @ant-design/icons

在App.tsx引入antd的按鈕元件:

import { Button } from 'antd'

// ...
<Button type="primary">按鈕</Button>

antd使用的是less,這時還需要支援Less

npm i less less-loader -D

我們還要對 antd 按需引入,安裝外掛

npm i vite-plugin-imp -D

vite.config.ts 的配置如下:

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

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    vitePluginImp({
      optimize: true,
      libList: [
        {
          libName: 'antd',
          libDirectory: 'es',
          style: (name) => `antd/es/${name}/style`
        }
      ]
    })
  ],
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true, // 支援內聯 JavaScript
      }
    }
  },
})

此時檢視頁面,確實單獨引入了按鈕的樣式元件

image.png

這樣頁面就正常顯示出antd的按鈕元件了

image.png

alias 別名設定

這個同webpack配置差不多,在 vite.config.js

import path from 'path'

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

改一下 App.tsx 的 Link 元件引入,試驗一下

- import { Link } from './components'
+ import { Link } from '@/components'

此時編輯器會看到紅色警告:Cannot find module '@/components' or its corresponding type declarations.,是因為我們別名沒有在 tsconfig.json 裡面配置,修改:

"compilerOptions": {
  "paths":{
    "@/*": ["src/*"],
   },
}

eslint 與 Prettier 配置

npm i -D @typescript-eslint/parser eslint eslint-plugin-standard @typescript-eslint/parser @typescript-eslint/eslint-plugin                    

.eslintrc.js檔案參考:

module.exports = {
  extends: ['eslint:recommended', 'plugin:react/recommended'],
  env: {
    browser: true,
    commonjs: true,
    es6: true,
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
      modules: true,
    },
    sourceType: 'module',
    ecmaVersion: 6,
  },
  plugins: ['react', 'standard', '@typescript-eslint'],
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.tsx', '.ts', '.js', '.json'],
      },
      alias: [['@', './src']],
    },
  },
  rules: {
    semi: 0,
    indent: 0,
    'react/jsx-filename-extension': 0,
    'react/prop-types': 0,
    'react/jsx-props-no-spreading': 0,

    'jsx-a11y/click-events-have-key-events': 0,
    'jsx-a11y/no-static-element-interactions': 0,
    'jsx-a11y/no-noninteractive-element-interactions': 0,
    'jsx-a11y/anchor-is-valid': 0,

    'no-use-before-define': 0,
    'no-unused-vars': 0,
    'implicit-arrow-linebreak': 0,
    'consistent-return': 0,
    'arrow-parens': 0,
    'object-curly-newline': 0,
    'operator-linebreak': 0,
    'import/no-extraneous-dependencies': 0,
    'import/extensions': 0,
    'import/no-unresolved': 0,
    'import/prefer-default-export': 0,

    '@typescript-eslint/ban-ts-comment': 0,
    '@typescript-eslint/no-var-requires': 0,
  },
}

Prettier 配置

npm i -D prettier

.prettierrc

{
  "singleQuote": true,
  "tabWidth": 2,
  "endOfLine": "lf",
  "trailingComma": "all",
  "printWidth": 100,
  "arrowParens": "avoid",
  "semi": false,
  "bracketSpacing": true
}

環境變數

新增.env.env.prod檔案,當使用自定義環境時變數要以VITE為字首

.env                # 所有情況下都會載入
.env.[mode]         # 只在指定模式下載入

.env

NODE_ENV=development
VITE_APP_NAME=dev-name

.env.prod

NODE_ENV=production
VITE_APP_NAME=prod-name

獲取環境變數

Vite在import.meta.env物件上暴露環境變數。修改 App.tsx,直接列印:

console.log('import.meta.env', import.meta.env)

重啟執行 npm run dev

image.png

TS 提示環境變數

在src目錄下新建env.d.ts,接著按下面這樣增加 ImportMetaEnv 的定義:

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_APP_NAME: string
  // 更多環境變數...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

然後 import.meta.env.VITE_APP_NAME等這些自定義的環境變數就會有提示了

結語

現在 Vite 官方雖然支援了 React,但對於 React 生態來說完整的官方支援還有待完善,所以對於公司 webpack 專案開發環境遷移 Vite 還是持保守態度,待 Vite 繼續發展,後續再慢慢跟進和學習再做升級。

本文專案地址:vite-react-ts-antd-starter

參考文章

相關文章