从0到1搭建React+TypeScript+webpack项目【1】

920 阅读3分钟

搭建项目结构

下载脚手架

npm install -g create-react-app

创建一个项目

create-react-app my-app --template typescript

该模版包含了全套正常运行 React 所需的包和配置,无需再额外手动安装 typescript 等,其中还包含了自动化测试文件以及PWA所需文件等,可自行根据需求增删。 创建结束后,项目结构如下:

my-app/
├─ .gitignore
├─ images.d.ts
├─ node_modules/
├─ public/
├─ src/
│  └─ ...
├─ package.json
├─ tsconfig.json

安装eslint

npm install eslint -dev

创建eslint的配置文件

./node_modules/.bin/eslint --init

根据自身情况选择

eslint.png

安装相关包

yarn add eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest eslint-config-standard@latest eslint@^7.12.1 eslint-plugin-import@^2.22.1 eslint-plugin-node@^11.1.0 eslint-plugin-promise@^4.2.1 @typescript-eslint/parser@latest  -D

安装eslint-import-resolver-alias,解决import/unresolver 的报错

yarn add eslint-import-resolver-alias -D

补上一些esliint 官网推荐的扩展和插件及取消掉平常开发用起来很不舒服的一些规则

module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
       
        "plugin:react-hooks/recommended",
        "standard"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint",
        "react-hooks"
    ],
    "rules": {
        "react-hooks/rules-of-hooks": "error",
        "react-hooks/exhaustive-deps": "warn",
        "react/no-unsafe": [
          "error",
          {
            "checkAliases": true
          }
        ],
        "react/self-closing-comp": "warn",
        "react/sort-comp": [
          "error",
          {
            "order": [
              "static-methods",
              "instance-variables",
              "lifecycle",
              "everything-else",
              "rendering"
            ]
          }
        ],
        "react/prop-types": "off",
        "@typescript-eslint/no-useless-constructor": "error",
        "@typescript-eslint/array-type": "error",
        "@typescript-eslint/ban-types": "error",
        "@typescript-eslint/no-array-constructor": "error",
        "@typescript-eslint/naming-convention": [
          "error",
          { "selector": "variable", "format": ["camelCase", "UPPER_CASE","PascalCase"] }
        ],
        "@typescript-eslint/no-use-before-define": "error",
        "getter-return": "off",
        "no-dupe-args": "off",
        "no-dupe-keys": "off",
        "no-unreachable": "off",
        "valid-typeof": "off",
        "no-const-assign": "off",
        "no-new-symbol": "off",
        "no-this-before-super": "off",
        "no-undef": "off",
        "no-dupe-class-members": "off",
        "no-redeclare": "off",
        "no-unused-vars": "off",
        "no-var": "error",
        "no-use-before-define": "off",
        "no-console": "warn",
        "prefer-rest-params": "error",
        "prefer-spread": "error",
        "prefer-const": "error",
        "no-empty-function": "error",
        "eqeqeq": "off",
        "array-callback-return": "warn",
        "default-case": "error",
        "no-shadow": "warn",
        "no-return-await": "error",
        "no-await-in-loop": "error",
        "require-await": "error",
        "generator-star-spacing": ["warn", "after"],
        "yield-star-spacing": ["warn", "after"],
        "spaced-comment": ["warn", "always", { "markers": ["/"] }] ,
        "semi": ["error", "always", { "omitLastInOneLineBlock": true }] ,
    }
};

安装对react-hooks 校验支持的插件eslint-plugin-react-hooks

yarn add eslint-plugin-react-hooks -D

安装 prettier

yarn add  prettier eslint-plugin-prettier eslint-config-prettier -D

配置代码格式的规则

在根目录下面新建一个.prettierrc 的文件:

{
  "trailingComma": "all",
    "tabWidth": 2,
    "semi": true,
    "singleQuote": true,
    "endOfLine": "auto",
    "printWidth": 100,
    "arrowParens": "always",
    "useTabs": false,
    "overrides": [
        {
            "files": "*.md",
            "options": {
                "tabWidth": 2
            }
        }
    ]
}

调整eslintrc.js 里面的插件配置

修改extends、plugins、rules:

module.exports = {

  extends: [..., "prettier"],
  plugins: [..., "prettier"],
  rules: {
     ...,
    "prettier/prettier": "error",
  },
};

安装stylelint

安装相关依赖包

yarn add stylelint stylelint-config-standard stylelint-config-css-modules stylelint-config-rational-order stylelint-config-prettier  -D

yarn add stylelint-order stylelint-scss -D

根目录上新建.stylelintrc.json

{
    "extends": [ "stylelint-config-standard",
      "stylelint-config-css-modules",
      "stylelint-config-rational-order",
      "stylelint-config-prettier"],
    "plugins": ["stylelint-scss","stylelint-order"],
    "rules": {
    "no-descending-specificity": null,
    "at-rule-no-unknown": null
    }
}

安装 husky 和lint-staged

yarn add husky lint-staged -D

在package.json 配置对应的配置

  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "**/*.{scss,less,css}": [
      "stylelint --fix",
      "git add"
    ],
    "src/**/*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "git add"
    ],
    "**/*.{json,ts,tsx,js,jsx,md,scss,less,css,html}": [
      "prettier --write",
      "git add"
    ]
  },

启动项目

yarn start

统一vscode的插件配置

根目录创建.vscode 文件夹

.vscode里创建extensions.json

配置如下

{
  "recommendations": [
   "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "steoates.autoimport",
    "formulahendry.auto-close-tag",
    "formulahendry.auto-rename-tag",
    "clinyong.vscode-css-modules",
    "quicktype.quicktype"
   ]
}

.vscode下面创建settings.json

{
{
  // #每次保存的时候将代码按eslint格式进行修复
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.organizeImports": true
  },
  // 点击保存时,根据 eslint 规则自定修复,同时集成 prettier 到 eslint 中
  "prettier.eslintIntegration": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  // 为了避免和 eslint 冲突,将编辑器默认的代码检查规则关闭(如果开启了)
  "editor.formatOnSave": true,
  // stylelint 扩展自身的校验就够了
  "css.validate": false,
  "less.validate": false,
  "scss.validate": false,
  // 使用本地安装的 TypeScript 替代 VSCode 内置的来提供智能提示
  "typescript.tsdk": "./node_modules/typescript/lib",
  // 指定哪些文件不参与搜索
  "search.exclude": {
    "**/node_modules": true,
    "dist": true,
    "yarn.lock": true
  },
  // 指定哪些文件不被 VSCode 监听,预防启动 VSCode 时扫描的文件太多,导致 CPU 占用过高
  "files.watcherExclude": {
    "**/.git/objects/**": true,
    "**/.git/subtree-cache/**": true,
    "**/node_modules/*/**": true,
    "**/dist/**": true
  },
  "eslint.options": {
    "configFile": "./.eslintrc.js"
  }
}

.vscode 里新建一个xx.code-snippets 的文件

把整个项目里面经常重复的代码配置成代码片段。这样只要敲关键字就能自动生成已经写好的代码。

{
 "ts react function component": {
    "scope": "typescriptreact",  // 语言范围ts
    "prefix": "tsrfc",    //匹配的关键字
    "body": [
      "import React from 'react';",
      "import styles from './${1:${TM_FILENAME_BASE}}.module.scss';",
      "",
      "interface ${1:${TM_FILENAME_BASE}}Props {",
      "  [key: string]: any;",
      "}",
      "",
      "const ${1:${TM_FILENAME_BASE}}: React.FC<${1:${TM_FILENAME_BASE}}Props> = () => {",
      "  return (",
      "    <div className={styles.wrap}>",
      "      ${0}",
      "    </div>",
      "  );",
      "};",
      "",
      "export default ${1:${TM_FILENAME_BASE}};"
    ]
  }
}

现在,在vscode的tsx 文件里面 敲tsrfc,就可以看到效果啦。