練練手吧! TS + React 小項目(01 建立項目)

有兩種通用初始化方案

咱們能夠經過兩種方式建立項目:手動配置和使用腳手架;手動配置爲了對項目的配置有一個基本瞭解,以後的開發仍是 基於腳手架開展css

手動配置

建立 基本的 ts 環境

安裝 react 及其聲明文件

npm i react react-dom
複製代碼
npm i -D @types/react @types/react-dom
複製代碼

修改配置項

TypeScript 具備三種 JSX 模式:preservereactreact-native。 這些模式只在代碼生成階段起做用 - 類型檢查並不受影響。html

  • preserve 模式下生成代碼中會保留 JSX 以供後續的轉換操做使用(好比:Babel)。 另外,輸出文件會帶有 .jsx 擴展名。
  • react 模式會生成 React.createElement,在使用前不須要再進行轉換操做了,輸出文件的擴展名爲.js
  • react-native 至關於 preserve,它也保留了全部的 JSX,可是輸出文件的擴展名是.js
模式 輸入 輸出 輸出文件擴展名
preserve <div /> <div /> .jsx
react <div /> React.createElement("div") .js
react-native <div /> <div /> .js
// tsconfig.json
{
  "compilerOptions": {
    "jsx": "react"
  }
}
複製代碼

修改入口文件配置

src/index.ts 修改文件拓展名 src/index.tsxnode

// webpack.base.config.js
module.exports = {
  entry: "./src/index.tsx",
  ...
};
複製代碼
// package.json
{
  ...
  "main": "./src/index.tsx"
}
複製代碼

調試一下,看看行不行

// src/components/demo/Hello.tsx

import React from "react";

interface Greeting {
  name: string;
}

const Hello = (props: Greeting) => <h1>hello {props.name}</h1>;

export default Hello;
複製代碼
// src/index.tsx

import React from "react";
import ReactDOM from "react-dom";
import Hello from "./components/demo/Hello";

ReactDOM.render(
  <Hello name="typescript" />,
  document.querySelectorAll(".app")[0]
);
複製代碼

npm start 後,在 http://localhost:8080/ 能夠看到 hello typescript 就 ok 。react

優化 webpack 打包

由於 react 庫體積是很大的,通常狀況將庫文件和業務文件拆分爲兩個文件,從而充分利用瀏覽器的緩存。webpack

修改一下 webpack 配置:ios

// webpack.base.config.js
module.exports = {
  // 爲入口文件單獨提供一個名稱
  entry: {
    app: "./src/index.tsx",
  },
  // 修改輸出文件名,[文件名].[8位哈希: 爲了防緩存加的版本號]
  output: { 
    filename: "[name].[chunkhash:8].js" 
    // ...
  },
  ...
  optimization: {
    // webpack4 提供了新的拆包方式
    splitChunks: {
      // 默認抽離出 node_modules 打包成單獨文件
      chunks: "all",
    },
  },
};
複製代碼

npm run build 後,獲得 dist(生產環境下):git

// mode=production
--dist
  |--935.e5091ef8.js // 庫代碼
  |--935.e5091ef8.js.LICENSE.txt // 註釋
  |--app.ec1f4b01.js // 業務代碼
  |--index.html
複製代碼

--mode=development--mode=production 生成結果會不同。web

Webpack 5 默認壓縮代碼工具爲 terser-webpack-plugin,無需安裝,默認使用,會將註釋提取到單獨的 LICENSE 文件中。不想要 LICENSE 文件的 戳 這個配置ajax

使用腳手架

一行命令定乾坤

npx create-react-app ts-react-app --template typescript
複製代碼

解讀命令:基於 typescript 建立一個叫 ts-react-appreact 工程。typescript

PS: 不少文章裏寫到這命令npx create-react-app xxx --typescript,如今已經失效了,但用它的建立過程並不會報錯,併成果建立一個不包含 Typescript 的默認 React 工程。--template typescript 是新的有效參數。

npx 只是安裝到臨時目錄,使用完後自動刪除;這樣能夠避免全局安裝,每次使用( create-react-app 腳手架)都是最新的版本。

Create React App 是一個官方支持的建立 React 單頁應用程序的方法,它提供了一個零配置的現代構建設置。

目錄結構

對工程按咱們的需求進行一下改造:

|--public // 該目錄下的內容 會被拷貝到 最終生成的項目的 根目錄下
    |--index.html // 首頁模版,全部構建後的腳本都會被注入到這裏(必需)
    |--favicon.ico // 靜態文件(圖標、字體..),對靜態文件的引用方式:如 href="%PUBLIC_URL%/favicon.ico"
|--src // 項目源碼
    |--components
        |--demo
            |--Hello.tsx
    |--index.tsx // 整個工程的入口文件
    |--react-app-env.d.ts
|--.gitignore
|--config-overrides.js
|--package.json
|--README.md
|--tsconfig.json
|--yarn.lock
複製代碼

咱們在 package.json 中並看不到 WebpackBabel 等工具。 其實它們是預先配置好而且隱藏的,它們都被封裝到了 react-scripts 中。

咱們要加裝的包

// package.json
{
  ...
  // 替換腳本 react-scripts -> react-app-rewired
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test"
  },

  "dependencies": {
    ...
    "antd": "^4.15.3", // UI 組件庫
    "axios": "^0.21.1", // 發送 ajax 請求
    "react-router-dom": "^5.2.0" // 路由
  },

  "devDependencies": {
    "@types/react-router-dom": "^5.1.7",
    "babel-plugin-import": "^1.13.3", // 實現 antd 的按需加載
    "customize-cra": "^1.0.0", // 看下面
    "http-proxy-middleware": "^1.3.0", // 把請求代理轉發到其餘服務器的中間件
    "http-server": "^0.12.3", // 簡單的零配置命令行http服務器。
    "react-app-rewired": "^2.1.8"
  }
}
複製代碼

若是項目須要單獨配置或者覆蓋原始 webpack 配置,該怎麼辦?

  • 方法一:使用 npm run eject 命令將 webpack.config.js 暴露出來。而後在該配置文件中進行修改。但這是極端且不推薦的,緣由有二:
    • 該命令是不可逆的。一旦執行了此命令 webpack.config.js 文件就永久的暴露出來。
    • 若是隻是修改一個很小的配置項。是否是有點大動干戈了?
  • 方法二(推薦):利用 customize-crareact-app-rewired 經過 config-overrides.js 文件覆蓋原配置項。

如何搭建一個 mock-server ?

http-proxy-middleware 是把請求代理轉發到其餘服務器的中間件。http-server 是簡單的零配置命令行 http 服務器。它能夠幫助咱們開啓本地服務器,方便局域網共享。這二者配合能夠搭建一個 mock-server

覆蓋原配置項

// config-overrides.js

const { override, fixBabelImports } = require("customize-cra");

module.exports = override(
  fixBabelImports("import", {
    // antd 按需加載
    libraryName: "antd",
    libraryDirectory: "es",
    style: "css",
  })
);
複製代碼

src/components/demo/Hello.ts

import React from "react";
import { Button } from "antd";

interface Greeting {
  name: string;
}

const Hello = (props: Greeting) => <Button>hello {props.name}</Button>;

export default Hello;
複製代碼

src/index.tsx

import React from "react";
import ReactDOM from "react-dom";
import Hello from "./components/demo/Hello";

ReactDOM.render(
  <Hello name="typescript。" />,
  document.querySelectorAll(".app")[0]
);
複製代碼

首頁模版

  • public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>TypeScript In Action</title>
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" type="image/x-icon" />
  </head>
  <body>
    <div class="app"></div>
  </body>
</html>
複製代碼

it's ok!

yarn start
複製代碼

ts-react.png

React & TS 系列

相關文章
相關標籤/搜索