React18 + Vite + Typescript開發一個TODO List

這是我參與更文挑戰的第4天,活動詳情查看: 更文挑戰css

第一章:環境搭建

因爲前端圈已經被React 18和Vite刷爆了,秉着嚐鮮的想法,決定使用React18 + Vite + Typescript開發一個TODO List。html

React 18

React在昨天剛剛在官網發佈了有關於React 18的計劃更新(The Plan for React 18 – React Blog),同時發佈了 Alpha 版本的 npm 包。在React 18發佈時,它具備如下特色:前端

  • 將包含開箱即用的改進(如automatic batching)
  • 全新的 API(如startTransition
  • 內置支持了React.lazy的全新SSR架構
  • 可漸進的升級策略。相比於以前要麼不升要麼全升的一刀切方式,只有由新特性觸發的更新會啓用併發渲染.

Vite

vite —— 一個由vue做者尤雨溪開發的web開發工具,它具備如下特色:vue

💡 極速的服務啓動: 使用原生ESM文件,無需打包!node

⚡️ 輕量快速的熱重載: 不管應用程序大小如何,都始終極快的模塊熱重載(HMR)react

🛠️ 豐富的功能: 對TypeScript、JSX、CSS等支持開箱即用。git

📦 優化的構建: 可選「多頁應用」或「庫」模式的預配置Rollup構建github

🔩 通用的插件: 在開發和構建之間共享Rollup-superset插件接口。web

🔑 徹底類型化的API: 靈活的API和完整TypeScript類型。typescript

解決了使用JavaScript開發的工具一般須要很長時間(甚至是幾分鐘!)才能啓動開發服務器,即便使用HMR,文件修改後的效果也須要幾秒鐘才能在瀏覽器中反映出來的問題。

新建項目

vite初始化

先用Vite初始化一個項目。文檔傳送門

# npm 6.x
npm init @vitejs/app todo-list --template react-ts

# npm 7+, 須要額外的雙橫線:
npm init @vitejs/app todo-list -- --template react-ts

# yarn
yarn create @vitejs/app todo-list --template react-ts
複製代碼

安裝依賴

# yarn
yarn
# npm
npm install
複製代碼

更新react版本

因爲package.json裏面內置react版本是17.0.2,因此咱們須要安裝alpha版本

# yarn
yarn add react@alpha react-dom@alpha
# npm 
npm i react@alpha react-dom@alpha -S
複製代碼

更新vite.config.js

使用ESBuild幫咱們自動注入JSX的轉換函數,可是須要注意的是,這裏依舊採用的React.createElement的功能,而不是React 17 jsx。若是你想要React 17的新功能,你須要配置一個ESbuild插件來幫忙解決這個問題,詳細能夠能夠看這個issue

export default defineConfig({
  plugins: [reactRefresh()],
  esbuild: {
    jsxInject: `import React from 'react'`
  }
})
複製代碼

因爲咱們沒有手動的導入React,因此咱們須要讓typescript知道。因此咱們同時須要修改tsconfig.json:

{
    compilerOptions: {
        ...,
        "jsx": "react-jsx",
    }
}
複製代碼

修改main.tsx

import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<App />);
複製代碼

修改App.jsx

import { useState } from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>Hello Vite + React!</p>
        <p>
          <button type="button" onClick={() => setCount((count) => count + 1)}>
            count is: {count}
          </button>
        </p>
      </header>
    </div>
  );
}
export default App;
複製代碼

這時候咱們執行yarn dev

yarn dev
複製代碼

突然發現報了這樣的錯誤:Property 'createRoot' does not exist on type 'typeof import("/code/my-app/node_modules/@types/react-dom/index")'. TS2339。這事由於現有的@types/react,@types/react-dom裏面沒有定義createRoot API,因此Typescript編譯器不知道什麼是createRoot,這時候須要升級@types/react,@types/react-dom

Typescript識別新API

升級@types/react,@types/react-dom,若是出現選擇選擇,選擇最高版本便可。

yarn add @types/react @types/react-dom
複製代碼

咱們從看@types添加了api支持的PR,咱們會找到一些提示。

/** * These are types for things that are present in the upcoming React 18 release. * * Once React 18 is released they can just be moved to the main index file. * * To load the types declared here in an actual project, there are three ways. The easiest one, * if your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section, * is to add `"react/next"` to the `"types"` array. * * Alternatively, a specific import syntax can to be used from a typescript file. * This module does not exist in reality, which is why the {} is important: * * ```ts * import {} from 'react/next' * ``` * * It is also possible to include it through a triple-slash reference: * * ```ts * /// <reference types="react/next" /> * ``` * * Either the import or the reference only needs to appear once, anywhere in the project. */
複製代碼

因此咱們須要編輯tsconfig.json,並要在compilerOptions下面添加一個選項:

{
    compilerOptions: {
        ...,
        "types": ["react/next", "react-dom/next", "src/types", "node_modules/@types"]
    }
}
複製代碼

咱們再次執行yarn dev

yarn dev
複製代碼

這時候又會發現這樣一個錯誤:Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Document | DocumentFragment | Comment'. Type 'null' is not assignable to type 'Element | Document | DocumentFragment | Comment'. TS2345。緣由是tsconfig中設置compilerOptions.strict = trueReactDOM.createRoot(rootElement)並不能保證返回的值非null,因此咱們再次修改main.tsx文件。

再次修改main.tsx

import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
const rootElement = document.getElementById("root");
if (!rootElement) throw new Error("Failed to find the root element");
const root = ReactDOM.createRoot(rootElement);
root.render(<App />);
複製代碼

咱們再次執行yarn dev

yarn dev
複製代碼

大功告成。🎆🎆。又見到咱們熟悉的頁面:

image.png 下一章,咱們將使用React18全新API進行開發,記得點贊關注收藏!!!

相關文章
相關標籤/搜索