從零學習React+TS項目搭建(一)

本文主要寫項目創(chuàng)建到項目開發(fā)環(huán)境配置,里面包含有 react + ts + ant-design+sass/scss+redux +Eslint + Prettier

項目創(chuàng)建

# 項目創(chuàng)建
npx create-react-app react-app
# ts項目創(chuàng)建
npx create-react-app react-ts-app --template typescript

安裝依賴

安裝ant-design前端架構+sass/scss

npm i sass scss antd --save

安裝完成后仆潮,將src目錄中css文件改為scss

App.css > App.scss
index.css > index.scss

相應代碼中import依賴也需要調整。

安裝react-app-rewired仿野、customize-cra插件

npm i react-app-rewired customize-cra --save-dev

配置package.json 替換腳本命令

{
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test"
  }
  ...
}

根目錄創(chuàng)建config-overrides.js文件羊瘩,配置 webpack @ 指向 src 路徑

const {
  override,
  addWebpackAlias
} = require('customize-cra')

const path = require('path')

module.exports =  override(
  addWebpackAlias({
    '@': path.resolve(__dirname, 'src')
  })
)

需要ts環(huán)境生效@寫法需要在根目錄下創(chuàng)建tsconfig.extend.json文件沦零。

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

然后在tsconfig.json中添加映射

{
  "extends": "./tsconfig.extend.json",
  "compilerOptions": {
      ...
   }
}

安裝 Redux

npm i @reduxjs/toolkit react-redux   

需要在src目錄添加以下文件&文件夾

src
├─ app
│  └─ store.ts
├─ features
│  ├─ counter
│  │  └─ counterSlice.ts

store.ts

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "@/features/counter/counterSlice";

export default configureStore({
  reducer: {
    // 可以添加更多模塊
    counter: counterReducer,
  },
});

實例代碼 counterSlice.ts

import { createSlice } from '@reduxjs/toolkit';

export interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0
};

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      // Redux Toolkit 允許我們在 reducers 寫 "可變" 邏輯餐曼。
      // 并不是真正的改變 state 因為它使用了 immer 庫
      // 當 immer 檢測到 "draft state" 改變時,會基于這些改變去創(chuàng)建一個新的
      // 不可變的 state
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    }
  }
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export default counterSlice.reducer;

src/index.ts里添加全局配置store

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.scss';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from "react-redux";
import store from "./app/store"

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

使用Eslint + Prettier 作為代碼檢查自動格式化

vscode需要安裝 Eslint + Prettier插件
安裝依賴

npm i eslint@7.32.0 @typescript-eslint/eslint-plugin@5.0.0 @typescript-eslint/parser@5.0.0 @eslint/js@9.0.0 globals@15.0.0 --save-dev
npm i eslint-config-prettier eslint-plugin-prettier prettier --save-dev

在根目錄新建以下文件

├─ .vscode
│  └─  settings.json
├─ .eslintignore
├─ .eslintrc.js
├─ prettier.config.js

setting.json

{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

.eslintignore

# .eslintignore
build/
dist/
node_modules/

.eslintrc.js

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react/recommended'
  ],
  settings: {
    react: {
      version: '999.999.999' //消除npm run lint時的警告信息
    }
  },
  overrides: [
    {
      env: {
        node: true
      },
      files: ['.eslintrc.{js,cjs}'],
      parserOptions: {
        sourceType: 'script'
      }
    }
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  plugins: ['@typescript-eslint', 'react'],
  rules: {
    'no-unused-vars': 'off',
    '@typescript-eslint/no-var-requires': 0,
    '@typescript-eslint/no-unused-vars': 'off',
    '@typescript-eslint/no-explicit-any': ['off']
  }
};

prettier.config.js

// prettier.config.js
module.exports = {
  // 一行最多 100 字符
  printWidth: 100,
  // 使用 2 個空格縮進
  tabWidth: 2,
  // 不使用縮進符德频,而使用空格
  useTabs: false,
  // 行尾需要有分號
  semi: true,
  // 使用單引號
  singleQuote: true,
  // 對象的 key 僅在必要時用引號
  quoteProps: 'as-needed',
  // jsx 不使用單引號苍息,而使用雙引號
  jsxSingleQuote: false,
  // 末尾不需要逗號
  trailingComma: 'none',
  // 大括號內的首尾需要空格
  bracketSpacing: true,
  // jsx 標簽的反尖括號需要換行
  jsxBracketSameLine: false,
  // 箭頭函數(shù),只有一個參數(shù)的時候,也需要括號
  arrowParens: 'always',
  // 每個文件格式化的范圍是文件的全部內容
  rangeStart: 0,
  rangeEnd: Infinity,
  // 不需要寫文件開頭的 @prettier
  requirePragma: false,
  // 不需要自動在文件開頭插入 @prettier
  insertPragma: false,
  // 使用默認的折行標準
  proseWrap: 'preserve',
  // 根據(jù)顯示樣式?jīng)Q定 html 要不要折行
  htmlWhitespaceSensitivity: 'css',
  // 換行符使用 lf
  endOfLine: 'lf'
};

然后重啟vscode即可竞思。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末表谊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盖喷,更是在濱河造成了極大的恐慌爆办,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件课梳,死亡現(xiàn)場離奇詭異距辆,居然都是意外死亡,警方通過查閱死者的電腦和手機暮刃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門跨算,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沾歪,你說我怎么就攤上這事漂彤。” “怎么了灾搏?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵挫望,是天一觀的道長。 經(jīng)常有香客問我狂窑,道長媳板,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任泉哈,我火速辦了婚禮蛉幸,結果婚禮上,老公的妹妹穿的比我還像新娘丛晦。我一直安慰自己奕纫,他們只是感情好,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布烫沙。 她就那樣靜靜地躺著匹层,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锌蓄。 梳的紋絲不亂的頭發(fā)上升筏,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音瘸爽,去河邊找鬼您访。 笑死,一個胖子當著我的面吹牛剪决,可吹牛的內容都是我干的灵汪。 我是一名探鬼主播檀训,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼识虚!你這毒婦竟也來了肢扯?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤担锤,失蹤者是張志新(化名)和其女友劉穎蔚晨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肛循,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡铭腕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了多糠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片累舷。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夹孔,靈堂內的尸體忽然破棺而出被盈,到底是詐尸還是另有隱情,我是刑警寧澤搭伤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布只怎,位于F島的核電站,受9級特大地震影響怜俐,放射性物質發(fā)生泄漏身堡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一拍鲤、第九天 我趴在偏房一處隱蔽的房頂上張望贴谎。 院中可真熱鬧,春花似錦季稳、人聲如沸擅这。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕾哟。三九已至,卻和暖如春莲蜘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帘营。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工票渠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芬迄。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓问顷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杜窄,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內容