当前位置: 首页 > 科技观察

React团队回应建议用Vite代替CreateReactApp

时间:2023-03-17 14:37:08 科技观察

大家好,我是CUGGZ。近日,网友t3dotgg建议将React官方文档中的使用CreateReactApp新建项目的建议替换为使用Vite新建项目的建议。这一建议引起了网友的热议,大多数网友表示赞同:新的React官方文档即将发布(目前显示已经完成99%),Beta文档仍然推荐使用CreateReactApp创建新项目.此外,还提供了两种选择:Vite和Parcel。查看CreateReactApp的Githubrepository,可以发现已经5个月没有更新了,累积了1500+个issues。1月31日,React团队核心成员DanAbramov回应了这个建议,解释了React团队成员对这个建议的权衡,并提供了一些选择。下面就让我们一起来看看详情吧(可以跳到最后看结论)!CreateReactApp的演变当CreateReactApp于2016年发布时,该工具的环境是分散的。如果你想将React添加到现有的应用程序中,你需要添加一个标签和应用程序包。当加载一个空的HTML文件时,浏览器等待React代码和完整的应用程序包下载。这在低带宽连接上可能需要一段时间,并且用户在此期间在屏幕上看不到任何内容。然后,加载应用程序代码。此时用户在屏幕上看到了一些东西——但通常仍然需要加载数据。所以代码发送请求加载数据,用户需要等待它返回。最后加载数据,组件重新渲染数据,用户看到最终结果。这是非常低效的,尽管如果你只在客户端运行React很难做得更好。将此与服务器端框架(如Rails)进行对比:服务器将立即开始数据获取,然后生成包含所有数据的页面。在这种情况下,用户看到的是包含所有信息的HTML文件,而不是等待脚本加载的空白文件。HTML是网络的基石——那么为什么创建一个React应用程序会产生一个空的HTML文件?为什么不利用网络最基本的功能——在所有交互式代码加载之前快速查看内容的能力?为什么要等到所有客户端代码都已加载后再开始加载数据?CreateReactApp只解决了问题的一方面,它提供了良好的开发体验,但它没有强加足够的结构来帮助我们利用网络的力量来获得良好的用户体验。开发者可以尝试自己解决这些问题,但这违背了CreateReactApp的初衷。每个真正高效的React设置都是自定义的、不同的,并且超出了CreateReactApp的范围。这些UX问题并不是CreateReactApp独有的。它们甚至不特定于React。例如,从Preact、Vue、Lit和Svelte的Vite主页模板创建的应用程序都存在同样的问题。这些问题是没有静态站点生成(SSG)或服务器端呈现(SSR)的纯客户端应用程序所固有的。React框架的兴起有些人可能不喜欢完全使用React进行构建。例如,HTML页面可以在服务器端生成,也可以在构建过程中使用不同的工具(如Jekyll或Astro)生成。这解决了空HTML文件的问题,但是两种渲染技术必须混合使用。随着时间的推移,你想要添加的交互性越多,这种技术分裂就会越明显。这种碎片化不仅会损害开发人员的体验——用户体验也会受到影响。使用真正以HTML为中心且未充分利用React的工具,每个页面导航都会变成完整的页面重新加载,清除所有客户端状态。如今,许多用户希望应用程序内的导航顺畅,而不是90年代风格的整页重新加载。此外,许多开发人员更喜欢使用单一渲染模型而不是混合两种不同的模型来构建他们的应用程序。开发人员希望在React中构建整个应用程序。如果您正在使用React构建整个应用程序,那么能够使用SSG/SSR非常重要。CreateReactApp中缺乏对它们的支持。除此之外,经过多年的生态创新,React的许多其他问题现在都有成熟的解决方案。例如,网络瀑布和捆绑包大小。即使应用程序不像面向内容的网站那样受益于SSG或SSR,它也会遭受网络瀑布的影响。如果在挂载时获取数据,第一次数据获取甚至不会开始,直到所有代码加载完毕并呈现组件。这是一个瀑布:如果应用程序知道如何在代码仍在加载时开始获取数据,则可以并行完成。在导航中,如果父子组件都需要获取一些内容,会产生更糟糕的瀑布。当我们谈论React性能时,我们无法回避瀑布是许多应用程序的性能瓶颈这一事实。要解决这些瀑布,您需要将数据获取与路由集成,这是CreateReactApp无法实现的。我们的应用程序代码随着每个新功能和附加依赖项的添加而不断增长。如果频繁部署,应用程序每次使用时加载速度都会变得非常慢,因为它总是需要加载所有代码。有几种方法可以解决这个问题;一些代码可以移动到服务器端或在构建期间运行(如果工具允许的话)。理想情况下也按路由拆分代码。但是,如果您尝试手动进行代码拆分,通常会获得更差的性能。解决这个问题需要把数据抓取和路由打包结合起来,这是CreateReactApp做不到的。React本身只是一个库,它没有规定如何使用路由或数据获取,CreateReactApp也没有规定。不幸的是,这意味着单靠React和最初设计的CreateReactApp都无法解决这些问题。服务器端渲染与静态生成、数据获取、打包和路由相关联。当CreateReactApp发布时,React还很新,如何让这些功能独立工作还有很多需要弄清楚的地方,更不用说如何将它们完美地结合在一起了。时代在进步,现在越来越难推荐不具备这些功能的解决方案。即使您不立即使用它们,它们也应该在您需要时可用,并且您不必迁移到不同的模板并重建所有代码来利用它们。同样,并非所有数据获取或代码拆分都需要基于路由。但这是一个很好的默认值,应该适用于大多数React应用程序。虽然可以自己集成所有这些功能,但很难做好。正如CreateReactApp本身集成了几个与编译相关的功能一样,Next.js、Gatsby和Remix等工具更进一步——将编译与渲染、路由和数据获取集成在一起。这种编译、渲染、路由和数据获取工具被称为“框架”(或者,如果你更喜欢称React为框架,你可以称它们为“元框架”)。这些框架提供了更好的用户体验。作为一种架构的React我们喜欢React的灵活性,您可以使用React构建单个按钮,也可以使用它构建整个应用程序。您可以使用它在一个有20年历史的Perl站点中构建仪表板,或者您可以使用React构建一个混合SSG/SSR电子商务站点。这种灵活性是必不可少的,并且用户喜欢它。React团队还希望为完全使用React构建的新应用程序提供更好的默认设置。如果默认建议的创建React应用程序的方法支持SSG和SSR、自动代码拆分、路由预加载、保留客户端UI状态的导航以及其他可实现出色用户体验的功能,那就太好了。至少,默认建议的创建React应用程序的方法不应该完全排除这些功能,因为现有的仅客户端架构没有实现它们。React有其挑战,帮助React框架提供出色用户体验的最佳方法是专注于底层React。React本身可以在渲染层做一些独特的事情,极大地提高框架在其他层的能力。比如像,一个ReactAPI可以在后台为框架解锁一系列的框架优化。React是一个提供允许定义和组合组件的API的库。React也是一种提供构建块的架构,允许框架作者充分利用他们的渲染模型。我们可以在没有框架的情况下使用React。但是你需要确保如果你将它与框架一起使用,框架可以充分利用React。过去几年构建的许多功能(、useTransition、流式API(如renderToPipeableStream和实验性服务器端组件)都是面向框架的。他们让框架完全集成打包、路由和数据获取LeverageReact。您可以在Next13、Gatsby5和Remix1.11中看到其中一些功能。还有很多工作要做,其中一些工作正在从实验阶段结束。尽管如此,React团队还是很高兴看到多年的辛勤工作得到回报,并使React框架(及其用户)能够发布更快的应用程序。一个库,多个框架React生态系统更适合拥有许多相互竞争的数据获取解决方案和路由解决方案。这些选择每年都会变得更好。还有多种集成路由、数据抓取、渲染和编译的解决方案——即多种React框架。我们希望保持这种状态,并且在可能的情况下,我们希望鼓励融合并使React生态系统受益。例如,不同的框架可能使用不同的机制来加载数据。但是,如果它们都采用作为加载指示器,那么中的更高级别的功能将适用于所有框架。如果做大多数React应用程序的最佳方式是从一个框架开始,我们应该推荐哪个框架?我们应该选择一个吗?我们如何决定选择哪一个?如果它随时间停滞怎么办?这就引出了上面提到的问题。我们应该用CreateReactApp做什么?CreateReactApp的最初目标是:提供一种无需配置即可启动新React项目的简单方法;集成编译相关依赖,方便升级;允许React团队尽可能广泛地部署工具更新(例如快速刷新支持、Hookslint规则)。然而,它不再实现其最初的目标,即成为创建React应用程序的最佳方式。通过提高标准并将编译与渲染、路由和数据获取相集成,该框架允许用户创建React应用程序:充分利用React及其框架级功能;提供路由和数据获取。React生态系统值得采用一种默认方法,以充分利用网络和React本身。这甚至并不意味着您必须依赖Node.js服务器。许多流行的框架不需要服务器并在SSG模式下工作,因此它们也可以解决“完全静态”的用例。该框架的优势在于,如果以后需要SSR,不需要迁移,它和其他功能一样开箱即用(例如Remix提供开箱即用的mutationAPI)。那么如何实现这个愿景呢?您有以下选择:选项1:从头开始创建一个新框架尝试将CreateReactApp重新构建为一个集成了数据获取、路由、打包和SSG/SSR的框架。构建一个高质量的新框架是一项艰巨的任务,需要大量的生态系统专业知识,甚至停止其他项目来实现它也会随着时间的推移面临停滞不前的重大风险。就像创建React应用程序一样。它会进一步分裂生态系统,尽管没有真正的用户。所以不要认为这个选项目前是实用的。方案二:放弃CreateReactApp,维护一个Vite模板你可以放弃CreateReactApp,维护自己的Vite模板。为了实现这个目标,模板必须非常复杂。事实上,它必须像React框架一样复杂——并且需要集成路由、数据获取等。这会导致相同的问题:有效地创建另一个框架。选项3:弃用CreateReactApp,支持React框架不再强调或反对将CreateReactApp作为工具,而是更加积极地强调React框架。这并不意味着必须使用其中一种React框架,但建议大多数应用程序使用一种。不利的一面是,这会影响React的品牌推广(“为什么不推荐创建React应用程序?”)。选项4:让CreateReactApp使用单一框架您可以选择一个特定的框架并更改CreateReactApp以默认使用该框架创建应用程序。这种方法的主要问题是它使其他解决方案很难竞争——尤其是当它们的权衡略有不同但在流行度、功能集和质量方面大致相同时。这种行为上的变化也是破坏性的,因为所有旧教程都会以一种不明显的方式中断。选项5:将CreateReactApp变成启动器您可以将CreateReactApp保留为命令,但将其变成启动器。它将建议推荐框架列表,然后是“经典”无框架方法。“经典”方法会产生像CRA现在所做的那样的仅客户端应用程序(以避免破坏现有教程),但在内部它可能最终使用Vite。要包含在特色框架列表中,React框架必须满足特定条件。需要考虑社区的流行度和采用率(以保持列表简短)、功能集、性能特征、充分利用Web平台和React本身的能力,是否积极维护并清楚如何在各种托管服务和环境上托管它.每个框架的入门模板将由React团队维护,以确保它们具有一致的设计和品牌,不与商业服务相关联,并且结构相似。这些选择是如何做出的需要明确地传达给社区,他们将定期重新评估。React团队建议React团队目前倾向于选项5(“将CreateReactApp变成启动器”)。CreateReactApp的最初目标是为大多数React用户提供启动新的ReactWeb应用程序的最佳方式。重新调整它的用途,Enabler清楚地传达了我们认为最适合大多数新Web应用程序的转变。与选项3不同,它避免了“创建React应用程序”以某种方式被弃用的看法。React团队将制定更详细的RFC提案来充实这些要点。同时,希望听到更多关于这些问题的反馈。您对使用Vite替代CreateReactApp有何看法?欢迎在评论区分享~参考:https://github.com/reactjs/reactjs.org/pull/5487#issuecomment-1409720741