react+typescript+antd腳手架搭建

reahink發表於2019-03-11

前段時間研究了一下react+typescript開發方式,再加上antd,開發感受還是挺不錯的。本篇文章主要講下在官方推薦的腳手架的基礎上搭建腳手架所遇到的問題。

一開始使用的是create-react-app-typescript腳手架(此方案已廢棄)

npx create-react-app my-app --scripts-version=react-scripts-ts
cd my-app
npm start

# or with yarn
yarn create react-app my-app --scripts-version=react-scripts-ts
cd my-app
yarn start
複製程式碼

不過這個腳手架,作者已經停止更新了,github倉庫上已經歸檔:

This repository has been archived by the owner. It is now read-only.
複製程式碼

由於依賴包webpack-dev-server低版本有漏洞,最好升級到大於3.1.11版本

CVE-2018-14732

Vulnerable versions: < 3.1.11
Patched version: 3.1.11

An issue was discovered in lib/Server.js in webpack-dev-server
before 3.1.11. Attackers are able to steal   developer's
code because the origin of requests is not checked by the
 WebSocket server, which is used for HMR (Hot Module Replacement). 
 Anyone can receive the HMR message sent by the WebSocket 
 server via a ws://127.0.0.1:8080/ connection from any origin.
複製程式碼

但是升級webpack-dev-server後還要涉及到一系列工具鏈包的升級,在原有腳手架上升級及後續的配置修改會很麻煩。然後就使用了下面的方法

新的腳手架:create react app 之Adding TypeScript

1、參考文章地址中的方法生成專案

// 使用此命令將配置分離出來,便於後面修改相關配置
yarn eject
複製程式碼

2、 由於預設的腳手架裡並沒有tslint,如果要使用tslint,需要在根目錄增加tslint.json,然後安裝相關包,並修改相關配置

yarn add tslint tslint-config-prettier tslint-react
複製程式碼
  • tslint.json配置(參考)如下:
{
  "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
  "rules":{
    "no-console":false,
    "no-debugger":false,
    "indent":[true, "spaces", 2], // 縮排
    "no-consecutive-blank-lines": [// 空行不超過兩行
      true,
      2
    ],
    "jsx-no-lambda": false,
    // 檢查物件中鍵的排序
    "object-literal-sort-keys": false,
    // 倒入(import)源的排序規則
    "ordered-imports": true
  },
  "linterOptions": {
    "exclude": [
      "config/**/*.js",
      "node_modules/**/*.ts"
    ]
  }
}
複製程式碼
  • 在paths.js檔案中增加appTsLint: resolveApp("tslint.json")如下:
module.exports = {
  dotenv: resolveApp(".env"),
  appPath: resolveApp("."),
  appBuild: resolveApp("build"),
  appPublic: resolveApp("public"),
  appHtml: resolveApp("public/index.html"),
  appIndexJs: resolveModule(resolveApp, "src/index"),
  appPackageJson: resolveApp("package.json"),
  appSrc: resolveApp("src"),
  appTsConfig: resolveApp("tsconfig.json"),
+ appTsLint: resolveApp("tslint.json"),
  yarnLockFile: resolveApp("yarn.lock"),
  testsSetup: resolveModule(resolveApp, "src/setupTests"),
  proxySetup: resolveApp("src/setupProxy.js"),
  appNodeModules: resolveApp("node_modules"),
  publicUrl: getPublicUrl(resolveApp("package.json")),
  servedPath: getServedPath(resolveApp("package.json"))
};
複製程式碼
  • webpack.config.js修改外掛ForkTsCheckerWebpackPlugin配置,增加tslint: paths.appTsLint,如下:
new ForkTsCheckerWebpackPlugin({
          typescript: resolve.sync("typescript", {
            basedir: paths.appNodeModules
          }),
          async: false,
          checkSyntacticErrors: true,
          tsconfig: paths.appTsConfig,
        + tslint: paths.appTsLint,
          compilerOptions: {
            module: "esnext",
            moduleResolution: "node",
            resolveJsonModule: true,
            isolatedModules: true,
            noEmit: true,
            jsx: "preserve"
          },
          reportFiles: [
            "**",
            "!**/*.json",
            "!**/__tests__/**",
            "!**/?(*.)(spec|test).*",
            "!**/src/setupProxy.*",
            "!**/src/setupTests.*"
          ],
          watch: paths.appSrc,
          silent: true,
          formatter: typescriptFormatter
        })
複製程式碼

tslint結合vscode的使用方法可參考這裡

使用路徑別名

typescript專案的路徑別名不是在webpack中配置的,而是在tsconfig.json中配置的。

如在tsconfig.json增加如下配置:

{
  "compilerOptions": {
 +  "baseUrl": ".",
 +  "paths": {
 +    "@/*": ["src/*"]
 +  },
    ...
  },
  ...
}
複製程式碼

index.tsx中使用:

import App from "@/App";
複製程式碼

此時啟動專案

yarn start
複製程式碼

出現以下編譯報錯:

Failed to compile.

./src/index.tsx
Module not found: Can't resolve '@/App' in 'dir/dir/src'
複製程式碼

解決編譯報錯

yarn add tsconfig-paths-webpack-plugin
複製程式碼

修改webpack.config.js檔案

+ const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
...

alias: {
        // Support React Native Web
        // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
        "react-native": "react-native-web"
      },
      plugins: [
        // Adds support for installing with Plug'n'Play, leading to faster installs and adding
        // guards against forgotten dependencies and such.
        PnpWebpackPlugin,
        // Prevents users from importing files from outside of src/ (or node_modules/).
        // This often causes confusion because we only process files within src/ with babel.
        // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
        // please link the files into your node_modules/ and let module-resolution kick in.
        // Make sure your source files are compiled, as they will not be processed in any way.
        new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
     +  new TsconfigPathsPlugin()
      ]
複製程式碼

使用antd

雖然antd已經有一些成熟的腳手架,但是個人感覺太過冗餘,或者以後修改起來會很麻煩,所以我還是傾向於自己去結合官方腳手架來弄一套自己熟悉的。

yarn add antd
複製程式碼

參考antd官方教程,快速上手,即可快速將antd引入我們的react+typescript專案。

當然為了效能,按需載入還是要做的,安裝babel-plugin-import,並增加相關配置

yarn add babel-plugin-import
複製程式碼

修改webpack.config.js檔案

{
              test: /\.(js|mjs|jsx|ts|tsx)$/,
              include: paths.appSrc,
              loader: require.resolve("babel-loader"),
              options: {
                customize: require.resolve(
                  "babel-preset-react-app/webpack-overrides"
                ),

                plugins: [
                  [
                    require.resolve("babel-plugin-named-asset-import"),
                    {
                      loaderMap: {
                        svg: {
                          ReactComponent: "@svgr/webpack?-svgo![path]"
                        }
                      }
                    }
                  ],
               +  [
               +    "import",
               +    {
               +      libraryName: "antd",
               +      style: "css"
               +    }
               +  ]
                ],
                // This is a feature of `babel-loader` for webpack (not Babel itself).
                // It enables caching results in ./node_modules/.cache/babel-loader/
                // directory for faster rebuilds.
                cacheDirectory: true,
                cacheCompression: isEnvProduction,
                compact: isEnvProduction
              }
            },
            
複製程式碼

至此整個腳手架就搭建完成了!

react-app-antd-ts腳手架

相關文章