react+ts白手起家建个属于自己的项目(二 应用篇)

405 阅读3分钟

目标

目前想到什么就弄什么
路由、antd、less、代码规范

1、配置路由

使用react-router-dom

    npm i react-router-dom
    npm i @types/react-router-dom -D

tip: 关于@types都放到dev环境下,在练手篇可能有误

官方文档 reactrouter.com/web/guides/… 项目目录

image.png

app.jsx代码

import { Home } from 'component/home';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import './style/index.less'

const Routers = () => {
  return (
    <>
      <BrowserRouter>
        <Switch>
          <Route path="/" exact={true} component={Home}/>
          <Route render={() => <Redirect to="/404" />} />
        </Switch>
      </BrowserRouter>
    </>
  )
}

ReactDOM.render(<Routers />, document.getElementById("root"));

home.jsx代码

import { Tag } from "antd";
import React from "react";
import { Link } from "react-router-dom";

export const Home = () => {
  const hrefList = [
    {
      href: '/page1',
      name: '页面1',
    },
    {
      href: '/page2',
      name: '页面2',
    }
  ];

  const getColor = () => {
    let color = '#';
    for (var i = 0; i < 6; i++) color += parseInt(Math.random() * 16 + '').toString(16);
    return color;
  };

  return (
    <div className="test-css">
      <h1 className="test-css-home">首页</h1>
      {hrefList.map((item, index) => {
        return (
          <Link key={index} to={item.href}>
            <Tag color={getColor()}>{item.name}</Tag>
          </Link>
        );
      })}
    </ div>
  );
}

2、引入antd

    npm i antd

暂时在全局下引入样式

3、配置less

方法一(style-loader)

    npm i less less-loader css-loader style-loader -D

配置

//webpack.config
      {
        test: /\.less$/i,
        include: path.resolve(__dirname, "./src"),
        // style-loader从 JS 中创建样式节点 css-loader转化 CSS 为 CommonJS  less-loader编译 Less 为 CSS
        use: ["style-loader", "css-loader", "less-loader"],
      },

方法二(mini-css-extract-plugin)

npm install --save-dev mini-css-extract-plugin

配置

  plugins: [
    new MiniCssExtractPlugin(),
  ],
//webpack.config
      {
        test: /\.less$/i,
        include: path.resolve(__dirname, "./src"),
        use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
      },

区别

style-loader:把js中import导入的样式文件打包到js文件中,运行js文件时,将样式自动插入到标签中。没有css文件。 打包如图:

image.png mini-css-extract-plugin:把js中import导入的样式文件,单独打包成一个css文件,结合html-webpack-plugin,以link的形式插入到html文件中。 打包如图:

image.png

配置完重新运行

image.png

4、关于Ts引用模块问题

模块解析规则 => juejin.cn/post/699030…

在ts中,想以下引用模块必须配置tsconfig.json的路径解析

import { Home } from 'component/home';

未配置前

image.png 配置后,报错将消失

// tsconfig.json
    "baseUrl": ".",
    "paths": {
      "*": ["src/*"],
    },

tip: 详细配置,移步 www.tslang.cn/docs/handbo…

配置别名

重新npm start还会报错,找不到模块,原因是node打包时候找不到模块,需要在webpack.config.js配置别名

// webpack.config.js
  resolve: {
    alias: {
      type: path.resolve(__dirname, "src/@type/"),
      component: path.resolve(__dirname, "src/component/"),
    }, // 别名
    extensions: [".tsx", ".ts", ".js"], //解析顺序
  },

5、加入代码规范

eslint + prettier实现自动保存格式化

// package.json
    "eslint": "7.30.0",
    "eslint-config-prettier": "8.3.0",
    "eslint-plugin-import": "^2.0.0",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-prettier": "3.4.0",
    "eslint-plugin-react": "7.22.0",
    "eslint-plugin-react-hooks": "4.2.0",
    "prettier": "2.3.2",

安装以上依赖

配置.prettierrc.js

// .prettierrc.js
module.exports = {
  printWidth: 140, // 指定代码长度,超出换行
  tabWidth: 2, // tab 键的宽度
  semi: true, // 结尾加上分号
  singleQuote: true,
  trailingComma: 'es5', // 确保对象的最后一个属性后有逗号
  bracketSpacing: true, // 大括号有空格 { name: 'rose' }
  insertPragma: false, // 是否在格式化的文件顶部插入Pragma标记,以表明该文件被prettier格式化过了
  htmlWhitespaceSensitivity: 'ignore', // html文件的空格敏感度,控制空格是否影响布局
};

配置.eslintrc.js

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    node: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended', // 如果同时使用了eslint和prettier发生冲突了,会关闭掉与prettier有冲突的规则,也就是使用prettier认为对的规则
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'react',
    '@typescript-eslint',
    'prettier', // eslint 会使用pretter的规则对代码格式化
  ],
  rules: {
    '@typescript-eslint/no-var-requires': 0,
    'prettier/prettier': 2, // 这项配置 对于不符合prettier规范的写法,eslint会提示报错
    'no-console': 1,
  },
};

配置忽略

// .eslintignore
dist

集成开发工具

在VsCode商店安装eslint和prettier

配置vscode settings.json文件

image.png

//settings.json
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "eslint.options": {
    "eslint.autoFixOnSave": true,
    "extensions": [
      ".js",
      ".vue",
      ".ts",
      ".tsx"
    ],
    // An array of language ids which should be validated by ESLint
    "eslint.validate": [
      "javascript",
      // jsx
      "javascriptreact",
      // vue
      {
        "language": "vue",
        "autoFix": true
      },
      // ts
      {
        "language": "typescript",
        "autoFix": true
      },
      // tsx
      {
        "language": "typescriptreact",
        "autoFix": true
      },
      "html"
    ],
    "eslint.alwaysShowStatus": true,
  },
  "eslint.codeAction.showDocumentation": {
    "enable": true
  },

我的完整配置

{
  "editor.suggestSelection": "first",
  "editor.fontSize": 15,
  "editor.tabSize": 2,
  "editor.detectIndentation": false,
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  "[javascript|react]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript|react]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[less]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "eslint.run": "onType",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "eslint.options": {
    "eslint.autoFixOnSave": true,
    "extensions": [
      ".js",
      ".vue",
      ".ts",
      ".tsx"
    ],
    // An array of language ids which should be validated by ESLint
    "eslint.validate": [
      "javascript",
      // jsx
      "javascriptreact",
      // vue
      {
        "language": "vue",
        "autoFix": true
      },
      // ts
      {
        "language": "typescript",
        "autoFix": true
      },
      // tsx
      {
        "language": "typescriptreact",
        "autoFix": true
      },
      "html"
    ],
    "eslint.alwaysShowStatus": true,
  },
  "eslint.codeAction.showDocumentation": {
    "enable": true
  },
  "typescript.updateImportsOnFileMove.enabled": "always",
  "explorer.confirmDelete": false,
  "diffEditor.ignoreTrimWhitespace": false,
  "workbench.statusBar.visible": true,
  "javascript.updateImportsOnFileMove.enabled": "always",
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "window.zoomLevel": -1,
}

重启下配置就可生效,如不生效试下shift + alt + f 选择prettier配置

6、参考文献

prettier

eslint

react-router-dom

git仓库 github.com/dengruifeng…