从零学习React+TS项目搭建(一)

2024-04-17  本文已影响0人  WhoJun

本文主要写项目创建到项目开发环境配置,里面包含有 react + ts + ant-design+sass/scss+redux +Eslint + Prettier

项目创建

# 项目创建
npx create-react-app react-app
# ts项目创建
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-rewiredcustomize-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"
  }
  ...
}

根目录创建config-overrides.js文件,配置 webpack @ 指向 src 路径

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

const path = require('path')

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

需要ts环境生效@写法需要在根目录下创建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" 改变时,会基于这些改变去创建一个新的
      // 不可变的 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,
  // 箭头函数,只有一个参数的时候,也需要括号
  arrowParens: 'always',
  // 每个文件格式化的范围是文件的全部内容
  rangeStart: 0,
  rangeEnd: Infinity,
  // 不需要写文件开头的 @prettier
  requirePragma: false,
  // 不需要自动在文件开头插入 @prettier
  insertPragma: false,
  // 使用默认的折行标准
  proseWrap: 'preserve',
  // 根据显示样式决定 html 要不要折行
  htmlWhitespaceSensitivity: 'css',
  // 换行符使用 lf
  endOfLine: 'lf'
};

然后重启vscode即可。

上一篇下一篇

猜你喜欢

热点阅读