👀滴! 送你一个开箱即用的 React-admin 开启你的前端工程化之路 🤖

1,902 阅读4分钟

前言

随着工作时长、前端知识的不断增加,我想总结一下自己到底会什么能做些什么。于是我想那就不如从零开始搭建一个完整的项目工程吧,于是就有这些项目:react-admin-tp 模板项目 本项目也适合想要入门工程化搭建的同学🥳

模版项目概览

工程化方面

  • webpack 从零开始配置项目打包
  • eslint 代码检查
  • husky lint-staged 代码提交检查
  • evn 动态环境变量导入
  • ts 使用ts编码
  • less 全局变量注入

项目方面

  • react-router-dom 菜单路由多级配置 动态菜单 懒加载
  • axios 二次封装 简化参数形式
  • mock 请求拦截 模拟数据
  • mobx context 基于mobx响应式 编写全局状态 context分发局部状态
  • antd 使用antd搭建

工程化搭建(基础)

说到工程化那肯定就是 代码编译 代码检查 不同环境打包 CICD 这些啦

首先新建文件夹 初始化项目

 pnpm init
 pnpm i react react-dom core-js

webpack 基础版

安装 webpack 相关依赖

pnpm i webpack webpack-cli webpack-dev-server html-webpack-plugin mini-css-extract-plugin -D

安装react、ts、babel、css相关loader依赖

pnpm i @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/preset-typescript css-loader -D

创建 webpack.config.js

const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const rootDir = __dirname;

const baseConfig = {
  // 入口文件
  entry: path.resolve(rootDir, "./src/main.tsx"),
  // 输出配置
  output: {
    clean: true,
    path: path.resolve(rootDir, "./dist"),
  },
  // sourcemap 调式源码映射
  devtool: false,
  // loader 规则
  module: {
    rules: [
      // 处理 css 文件
      {
        test: /\.(c|le)ss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      // 处理 jsx tsx ts 文件
      {
        test: /\.(t|j)sx?$/, // 比配到相应的文件及执行该 loader
        exclude: /(node_modules|bower_components)/,
        loader: "babel-loader",
        options: {
          presets: [
            [
              "@babel/preset-env",
              {
                targets: "> 0.25%, not dead",
                useBuiltIns: "usage",
                corejs: "3.30.2",
              },
            ],
            [
              "@babel/preset-react",
              {
                runtime: "automatic",
              },
            ],
            ["@babel/preset-typescript", { isTSX: true, allExtensions: true }],
          ],
        },
      },
      // 处理静态资源
      {
        test: /\.(jpe?g|png|svg|gif)/i,
        type: "asset",
      },
    ],
  },
  // 模块解析
  resolve: {
    alias: {
      "@src": path.resolve(rootDir, "./src"),
    },
    extensions: [".ts", ".jsx", ".tsx", "..."], // 自动不全文件后缀
  },
  plugins: [
    new webpack.ProgressPlugin(), // 编译进度
    new HtmlWebpackPlugin({
      title: "webpackApp",
      template: path.resolve(rootDir, "./public/index.html"),
    }), // 生成 indeX.html
    new MiniCssExtractPlugin(), // 抽离 css 文件
  ],
};

module.exports = (_, argv) => {
  console.log("MODE ===>", argv.mode);
  return baseConfig;
};

创建 ./src/main.tsx

import { createRoot } from "react-dom/client";
import styles from './main.module.css'

const dom = document.getElementById("root") as Element;
const root = createRoot(dom);

root.render(
  <div className={styles.container} >
    webpack test_demo
  </div>
);

此时的目录结构是这样的

在 package.json scripts 加入

"build": "webpack -c webpack.config.js --mode=development"

pnpm build

此时应该就可以看到打包输出的产物啦 dist 文件夹内。
以上就是webpack打包react、typescript的基础配置啦!

以上需要注意的就是使用到了 babel 的几个预设 (具体的使用可以看看官网)
core-js 是用来补全浏览器还未支持的特性用的 不使用stage提案或非远古浏览器不用也可

dev-serve

真实开发过程中我们肯定需要一遍开发一遍查看效果,所以还需要加入 dev-server。
将 webpack.config.js 中的导出部分修改为

module.exports = (_, argv) => {
  console.log("MODE ===>", argv.mode);

  if (argv.mode === "development") {
    // mode=development 时添加 devServer 相关配置
    const devServer = {
      historyApiFallback: true,
      open: true,
      port: 8888,
    };
    baseConfig.devServer = devServer;
    baseConfig.plugins.push(new webpack.SourceMapDevToolPlugin({})); // 添加 SourceMapD 此插件可替代 devtool
  }

  return baseConfig;
};

在 package.json scripts 加入

"start": "webpack serve -c webpack.config.js --mode=development"
运行 pnpm start 即可开到开发页面啦🥳

到这里 webapack 相关的基础配置就结束了。

Eslint Ts format

开发和打包弄好了,该优化一下我们的开发体验啦,刚才的编码过程中Vscode会一直提示的ts、eslint相关的错误一片红这个严重影响我们的开发体验,现在我们来解决他们🥳。

首先安装下依赖

pnpm i eslint eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks -D

安装 ts 相关依赖

pnpm i typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser -D

安装 react 类型声明

pnpm i @types/react @types/react-dom

添加 .eslintrc.js

module.exports = {
  // 以此文件为准 不往上查找 eslint 配置文件
  root: true,
  parser: "@typescript-eslint/parser",
  // 环境
  env: {
    browser: true,
    es2021: true,
    commonjs: true,
  },
  globals: {
    process: "writable",
    __dirname: "readonly",
  },
  // 继承插件特性
  extends: [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react/jsx-runtime",
    "plugin:react-hooks/recommended",
    "plugin:@typescript-eslint/recommended",
  ],
  // 解析选项
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 13,
    sourceType: "module",
  },
  // 共享配置
  settings: {},
  // 插件
  plugins: ["prettier", "react", "@typescript-eslint"],
  // 检查规则
  rules: {
    "prettier/prettier": ["error"],
  },
  // 过滤文件
  ignorePatterns: ["dist", "node_modules", "pnpm-lock", "env"],
};

添加 tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@src/*": ["src/*"]
    }
  },
  "include": ["src", "./index.d.ts"]
}

添加 index.d.ts 样式文件静态资源类型声明

declare module "*.module.scss" {
  const classes: { [key: string]: string };
  export default classes;
}
declare module "*.module.less" {
  const classes: { [key: string]: string };
  export default classes;
}
declare module "*.module.css" {
  const classes: { [key: string]: string };
  export default classes;
}
declare module "*.jpg" {
  const classes: string;
  export default classes;
}
declare module "*.png" {
  const classes: string;
  export default classes;
}
declare module "*.jpeg" {
  const classes: string;
  export default classes;
}
declare module "*.svg" {
  const classes: string;
  export default classes;
}
declare module "*.gif" {
  const classes: string;
  export default classes;
}

此时当我们写的代码不符合规范时就会有错误提示

image.png

注意:最好vscode安装 Eslint、Prettier 这样可以自动fix和format一些问题哦!
当我们配置好后会发现 使用了 commonjs require 导入的文件会提示错误
在使用到 require 的文件顶部加上 /* eslint-disable @typescript-eslint/no-var-requires */ 就可以啦! image.png


好啦,以上内容就是项目工程的基础内容啦!还有一些 husky lint-staged 动态导入环境变量撒的大家有情趣可以看下我的react-admin-tp 模板项目哦~

另外我还写了个脚手架工具方便快速搭建拉取项目 模版项目脚手架 大家可以试试哦🥳🥳

最后祝各位大佬牛气冲天🐮🐮🐮