这是我参与更文挑战的第4天,活动详情查看: 更文挑战。
第一章:环境搭建
由于前端圈已经被React 18和Vite刷爆了,秉着尝鲜的想法,决定使用React18 + Vite + Typescript开发一个TODO List。
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开发工具,它具有以下特点:
💡 极速的服务启动: 使用原生ESM文件,无需打包!
⚡️ 轻量快速的热重载: 无论应用程序大小如何,都始终极快的模块热重载(HMR)
🛠️ 丰富的功能: 对TypeScript、JSX、CSS等支持开箱即用。
📦 优化的构建: 可选“多页应用”或“库”模式的预配置Rollup构建
🔩 通用的插件: 在开发和构建之间共享Rollup-superset插件接口。
🔑 完全类型化的API: 灵活的API和完整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 = true, ReactDOM.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
大功告成。🎆🎆。又见到我们熟悉的页面:
下一章,我们将使用React18全新API进行开发,记得点赞关注收藏!!!