专栏名称: 前端早读课
我们关注前端,产品体验设计,更关注前端同行的成长。 每天清晨五点早读,四万+同行相伴成长。
目录
相关文章推荐
龙视新闻联播  ·  龙江最美飘雪时|早春升温日 赏冰乐雪时 ·  10 小时前  
宝山消防支队  ·  以案为例 |《油锅起火怎么办?》 ·  14 小时前  
前端早读课  ·  【第3458期】React ... ·  昨天  
51好读  ›  专栏  ›  前端早读课

【第3458期】React 团队宣布停止维护 Create React App

前端早读课  · 公众号  · 前端  · 2025-02-19 08:00

正文

前言

React 团队宣布停止维护 Create React App,并鼓励现有应用迁移到框架或构建工具。今日前端早读课文章由 @Matt Carroll 和 Ricky Hanlon分享, 公号:前端圈授权。

译文从这开始~~

今天,我们不再推荐使用 Create React App 来创建新应用,并建议现有的应用迁移到框架,或者迁移到像 Vite、Parcel 或 RSBuild 这样的构建工具。

我们还提供了文档,帮助那些不适合使用框架的项目,或者更倾向于从头构建框架的开发者。

2016 年,我们发布 Create React App 时,业界还没有一个清晰的构建 React 应用的方法。

要创建一个 React 应用,你必须安装一堆工具并自己将它们连接在一起,以支持 JSX、代码检查(linting)和热重载等基本功能。要正确完成这些工作非常棘手,因此社区为常见的配置创建了样板代码(boilerplates)。然而,样板代码很难更新,而且碎片化使得 React 难以发布新功能。

Create React App 通过将多个工具组合成一个推荐配置来解决这些问题。这使得应用能够轻松地升级到新的工具特性,并让 React 团队能够将重要的工具改进(如 Fast Refresh 支持、React Hooks 代码检查规则)推广给尽可能广泛的用户。

这种模式变得如此流行,以至于现在有一整类工具都采用这种方式工作。

停用 Create React App

尽管 Create React App 让入门变得容易,但它有一些限制,使得构建高性能的生产应用变得困难。理论上,我们可以通过将其发展成一个框架来解决这些问题。

然而,由于 Create React App 目前没有活跃的维护者,而且已经有许多现有的框架可以解决这些问题,我们决定逐步淘汰 Create React App。

从今天开始,如果你安装一个新应用,你会看到一个弃用警告:

图片

create-react-app 已被弃用。
您可以在 react.dev 上找到最新的 React 框架列表。
更多信息,请参阅:react.dev/link/cra
此错误消息每次安装只显示一次。

如何迁移到框架

我们建议使用框架来创建新的 React 应用。我们推荐的所有框架都支持纯客户端 SPA(单页应用),并且可以部署到 CDN 或静态托管服务,无需服务器。

对于现有应用,以下指南将帮助你迁移到纯客户端 SPA:

  • Next.js 的 Create React App 迁移指南

  • React Router 的框架采用指南

  • Expo Webpack 迁移到 Expo Router 的指南

Create React App 将继续以维护模式运行,我们已发布了与 React 19 兼容的新版本。

如何迁移到构建工具

如果你的应用有特殊限制,或者你更喜欢通过构建自己的框架来解决这些问题,或者你只是想从头开始学习 React 如何工作,你可以使用 Vite 或 Parcel 自定义 React 设置。

为了帮助用户上手 Vite 或 Parcel,我们发布了关于《构建框架》的新文档。继续阅读以了解更多关于 Create React App 的局限性以及为什么我们推荐使用框架。

  • 构建框架:https://react.dev/learn/building-a-react-framework

  • 局限性:https://react.dev/blog/2025/02/14/sunsetting-create-react-app#limitations-of-create-react-app

  • 为什么我们推荐使用框架:https://react.dev/blog/2025/02/14/sunsetting-create-react-app#why-we-recommend-frameworks

注意

你们是否推荐 Vite?

我们提供了几项基于 Vite 的推荐。

React Router v7 是一个基于 Vite 的框架,它允许你使用 Vite 的快速开发服务器和构建工具,同时提供路由和数据获取功能。正如我们推荐的其他框架一样,你可以使用 React Router v7 构建单页应用(SPA)。

我们还建议在将 React 添加到现有项目或构建框架时使用 Vite。

就像 Svelte 有 Sveltekit、Vue 有 Nuxt、Solid 有 SolidStart 一样,React 推荐在新项目中使用与 Vite 等构建工具集成的框架来开展新项目。

Create React App 的局限性

Create React App 和类似的构建工具让开始构建 React 应用变得容易。运行 npx create-react-app my-app 后,你就能得到一个完全配置好的 React 应用,包含开发服务器、代码检查和生产环境构
建。

例如,如果你正在构建一个内部管理工具,你可以从一个简单的页面开始:

 export default function App() {
return (
<div>
<h1>Welcome to the Admin Tool!</h1>
</div>
)
}

这使你能够立即开始使用 React 编码,具备 JSX、默认代码检查规则以及可在开发和生产环境中运行的打包工具等功能。然而,这种设置缺少构建真正的生产应用所需的工具。

大多数生产应用都需要解决诸如路由、数据获取和代码分割等问题。

路由(Routing)

Create React App 不包含特定的路由解决方案。如果你刚刚入口,一种选择是使用 useState 在状态中切换路由。但这样做意味着你无法分享应用中的链接 - 每个链接都会指向同一个页面 - 而且随着时间推移,应用的结构会变得越来越难以管理:

 import {useState} from 'react';

import Home from './Home';
import Dashboard from './Dashboard';

export default function App() {
// ❌ Routing in state does not create URLs
const [route, setRoute] = useState('home');
return (
<div>
{route === 'home' && <Home />}
{route === 'dashboard' && <Dashboard />}
</div>
)
}

这就是为什么大多数使用 Create React App 的应用都通过添加像 React Router 或 Tanstack Router 这样的路由库来解决路由问题的原因。使用路由库后,你可以为应用添加额外的路由,这不仅提供了有关应用结构的规范,并允许你开始分享路由链接。例如,使用 React Router 可以定义路由:

 import {RouterProvider, createBrowserRouter} from 'react-router';

import Home from './Home';
import Dashboard from './Dashboard';

// ✅ Each route has it's own URL
const router = createBrowserRouter([
{path: '/', element: <Home />},
{path: '/dashboard', element: <Dashboard />}
]);

export default function App() {
return (
<RouterProvider value={router} />
)
}

通过此更改,您可以共享指向 /dashboard 的链接,应用将导航到仪表板页面。拥有路由库后,你可以添加其他功能,如嵌套路由、路由守卫和路由过渡,这些功能在没有路由库的情况下很难实现。
这里有一个权衡:路由库增加了应用的复杂性,但也提供了难以自行实现的功能。

数据获取(Data Fetching)

Create React App 的另一个常见问题是数据获取。Create React App 并未包含特定的数据获取解决方案。如果你刚刚入门,一个常见的选择是在 useEffect 中使用 fetch 来加载数据。

但这样做意味着数据会在组件渲染后才被获取,这可能会导致网络瀑布流(network waterfalls)。网络瀑布流是由于在应用渲染时而不是在代码下载的同时并行获取数据造成的:

 export default function Dashboard() {
const [data, setData] = useState(null);

// ❌ Fetching data in a component causes network waterfalls
useEffect(() => {
fetch('/api/data')
.then(response => response.json())
.then(data => setData(data));
}, []);

return (
<div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}

在 useEffect 中获取数据意味着用户需要等待更长时间才能看到内容,即使数据本可以在更早的时候获取。为了解决这个问题,你可以使用像 React Query、SWR、Apollo 或 Relay 这样的数据获取库,它们提供了预获取数据的选项,以便在组件渲染之前就开始请求。

这些库在与路由的 "加载器" 模式集成时效果最好,可以在路由级别指定数据依赖,从而让路由器优化数据获取:

 export async function loader() {
const response = await fetch(`/api/data`);
const data = await response.json();
return data;
}

// ✅ Fetching data in parallel while the code is downloading
export default function Dashboard({loaderData}) {
return (
<div>
{loaderData.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}

在初次加载时,路由器可以在路由渲染之前立即获取数据。当用户在应用中导航时,路由器能够同时获取数据和路由,实现并行获取。这减少了用户看到内容所需的时间,并能改善用户体验。
然而,这需要正确配置应用中的加载器,并在复杂性和性能之间做出权衡。

代码拆分(Code Splitting)

Create React App 的另一个常见问题是代码拆分。Create React App 没有包含特定的代码分割解决方案。如果你刚刚入门,你可能根本不会考虑代码拆分。

这意味着你的应用会被打包成一个单一的文件:

 - bundle.js    75kb

但为了达到理想的性能,你应该将代码 "拆分" 成多个文件,这样用户只需要下载他们需要的部分。通过只下载用户查看当前页面所需的代码,这减少了用户加载应用所需等待的时间。

 - core.js      25kb
- home.js 25kb
- dashboard.js 25kb

实现代码拆分的一种方式是使用 React.lazy。然而,这意味着代码直到组件渲染时才会被获取,这可能会导致网络瀑布流。一个更优的解决方案是使用路由器功能,在代码下载的同时并行获取代码。例如,React Router 提供了一个 lazy 选项,用于指定路由应该进行代码拆分并优化其加载时机:

 import Home from './Home';
import Dashboard from './Dashboard';

// ✅ Routes are downloaded before rendering
const router = createBrowserRouter([
{path: '/', lazy: () => import('./Home')},
{path: '/dashboard', lazy: () => import('Dashboard')}
]);

优化代码拆分很难做到完美,并且很容易犯错误,导致用户下载比实际需要更多的代码。它在与路由器和数据加载解决方案集成时效果最佳,可以最大化缓存,并行化获取,并支持 “交互时导入” 模式。







请到「今天看啥」查看全文