问题

为什么 React 源码不用 TypeScript 来写?

回答
React 源码之所以不直接使用 TypeScript 来写,而是选择 JavaScript(通常是 ES6+ 的语法,并通过 Babel 等工具编译),主要是出于以下几个历史、技术和社区的综合考量。虽然现在 TypeScript 在前端领域非常流行,并且在很多大型项目中表现出色,但对于 React 这样拥有悠久历史且生态庞大的项目来说,迁移到 TypeScript 并不是一个简单的决定,而是需要权衡利弊的。

以下是详细的分析:

1. 历史原因和早期决策

React 的诞生时间: React 于 2013 年首次发布。在那个时候,JavaScript 的静态类型检查工具(如 TypeScript 或 Flow)还没有像现在这样成熟和普及。JavaScript 仍然是构建 web 应用的默认语言,而大型项目通常会采用成熟的 JavaScript 框架。
早期生态系统: React 在早期就已经建立了一个庞大的生态系统,包括各种库、工具和社区贡献。如果 React 本身的核心代码使用 TypeScript 编写,那么所有依赖于 React 的第三方库也需要适配 TypeScript,或者其类型定义需要与 React 的类型定义兼容。这种迁移成本在当时是巨大的。
渐进式采纳的哲学: React 的设计理念之一就是渐进式采纳。这意味着开发者可以逐步将 React 的功能引入到现有项目中,而不需要一次性重写。如果 React 核心使用 TypeScript,那么对于大量仍然使用原生 JavaScript 的项目来说,集成 React 就会增加额外的学习成本和工具链配置。

2. 技术考量和权衡

编译和打包的复杂性:
JavaScript + Babel: React 社区已经建立了一套非常成熟和优化的 JavaScript 构建流程(如 Webpack, Rollup, Parcel)。Babel 可以将 ES6+ 语法转换成兼容性更好的 JavaScript,并且有大量的插件支持各种转换和优化。这套流程非常灵活,可以轻松集成各种预处理器(如 CSS Modules, styledcomponents)和转换。
TypeScript 本身: TypeScript 需要一个编译步骤来将其转换为 JavaScript。虽然现在有很多工具(如 esbuild, swc)可以非常快速地编译 TypeScript,但在 React 的整个构建管线中引入另一个编译步骤,可能需要对现有的构建工具和配置进行大量修改,以确保性能和效率。
维护和社区贡献:
现有贡献者: React 拥有一个庞大的社区,其中许多贡献者可能更熟悉 JavaScript,而不是 TypeScript。如果核心代码库切换到 TypeScript,可能会增加社区成员的贡献门槛,或者导致一些经验丰富的贡献者难以适应。
学习曲线: 虽然 TypeScript 的学习曲线相对平缓,但对于不熟悉 TypeScript 的开发者来说,仍然需要时间来学习其类型系统、接口、泛型等概念。这可能会影响社区的参与度。
JavaScript 的灵活性和动态性:
React 的一些内部实现和设计可能受益于 JavaScript 的动态性和灵活性。例如,在处理组件的 props、state 和 context 时,JavaScript 的动态特性有时可以提供更简洁的表达方式。
在某些复杂的内部机制中(例如,底层的 diffing 算法、Fiber 架构的调度),严格的静态类型可能会带来一些限制或需要更复杂的类型推导和转换。
性能优化: React 的核心团队在性能优化方面投入了巨大的精力。他们使用的 JavaScript 代码经过了高度的优化,并且能够充分利用 JavaScript 引擎的特性。迁移到 TypeScript 后,需要确保生成的 JavaScript 代码仍然能够保持同样的性能水平,并且不会引入额外的运行时开销。
类型定义 (Definition Files): 尽管 React 核心不使用 TypeScript,但它通过提供高质量的 `.d.ts` 类型定义文件(例如 `@types/react` 包),使得使用 TypeScript 的开发者能够获得完整的类型支持。这意味着外部用户可以在使用 TypeScript 的同时享受 React 的类型安全。这是 React 团队采取的一种折衷方案,既不强制改变核心实现,又能满足 TypeScript 用户需求。

3. 社区的反馈和趋势

TypeScript 的崛起: 随着 TypeScript 的成熟和普及,社区对 React 核心采用 TypeScript 的呼声越来越高。Facebook(Meta)内部也在大规模使用 TypeScript,这为未来的迁移提供了内部支持和经验。
未来可能性: 虽然目前 React 核心没有使用 TypeScript,但这并不意味着永远不会。随着技术的发展和社区的成熟,未来 React 核心完全有可能逐步迁移到 TypeScript,或者至少更深入地集成 TypeScript 的优势。Facebook/Meta 也在持续探索如何更好地利用类型系统来改进 React 的开发和维护。

总结 React 源码不用 TypeScript 的主要原因:

1. 历史包袱和早期决策: React 在 TypeScript 普及之前就已成熟,且生态庞大。
2. 维护成本和社区贡献: 避免增加现有贡献者和用户的学习成本和迁移负担。
3. 构建工具链的复杂性: 需要与现有成熟的 JS 构建流程集成,避免引入不必要的复杂性。
4. JavaScript 语言的灵活性: 在某些内部实现上,JS 的动态性可能提供了更直接的解决方案。
5. 提供类型定义文件作为折衷: 满足 TypeScript 用户需求,同时保持核心代码的灵活性。

尽管如此,React 团队对 TypeScript 持开放态度,并且社区的反馈也在不断推动着变化。我们看到越来越多的 React 相关库和生态工具都使用 TypeScript,并且在 React 的内部实现中也可能使用一些类型检查和校验的工具来辅助开发。未来,随着 TypeScript 的进一步发展以及 React 社区的需求变化,我们或许会看到 React 在核心实现上采取更“类型安全”的方式。

网友意见

user avatar

外界能看到的时间线请参考 @贺师俊 的答案,我从 Facebook 内部的角度告诉你为什么现在 React 的源代码用了 Flow 但没有用 TypeScript 吧。

Facebook 是一家技术很厉害的公司,能够超前做一些外界没有的东西,但等外界把这个东西做出来了,Facebook 就发现自己迁移不过去了,被自己过去超前做的技术锁定了,因为迁移成本太高。举个例子,在还没有 webpack 的时候 Facebook 就有自己很好的前端构建流水线,但 webpack 出来后 Facebook 无法迁移到 webpack,甚至无法轻易把 transpiler 迁移到 Babel。

如果我没记错的话,Babel 作者 Sebastian McKenzie 进入 Facebook 后做过一个项目,就是帮助 Facebook 迁移到 Babel。为什么呢?因为在外界还没有 Babel 的时候,甚至在 Babel 前身 6to5 还没出现的时候,Facebook 内部的流水线已经有自己的 transpiler,能够把一部分 ES6 语法转译为 ES5。当时我们可爽了,在外部根本还没意识到能这样做事情的时候,我们已经可以随手写 ES6 了。但有了 Babel 后,内部流水线根本不兼容中间插入 Babel 这一步,所以就需要专门改造这个流水线才能迁移到 Babel。而且 Facebook 已有的大量代码的 ES6 写法是基于内部 transpiler 写的,谁能保证迁移到 Babel 后 100% 兼容?迁移到 Babel 后如果编译出错了,那还能找出来修复。如果不出错,但实际执行结果略微不一样,导致出现线上事故,那怎么办?

React 在写的时候,是基于上述 Facebook 内部流水线写的,所以自然是内部有什么工具就依赖什么工具。React 一开始写的时候,其实是没有 Babel、TypeScript 和 Flow 的,但有上述内部 transpiler,所以就这样写了。到后来有了 Flow,而且要保证依赖于 React 的代码能够得到正确的 Flow 类型推断,自然就加上了 Flow 注释。此外,内部流水线应该是从来没做过 TypeScript 支持的,所以估计就算想用 TypeScript 来写也做不到,因为这不是加个 webpack 插件就能支持的。


为什么 Facebook 要做 Flow 而不用 TypeScript?这是一个规模的问题,对于大多数一般人来说没有这个规模是不可能理解的。我可以举若干个故事来解释一下什么是规模,以及为什么大多数人都没有机会解决这类问题,但非常少数的超大规模型公司需要请非常资深的工程师来解决。

第一个例子是为什么 Facebook 不能用 TypeScript,因为 TypeScript 会把所有源代码加载到内存里进行处理。Facebook 用的是 monorepo,也就是一个单体源代码库,不按项目分多个代码库,这使得互相引用的 JavaScript 非常庞大。如果让 TypeScript 直接跑,TypeScript 的内存开销会大到连 Facebook 的服务器都 hold 不住,然后崩溃掉。为此 Facebook 坚持做自己的 Flow,Flow 能够分拆要处理的 JavaScript 然后一部分一部分地处理,解决 Facebook 内部的独家问题。Facebook Flow 团队的态度很明确:「这是做给我们自己用的,我们顺手开源而已,你们爱用就用,没人逼你们用。我们会优先做内部需求,社区需求不着急做,如果社区需求跟内部需求冲突的必然让路给内部需求。」

第二个例子是为什么 Facebook 用 Mercurial (hg) 而不用 Git,因为 Facebook 几年前每周的 commit 数量就高达五位数,现在可能已经六位数了。这导致每天上班跑一次 git pull --rebase 搞不好就 30 分钟,非常影响生产力,而且一天还可能要跑几次。既然 Git 是开源的,Facebook 就想要去改 Git 源代码,改善自己工作流程的生产力。Facebook 主动去撩 Git,说「我们愿意贡献源代码啊,我们可以优化我们在乎的工作流程的性能,你们愿意接受我们的 Pull Request 吗?」Git 说「滚!这是你们特有的问题,正常的 Git 用户根本没有这么高的 commit 流量,不要引入非必要的复杂度到我们的源代码里。」于是 Facebook 跑去撩 Mercurial,人家说「欢迎来贡献代码」,于是 Facebook 就切换到 Mercurial 了。

第三个例子是 Facebook 特有的 iOS 开发环境优化。跟上面的例子相似,如果当作一个普通的 Xcode 项目打开 Facebook 主应用的源代码,编译一下就 60 分钟,根本无法干活。所以 Facebook 做了一些非常专门的优化,保证大家如果只是改动一两个模块里的代码时,编译速度非常快,一下子就能把 Facebook 主应用编译出来,能看到改动的效果。Facebook 跟 Apple 的关系不错,就问 Apple 有没有兴趣对 Xcode 做一些相关的优化,Apple 当然表示没兴趣。Apple 说他们真正看重的是那些一两个程序员组成的小开发者,因为这种类型开发者写了绝大部分 App Store 上面的应用,包括大部分的高质量应用。Apple 要优先满足这种类型开发者的需求,而不是 Facebook 这种「仅此一家」的需求。

举这三个例子是为了说明这样一个事情:Facebook 的很多问题是独家的,并不是外部看到的那么简单的问题。有些很多问题是因为规模导致的,做不到 Facebook 这样的规模根本遇不到这样的问题。你可以想象你自己做项目会怎么做,但你把这应用到 Facebook 这样的规模就很可能行不通。

类似的话题

  • 回答
    React 源码之所以不直接使用 TypeScript 来写,而是选择 JavaScript(通常是 ES6+ 的语法,并通过 Babel 等工具编译),主要是出于以下几个历史、技术和社区的综合考量。虽然现在 TypeScript 在前端领域非常流行,并且在很多大型项目中表现出色,但对于 React.............
  • 回答
    React 函数式组件的崛起:为什么我们不再执着于 Class?在 React 的世界里,组件是构建用户界面的基石。最初,Class 组件是构建复杂应用的主流方式,它提供了生命周期方法和 `this` 关键字带来的清晰的逻辑组织。然而,随着 React 的发展,函数式组件凭借其引入的 Hooks A.............
  • 回答
    Vue 和 React 并没有“抛弃”面向对象的写法,更准确地说,它们没有将面向对象作为主要的、官方推崇的开发范式。这其中有历史原因、技术发展趋势以及它们各自的设计哲学使然。我们可以从几个方面来详细解读: 1. JavaScript 的演进:从原型链到函数式思维首先,我们需要理解 JavaScrip.............
  • 回答
    在前端开发领域,当我们谈论 React 或 Vue 这类框架时,经常会听到“生命周期”这个概念。这可不是凭空出现的,而是为了更好地管理和控制我们编写的组件在整个“生存”过程中所经历的各个阶段。想象一下,一个组件就像一个小小的生命体,它也有自己的诞生、成长、工作和最终消失的过程。前端框架正是为了给开发.............
  • 回答
    我知道你的感受。很多人刚接触 React 时都会觉得它有点“劝退”,甚至难以驾驭。我当年也是一样,花了不少时间才摸清门道。今天咱们就好好聊聊,为什么会有这种“React 难用”的感觉,从几个关键点给你掰扯清楚。1. JSX:初见时的“怪异”刚看到 React 的 JSX 语法时,很多人都会觉得:这啥.............
  • 回答
    关于“尤大说 React 性能不如 Vue”这个说法,需要先明确一点:尤雨溪(Vue.js 的作者)并没有公开、明确地断言“Vue.js 的性能在所有场景下都优于 React”。事实上,在性能优化这件事上,开发者社区的共识是:对于绝大多数应用来说,React 和 Vue.js 之间的性能差异微乎其微.............
  • 回答
    这件事挺有意思的,网上关于“操作真实 DOM 慢”的说法深入人心,但你遇到的测试结果却指向了相反的方向,这背后其实涉及几个关键点,咱们一点点掰开了聊。首先,我们要明白,网上的“操作真实 DOM 慢”这个说法,大多数时候是在一个特定的语境下成立的,也就是频繁且无序地直接操作真实 DOM。想象一下,如果.............
  • 回答
    Vue 和 React 都是目前非常流行的 JavaScript 前端框架,它们都旨在帮助开发者构建用户界面。虽然它们在很多方面有相似之处,但各自的优缺点也使得它们在不同的场景下有不同的适用性。下面我们来详细分析一下 Vue 和 React 的优点: Vue.js 的优点:Vue.js 以其易用性、.............
  • 回答
    近年来,自由主义在全球范围内的影响力确实呈现出明显的衰落趋势,这一现象涉及经济、政治、社会、技术、文化等多个层面的复杂互动。以下从多个维度详细分析自由主义衰落的原因: 一、经济全球化与贫富差距的加剧1. 自由主义经济政策的局限性 自由主义经济学强调市场自由、私有化、减少政府干预,但其在21世.............
  • 回答
    俄乌战争期间,虚假信息(假消息)的传播确实非常广泛,其背后涉及复杂的国际政治、媒体运作、技术手段和信息战策略。以下从多个角度详细分析这一现象的成因: 1. 信息战的直接动因:大国博弈与战略竞争俄乌战争本质上是俄罗斯与西方国家(尤其是美国、北约)之间的地缘政治冲突,双方在信息领域展开激烈竞争: 俄罗斯.............
  • 回答
    政府与军队之间的关系是一个复杂的政治与军事体系问题,其核心在于权力的合法性和制度性约束。虽然政府本身可能不直接持有武器,但通过法律、组织结构、意识形态和历史传统,政府能够有效指挥拥有武器的军队。以下是详细分析: 一、法律授权与国家主权1. 宪法与法律框架 政府的权力来源于国家宪法或法律。例如.............
  • 回答
    关于“传武就是杀人技”的说法,这一观点在历史、文化和社会语境中存在一定的误解和偏见。以下从历史、文化、现代演变和误解来源等多个角度进行详细分析: 一、历史背景:武术的原始功能与社会角色1. 自卫与生存需求 中国传统武术(传武)的起源与农耕社会、游牧民族的生存环境密切相关。在古代,武术的核心功.............
  • 回答
    关于近代历史人物是否能够“翻案”的问题,需要结合历史背景、人物行为对国家和民族的影响,以及历史评价的客观性进行分析。袁世凯和汪精卫作为中国近代史上的重要人物,其历史评价确实存在复杂性和争议性,但“不能翻案”的结论并非基于单一因素,而是综合历史、政治、道德等多方面考量的结果。以下从历史背景、人物行为、.............
  • 回答
    关于“俄爹”这一称呼,其来源和含义需要从多个角度分析,同时要明确其不尊重的性质,并指出如何正确回应。以下是详细解析和反驳思路: 一、称呼的来源与可能的含义1. 可能的字面拆解 “俄”是“俄罗斯”的拼音首字,而“爹”在中文中通常指父亲,带有亲昵或戏谑的意味。 若将两者结合,可能暗示.............
  • 回答
    民国时期(19121949)虽然仅持续约37年,却涌现出大量在文学、艺术、科学、政治、哲学等领域具有划时代意义的“大师级人物”。这一现象的出现,是多重历史、社会、文化因素共同作用的结果。以下从多个维度进行详细分析: 一、思想解放与文化启蒙的浪潮1. 新文化运动(19151923) 思想解放.............
  • 回答
    航空航天领域在待遇和职业环境上确实存在一定的挑战,但国家在该领域取得的飞速发展,主要源于多方面的国家战略、技术积累和系统性支持。以下从多个维度详细分析这一现象: 一、国家战略与长期投入:推动技术突破的核心动力1. 国家层面的战略目标 航空航天技术往往与国家的科技竞争力、国家安全和国际地位密切.............
  • 回答
    吴京作为中国知名演员、导演,近年来因《战狼2》《英雄联盟》等作品及个人生活引发公众关注,其形象和言论在不同语境下存在争议,导致部分人对其产生负面评价。以下从多个角度详细分析可能的原因: 1. 个人生活与公众形象的冲突 妻子被曝光:2018年,吴京妻子的近照和视频被网友扒出,引发舆论争议。部分人.............
  • 回答
    近年来,全球范围内对乌克兰的支持确实呈现出显著增加的趋势,这一现象涉及多重因素,包括国际局势、地缘政治博弈、信息传播、经济援助、民族主义情绪以及国际社会的集体反应。以下从多个角度详细分析这一现象的成因: 1. 俄乌战争的爆发与国际社会的集体反应 战争的爆发:2022年2月,俄罗斯对乌克兰发动全面入侵.............
  • 回答
    《是大臣》《是首相》等政治剧之所以能在编剧缺乏公务员经历的情况下取得成功,主要源于以下几个关键因素的综合作用: 1. 构建政治剧的底层逻辑:制度与权力的结构性认知 政治体制的系统性研究:编剧可能通过大量研究英国议会制度、政府运作流程、政党政治规则(如议会制、内阁制、党鞭系统等)来构建剧情。例如.............
  • 回答
    关于“剧组中男性可以坐镜头箱而女性不能”的现象,这一说法可能存在误解或过度泛化的倾向。在影视拍摄中,镜头箱(通常指摄影机或固定设备)与演员的性别并无直接关联,但若涉及性别差异的讨论,可能与以下多方面因素相关: 1. 传统性别刻板印象的延续 历史背景:在传统影视文化中,男性常被赋予主导、主动的角.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有