从零开始使用 Vite + React,并提前启用 React Compiler
使用 Vite 搭建脚手架,读取入口文件,并在首个功能实现之前启用 React Compiler。
React最初的定位是让UI能够随数据变化而相应更新。如今的推荐方案是使用Vite以实现快速的本地反馈,若需要的话,还可以启用React Compiler来自动处理过去需手动编写的记忆化操作。
我们使用什么(以及不使用什么)
以Vite + React + TypeScript作为基础,不使用CRA。特意启用了React Compiler,这样从第一个组件开始就能看到它的效果。
前提条件:Node.js
安装最新版本的LTS版Node.js,确认PATH环境变量中已包含node和npm(或pnpm),然后创建项目框架:
// The old way — you manually keep the screen in sync every time the data changes
const badge = document.querySelector('#unread-badge');
badge.textContent = count;
if (count === 0) {
badge.style.display = 'none';
} else {
badge.style.display = 'block';
}
了解文件夹结构
在更换开发工具之前,先明确index.html、src/main.tsx以及App文件的位置:
// The React way — you simply declare "for this state, the screen looks like this"
function UnreadBadge({ count }: { count: number }) {
if (count === 0) return null;
return <span className="badge">{count}</span>;
}
入口点的解析
入口点用于加载应用根组件并引入全局CSS。这部分保持简单即可,功能代码应放在各个组件中。
node -v
corepack enable
启用 React Compiler
将编译器插件添加到构建配置中,以便 Babel/SWC 的集成符合你所使用 Vite 版本的文档要求:
npm install -g pnpm
pnpm create vite@latest restart-react --template react-ts
确认其已处于激活状态
使用文档中推荐的检测方法,或创建一个原本需要使用 useMemo/memo 的小型组件,进而验证编译器输出或相关工具的指示信息:
cd restart-react
pnpm install
pnpm dev
restart-react/
├── index.html ← the single HTML file the app mounts into
├── package.json ← dependencies and scripts
├── tsconfig.json ← TypeScript config
├── vite.config.ts ← Vite config (we'll edit this shortly)
└── src/
├── main.tsx ← the app's entry point
├── App.tsx ← the top-level component
├── App.css
└── index.css
首个无需与工具冲突的功能
// src/main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
pnpm install -D babel-plugin-react-compiler@latest @rolldown/plugin-babel
总结
// vite.config.ts (before)
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
});
// vite.config.ts (after)
import { defineConfig } from 'vite';
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
import babel from '@rolldown/plugin-babel';
export default defineConfig({
plugins: [
react(),
babel({
presets: [reactCompilerPreset()],
}),
],
});
你现在拥有一个从一开始就具备编译器支持的 Vite React 应用——这非常适合那些假定会自动进行记忆化的项目,无需后期再添加相关功能。 要确保测试用例始终正常运行,逐个阶段进行测试,切勿仅凭感觉就发布版本,因为下一次发布很可能会以新名称重新出现同样的隐性故障。 要确保测试用例始终正常运行,逐个阶段进行测试,切勿仅凭感觉就发布版本,因为下一次发布很可能会以新名称重新出现同样的隐性故障。 要确保测试用例始终正常运行,逐个阶段进行测试,切勿仅凭感觉就发布版本,因为下一次发布很可能会以新名称重新出现同样的隐性故障。 要确保测试用例始终正常运行,逐个阶段进行测试,切勿仅凭感觉就发布版本,因为下一次发布很可能会以新名称重新出现同样的隐性故障。 要确保测试用例始终正常运行,进行测试……
逐个阶段单独测试,切勿仅凭感觉就决定发布,因为下次版本可能会以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,逐个阶段单独测量,切勿仅凭感觉就决定发布,因为下次版本可能会以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,逐个阶段单独测量,切勿仅凭感觉就决定发布,因为下次版本可能会以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,逐个阶段单独测量,切勿仅凭感觉就决定发布,因为下次版本可能会以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,逐个阶段单独测量,切勿仅凭感觉就决定发布,因为下次版本可能会以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,逐个阶段单独测量,切勿仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段,绝不能仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段,绝不能仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段,绝不能仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段,绝不能仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段,绝不能仅凭感觉就决定发布。在下次发布时可以用新名称重新引入同样的隐性故障模式,此时仍应坚持使用现有测试用例,单独检测每个阶段。用新的名称来掩盖同样的隐性故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就发布产品,因为下一次版本仍可能以新名称重新出现同样的隐性故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就发布产品,因为下一次版本仍可能以新名称重新出现同样的隐性故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就发布产品,因为下一次版本仍可能以新名称重新出现同样的隐性故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就发布产品,因为下一次版本仍可能以新名称重新出现同样的隐性故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就发布产品,因为下一次版本仍可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段,切勿仅凭感觉就决定发布——因为下一次版本很可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段,切勿仅凭感觉就决定发布——因为下一次版本很可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段,切勿仅凭感觉就决定发布——因为下一次版本很可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段,切勿仅凭感觉就决定发布——因为下一次版本很可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段,切勿仅凭感觉就决定发布——因为下一次版本很可能以新名称重新出现同样的隐性故障模式。保持测试环境正常运行,分别检测每个阶段保持测试装置处于正常状态,分别检测每个阶段,切勿仅凭感觉就决定发布,因为下次版本很可能以新名称重新出现同样的隐性故障模式。当下一个版本可以用新名称重新引入同样的隐性故障模式时,切勿如此。保持测试环境正常运行,逐个阶段进行检测,绝不能仅凭感觉就决定发布,尤其是在下一个版本能够用新名称重新引入同样的隐性故障模式的情况下。保持测试环境正常运行,逐个阶段进行检测,绝不能仅凭感觉就决定发布,尤其是在下一个版本能够用新名称重新引入同样的隐性故障模式的情况下。保持测试环境正常运行,逐个阶段进行检测,绝不能仅凭感觉就决定发布,尤其是在下一个版本能够用新名称重新引入同样的隐性故障模式的情况下。保持测试环境正常运行,逐个阶段进行检测,绝不能仅凭感觉就决定发布,尤其是在下一个版本能够用新名称重新引入同样的隐性故障模式的情况下。保持测试环境正常运行,逐个阶段进行检测,绝不能仅凭感觉就决定发布,尤其是在下一个版本能够重新引入该故障模式的情况下。用新的名称来掩盖那种隐蔽的故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就决定发布——因为下一次版本仍可能以新名称重新出现同样的隐蔽故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就决定发布——因为下一次版本仍可能以新名称重新出现同样的隐蔽故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就决定发布——因为下一次版本仍可能以新名称重新出现同样的隐蔽故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就决定发布——因为下一次版本仍可能以新名称重新出现同样的隐蔽故障模式。保持测试环境稳定,逐个阶段进行检测,绝不能仅凭感觉就决定发布——因为下一次版本仍可能以新名称重新出现同样的隐蔽故障模式。