cover of episode CodeSandbox with Ives van Hoorne

CodeSandbox with Ives van Hoorne

2024/12/4
logo of podcast Software Engineering Daily

Software Engineering Daily

People
I
Ives van Hoorne
Topics
Ives van Hoorne: CodeSandbox 是一个在线开发环境,允许开发者在浏览器中进行完整的 Web 开发项目工作。它类似于 Google Docs 和 Microsoft Word 的协作理念,旨在简化代码共享和协作。其核心功能是代码编辑器和预览窗口,将代码编辑器(左侧)的输入转换为预览窗口(右侧)的输出。CodeSandbox 的发展始于作者在团队协作中共享 React 代码的困难,以及对类似 Figma 和 Google Docs 的在线协作工具的启发。最初版本使用 JavaScript、Create React App、Elixir 后端、Postgres 数据库和 Redis 缓存。为了支持大型项目,CodeSandbox 推出了 DevBoxes 功能,使用虚拟机运行项目,并通过 WebSockets 连接进行文件检索。为了提高 DevBoxes 的性能和可扩展性,CodeSandbox 使用了 Firecracker 虚拟机技术,该技术允许暂停和恢复虚拟机,并从快照中创建新的虚拟机。为了解决安全问题,CodeSandbox 通过多种方法来确保 DevBoxes 的安全性,包括使用 Unix 用户、jailer 和检测算法来防止滥用,例如加密货币挖掘和网络钓鱼。为了应对网络钓鱼攻击,CodeSandbox 在预览页面添加了警告信息,提醒用户注意潜在风险。CodeSandbox 的前端使用 iframe 来渲染预览部分,以隔离用户应用并提高安全性。它通过解析代码、转换代码和使用 eval 函数来执行代码。为了优化用户体验,CodeSandbox 提供了安装依赖项的建议,并对一些常见错误进行了处理。CodeSandbox 的依赖项安装通过 AWS Lambda 服务处理,并对下载过程进行了优化。CodeSandbox 的代码编辑器最初使用 CodeMirror,后来迁移到 Monaco(VS Code 的代码编辑器),并通过模拟 Node.js 环境来支持扩展。为了实现类型信息的显示,CodeSandbox 在浏览器中运行 VS Code 扩展程序,并模拟 Node.js 环境和文件系统。CodeSandbox 现在直接从 NPM 注册表下载 tar 文件来获取类型文件,以降低带宽成本。未来 CodeSandbox 可能转向使用 ES 模块和 Service Worker 来改进打包和执行代码的方式。CodeSandbox 的 Firecracker 虚拟机技术具有广泛的应用潜力,可以扩展到 CI/CD 系统和其它领域。 Josh Goldberg: 主要参与访谈,提出问题,引导 Ives van Hoorne 讲解 CodeSandbox 的技术细节。

Deep Dive

Key Insights

What is CodeSandbox and how does it compare to traditional development tools?

CodeSandbox is an online development environment that allows users to start web development projects directly in the browser. It is similar to Google Docs, where users can share a link to a live, editable environment, eliminating the need for local setups.

Why did Ives van Hoorne start coding?

Ives started coding at around 10 years old to create a program that translated a secret language he and his friend used to write letters in class. This was his first interaction with programming, using Visual Basic to create a simple translator.

How did Ives van Hoorne's early coding experience influence his later work?

Ives' first coding project involved creating a program with input on the left and output on the right, a concept that mirrors the core functionality of CodeSandbox, where users write code on the left and see the result on the right.

What challenges did Ives face when transitioning from graphic design to coding?

Ives initially disliked graphic design because it was too subjective, with clients often requesting designs he didn't agree with. He found coding more appealing as it felt like solving puzzles with clear solutions, though he later realized coding also has subjective elements.

How did Ives van Hoorne's experience at his first job influence the creation of CodeSandbox?

At his first job, Ives struggled with sharing React code snippets over Slack, as it was difficult to debug errors without a live environment. This frustration led him to envision an online code environment where users could share running code easily, similar to Google Docs.

What was the initial tech stack of CodeSandbox when it launched in 2017?

The initial tech stack included Create React App for the frontend, Elixir with the Phoenix framework for the backend, Postgres for the database, and Redis for caching. The entire platform was hosted on a $20 VPS with 2GB of RAM.

How did CodeSandbox scale its database to handle half a billion files?

CodeSandbox stored all files in a Postgres database, with each file represented as a row. Despite handling over 500 million files, the database queries remained efficient, with sandbox loading times under 100 milliseconds due to well-indexed columns in Postgres.

Why did CodeSandbox introduce DevBoxes, and how do they differ from sandboxes?

DevBoxes were introduced to support larger projects that exceeded the 500-file limit of sandboxes. Unlike sandboxes, which run entirely in the browser, DevBoxes run on a server-based VM, allowing for full-scale development with features like lazy file retrieval and VM snapshots.

How does CodeSandbox handle security for its DevBoxes?

DevBoxes use Firecracker, a VM technology developed by AWS, which allows for secure execution of user code. Each VM runs as a separate Unix user, and a jailer ensures code remains within its environment, preventing unauthorized access to the host system.

What challenges does CodeSandbox face with crypto miners and phishing attempts?

Crypto miners often abuse CodeSandbox by running miners on VMs, while phishing attempts involve creating fake login pages. CodeSandbox uses detection heuristics and AI to identify and block malicious activities, though it remains a constant cat-and-mouse game.

How does CodeSandbox execute user code in the browser?

CodeSandbox executes user code by parsing it to create a dependency graph, transpiling the code, and then using JavaScript's eval function to run it. The require function is overridden to handle dynamic imports, creating a loop that allows for efficient code execution.

How does CodeSandbox handle dependency installations for NPM packages?

CodeSandbox uses an AWS Lambda service to install NPM dependencies, creating a dependency graph to determine which files are needed. These files are then bundled and cached in an S3 bucket, allowing for fast retrieval and installation of dependencies.

How does CodeSandbox integrate VS Code into its editor?

CodeSandbox uses the browser version of VS Code, emulating Node.js in the browser to run VS Code extensions. This allows users to have a familiar VS Code experience with features like type information and extensions, all within the browser environment.

What is Ives van Hoorne's vision for the future of CodeSandbox's infrastructure?

Ives envisions generalizing the Firecracker-based infrastructure to support not just development environments, but also CI/CD systems and deployments. This technology could significantly reduce setup times and improve parallelization in CI/CD pipelines.

Why does Ives van Hoorne enjoy playing volleyball?

Ives enjoys volleyball because it allows him to disconnect from work and focus entirely on the game. It is also a highly competitive and physically demanding sport, requiring short bursts of energy and strategic thinking, which he finds both challenging and rewarding.

Chapters
CodeSandbox, founded in 2017, is an online development environment allowing users to work on web development projects directly in their browsers. It's compared to collaborative document editors like Google Docs, enabling easy code sharing and collaboration. The core functionality involves a code editor on the left and a preview on the right, mirroring the input-output process from the founder's early programming experiences.
  • Founded in 2017
  • Cloud-based development environment
  • Allows users to work directly in their browsers
  • Core functionality: code editor on the left, preview on the right

Shownotes Transcript

CodeSandbox成立于2017年,提供基于云的开发环境以及其他功能。它迅速成为最突出的云开发平台之一。Yves Van Horn是CodeSandbox的联合创始人。他加入节目讨论该平台。本集由独立的全职开源开发者Josh Goldberg主持。

Josh从事TypeScript生态系统中的项目,最值得注意的是TypeScript ESLint,这是一种使ESLint和Prettier能够在TypeScript代码上运行的工具。Josh还是O'Reilly《学习TypeScript》一书的作者,微软开发者技术MVP,以及Twitch上的直播代码博主。在Blue Sky、Mastodon、Twitter、Twitch、YouTube和.com上搜索Joshua K. Goldberg即可找到Josh。♪

- Divas,欢迎来到软件工程日报。最近怎么样?- 非常好,感谢邀请。- 非常感谢你的到来。我们很高兴能邀请到你。我个人在工作面试、沙盒和演示中多次使用过你的产品。你能简单介绍一下CodeSandbox是什么吗?- 好的,简单来说,CodeSandbox是一个在线开发环境。你可以在CodeSandbox上启动一个新的Web开发项目,并且可以在浏览器中完成所有工作。

我倾向于将其与Google Docs和Microsoft Word进行比较,如果你在Microsoft Word中编写文档并在你的电脑上编写内容,但如果要共享它,就会变得更加困难。因此,人们更多地使用Google Docs,他们可以共享一个链接到网站,在那里他们可以在一个环境中一起编写。我们希望用CodeSandbox构建相同的东西。

太棒了。在我们深入探讨代码共享的未来之前,我想稍微回顾一下你作为一名开发者,作为一个人。你是如何开始编程的?这很久以前的事了。我最初开始编程并不是因为我想学习编程,而是因为我需要它。我想我当时大约10岁或11岁。我不确定我当时几岁,但是

我和我的一个朋友,我们有一种秘密语言,我们倾向于在课堂上互相写秘密信。我们会写下秘密字符,然后另一个人必须翻译它。这很有趣,但我希望更快一些。那时我开始考虑是否有可能创建一个程序。

那是我第一次接触编程,一个简单的Visual Basic程序,你可以,它实际上只是两个文本框,如果你在左边的文本框中输入一些内容,它会翻译它并将解决方案或翻译放在右边的文本框中。它也可以反过来操作。我们当时有一个荷兰的Facebook,我们会用这种秘密语言互相发送公开信息。

那是我第一次接触编程。这很有挑战性。老实说,在那之后,我很长时间没有编程了。直到我开始关注游戏和mod,我才再次开始编程。但那是我第一次接触编程。有趣的是,你第一次编程的形式是在左边输入,右边输出。几十年后的你还在做同样的事情。是的。

是的,最终,这都是一样的。是的,你在左边有一些东西,它会转换它并把它放在右边。我想你也可以对CodeSandbox说同样的话,这很有趣。CodeSandbox有很多很酷的功能,但是核心功能和最重要的功能仍然是你在左边有一个代码编辑器,右边有一个预览,显示代码的作用。这是核心功能。

这个核心功能是如何实现的?或者你是如何开始创建这个产品的?我停止编程一段时间了。但后来,我想我17岁的时候,我为一家公司做了很多平面设计。我开始意识到我喜欢平面设计,但我并不喜欢……

为其他人做平面设计,因为他们想让我设计一些我不认同的东西。比如,“你能让这个火在紫色背景上变成黄色吗?”我当时17岁,有点天真。我认为平面设计不适合我,因为它太主观了。

所以我开始转向编程,心想,“这有点像解谜,一个谜题只有一个答案。所以编程没有讨论,也没有主观性。”但事后看来我错了,但我仍然很喜欢它。

但我开始学习Web开发。最初,我创建了一个作品集网站。后来,我在当地报纸上读到,我们荷兰一个小村庄的当地报纸上说,有一家非常酷的新兴公司发展非常迅速。我在想,我想加入这家公司,因为这个村庄没有什么事情发生。

所以高中毕业后,我问是否可以加入他们进行假期工作,以便在假期为他们工作。

他们基本上说,最初他们忽略了我。他们不想……好吧,招聘人员有点困惑。一个18岁的年轻人只是要求在那里作为一名开发者工作。但后来,在我多次给他们打电话后,他们回电了,说:“是的,你可以在这里工作,但你必须至少工作一年。那么,你是否可以休一年假?”所以我开始在那里工作,所有东西都在Ruby on Rails中。大约在那个时候,

一项名为React的新技术变得越来越流行。我对React很感兴趣。我开始用React构建更多的小页面,我在想,“哇,与React的单页应用程序的速度相比,我们的Ruby on Rails前端感觉有点过时了。”我想,我又有点天真了,我开始将越来越多的Ruby on Rails页面转换为React。这很有趣,因为

当我进行转换时,在某个时候,我们想测试它并将其上线。然后市场部的人来找我们,因为他们很沮丧。突然,他们50%的分析数据消失了,因为我没有考虑到……

所有其他业务方面的事情,比如实施分析。总之,我有点离题了,但在某个时候我意识到,当我与同事一起处理React代码时,很难互相分享工作。就像每当我休假时,我的同事会问一些关于React路由器中一段代码的问题,他们只是在Slack上给我发送代码片段,我必须在我的手机上解读发生了什么以及出了什么问题。

以及错误是什么。我的脑子里没有JavaScript解释器。所以那时我开始认为,如果他们可以只发送给我运行的代码,那就太好了。

当时,Figma变得越来越流行。Google Docs成为许多人的默认选择。我开始思考,是否可以在浏览器中拥有一个代码环境?当时,我只是写下我所有想法,以备将来想创业时使用。所以我写下了这个想法,没有做太多事情,在休假后开始上大学。然后在大学里,最初我非常喜欢喝酒。

但这过了一段时间就变得无聊了。我们开始学习关于Java中面向对象编程的课程。到那时我已经完全沉浸在React的世界中了。我想,“为什么我必须再次经历这一切?”所以那时我开始做一个副项目。我只是查看我的想法列表,选择最新的一个,也就是在线Web编辑器,并开始进行第一个设计和草图。

然后我的朋友Buzz加入了,我们开始越来越多地工作。然后在4月2日,不是4月1日,我们发布了CodeSandbox的第一个版本。这就是它最初的启动原因。这是2017年4月2日吗?

是的,没错。所以已经超过七年了。你在2017年最初在React领域使用的技术平台是什么?哇,非常不同。所有内容都在JavaScript中,甚至不是TypeScript。我们确实使用了flow类型来使用注释对内容进行类型化,所有这些。那也很有趣。基本应用程序是在Create React app中。

后端是用Elixir编写的,使用Phoenix框架,因为Elixir是这个很酷的新事物,它看起来很像Ruby和Ruby on Rails,但它是完全函数式的。所以这是一个有趣的学习项目。事实证明,它的扩展性非常好。然后对于数据库,我们使用Postgres。对于一些缓存,我们使用Redis。所以最终的堆栈是Create React app前端,

Elixir后端,Postgres数据库,Redis,第二个内存数据库。我把所有这些都部署到Vultr上的VPS上,每月20美元的VPS,2GB内存。它扩展得非常好,这让我很惊讶。它扩展了一年,我想。在某个时候,我们的月活跃用户达到了50万,它仍然运行在这个Vultr上的20美元的VPS上。

在那之后,我们迁移到了Kubernetes,并将部署迁移到了GCP,也就是谷歌云平台。但因为这样可以更容易地进行迁移和扩展。但令人感兴趣的是,这样一个简单的解决方案……

运行得这么好。我想,这在某种程度上隐含地帮助了它的扩展。我记得在构建CodeSandbox的第一个版本时,我非常担心保存文件。例如,如果有人创建一个沙盒,然后他们按下fork,然后他们得到自己的版本,那么另一个人也会得到他们自己的沙盒版本。

我们如何扩展所有这些文件?我们应该使用像S3这样的东西吗?我们应该使用像Dropbox这样的东西吗?关于如何存储这些文件有很多问题。最终,经过大约一个月非常深入的思考,例如我们是否应该使用Git等等,我当时决定将所有内容都存储在Postgres中。

所以每个文件都只是Postgres表中的一行。当你按下fork时,我们只需要在Postgres中执行一些select和一些insert操作来复制所有文件,没有任何重复数据删除或其他操作。

有趣的是,我们今天仍在使用该系统。它从未达到极限。现在我们有,我想我们有超过8000万个沙盒,超过5亿个文件存储在Postgres数据库中。而且这个查询仍然在20毫秒以内,沙盒可以在100毫秒内加载,只需执行一些select操作。我们唯一不存储在数据库中的是

二进制文件。这有点太远了。所以它们存储在谷歌云存储桶中,然后我们在数据库中存储指向该文件的链接。但这提醒我,简单的解决方案通常是最好的,要么是因为它太简单了,以至于很少有竞争条件或很少有出错的地方,要么是因为更容易理解它是如何工作的。所以是的,这就是最初的情况。

在我们深入探讨其工作原理之前,我想花一点时间强调一下,你的Postgres数据库中有5亿个文件条目,你仍然能够在十分之一秒内加载网站的核心部分,这部分可能涉及许多文件查询。这是一个令人难以置信的扩展性能壮举,不是吗?是的,但我将其归功于Postgres。Postgres……

一次又一次地超出了我的预期。如果你在多个列上有一个好的索引,那么性能就非常出色。可扩展性也非常好。我现在会为任何数据库选择Postgres。唯一的例外是用于存储……

大量与时间相关的固有数据。所以是时间序列数据。然后我会考虑像ClickHouse这样的东西,但对于其他所有东西,Postgres都是一个令人难以置信的解决方案。让我们看看我们能否在他们的主页上获得这个报价。

让我们继续这段旅程。在CodeSandbox的底部或背面,你将文件存储在Postgres数据库中,以及指向存储在谷歌云中的大型二进制对象的链接。在其之上是什么?这些是如何检索的?或者围绕它们的系统是什么?是的,所以……

我认为,如果我们看一下CodeSandbox的最旧版本,例如CodeSandbox的初始版本,那么描述所有内容是如何检索的最简单方法。因为否则我们需要考虑现在介于两者之间的所有权限、计费等问题。但是最简单的,CodeSandbox的第一个版本,每当你检索一个沙盒时,

你会对我们的Elixir服务器进行API调用。Elixir服务器将进行一些检查。它将检查你是否可以访问该特定沙盒。它将从cookie中获取你的用户。然后它将在数据库上运行一个查询。这个查询很大。它有大约20个连接。这是少数几个手工编写的查询之一,而不是由ORM生成的查询。

该查询查看我们的模块表。这就是所有文件存储的地方。它查看我们的目录表,这是文件如何链接到不同目录的方式。

它查看我们的沙盒表。所以它从沙盒表中获取沙盒,然后从目录表中获取与沙盒相关的目录,然后从模块表中获取具有相同沙盒ID的所有文件。然后根据所有这些信息,它生成一个包含沙盒本身所有文件的JSON信息,并将其返回。而且

你可以认为这在某种程度上是不可扩展的,因为它不适用于大型项目。这是完全正确的。CodeSandbox是专门为创建原型、创建小型项目而构建的。这是最初的用例。

所以单个沙盒的文件数量限制为500个。如果文件数量限制为500个,那么返回沙盒的全部内容就可以了。现在,在这个阶段,我们还有一个名为dev boxes的第二种类型的项目。我们有用于原型的沙盒和用于开发的dev boxes。对于dev boxes,我们有更,我想说,更复杂的文件检索方式。你可以延迟检索文件,这样你就不必下载整个沙盒就能看到发生了什么。

简而言之,这就是它的工作原理。我们中间还有Redis,用于简单的、小的事情,如缓存,以及跟踪页面浏览量。这样,如果你在一个小时内两次访问一个沙盒,它会被视为一次页面浏览,而不是两次。但这就是我们检索沙盒的方式。

所以DevBox的概念在CodeSandbox的早期版本中并不存在。它是什么时候添加的?DevBoxes现在,我想说,大约有两到三年历史了,甚至可能三年了。CodeSandbox发布时,最初并不流行。我把它放在Twitter上。我在Twitter上只有60个关注者。我的大多数关注者都是高中朋友。所以我得到了三个赞。我们

我们开始更积极地谈论CodeSandbox。我开始阅读关于它如何工作的博客文章,开始直接与创建帐户的人交谈以获取反馈,所有这些都是基于这样一个想法,保罗·格雷厄姆说过,拥有100个粉丝比拥有10万个喜欢你的人更好。有了这个想法,我们试图通过做很多不可扩展的事情来获得100个粉丝。CodeSandbox,

CodeSandbox开始发展壮大,人们开始将它用于我们最初无法想象的事情。它最初是为我在工作中遇到的特定情况而构建的,在这种情况下,你想问一个问题,并且想要一个该问题的实时示例。

但是人们开始将它用于其他事情,例如工作面试、错误报告、文档,以及人们学习如何编程的研讨会。人们开始用它来构建新项目。例如,他们开始制作一个新的网站,一个作品集网站,或者他们开始制作一个新的博客,甚至有些人开始了一家新公司。例如,有一个我一直觉得很有趣的……

好吧,有趣,更像是自豪。有一个名为Excalibur的白板工具。我经常使用它。有趣的是,Excalibur的初始版本是在CodeSandbox上构建的,当时它被称为Excalibur。它是通过Twitter共享的沙盒。所以人们想用CodeSandbox构建真实的东西。他们想构建他们的作品集网站,以及他们最终想要在线部署的东西。

虽然CodeSandbox对于小型项目(如工作面试或示例)运行良好,但由于我们的500个文件限制,它并不适用于大型项目。那时我们开始考虑……

如果我们可以为小型项目创建与CodeSandbox相同的体验,那么对于大型项目也是如此。你仍然应该能够与某人共享链接,他们可以看到运行的代码。他们可以看到一切,它是如何工作的,他们可以按下fork来获取自己的版本。这就是DevBoxes的由来。这有点像CodeSandbox的重写,因为底层文件系统发生了变化。

通常情况下,沙盒都在浏览器中运行,因为它们可以运行小型项目,但是dev boxes在服务器上运行。所以我们构建了一个CodeSandbox版本,它确实是为完整开发而设计的。那么,仅仅从数据库上下文的角度来看,它有什么不同呢?dev boxes如何检索内容与原始布局有何不同?对于dev boxes,我们运行一个虚拟机来运行该项目。

一个虚拟机。所以本质上是一个运行项目本身的小型服务器。在这个服务器内部,我们运行一个可以从文件系统读取的进程。因此,现在当你打开一个dev box时,你不会连接到我们的API服务器来获取文件。相反,你会通过WebSockets连接连接到在该虚拟机中运行的小型服务器。

然后编辑器可以提出问题。它可以询问,例如,“你能给我项目/hello.txt文件路径下的文件内容吗?”然后它将返回它。所以整个API服务器仍然存在,但它只用于验证、身份验证。但是最终,获取文件和理解项目中发生的事情的连接将通过直接连接到服务器,即虚拟机本身来完成。

所以这不像原始沙盒那样可扩展。所有内容都在客户端运行。我们只是一个文件和API查找。它并不那么可扩展。例如,为每个用户、每个项目启动一个虚拟机,这是一个真正的挑战。至少在过去的四年里,我一直

非常深入地学习如何构建高效的基础设施。我们经历了多次迭代,寻找高效运行虚拟机的方法。最初,我们尝试了Kubernetes,我们尝试了Docker容器,但我们觉得这太慢了。在2021年,我们

我发现了一个名为Firecracker的项目。它是亚马逊团队,AWS团队创建的,因为他们使用它来运行AWS Lambda和AWS Fargate。Firecracker真正有趣的地方在于,它是一个可以运行代码的虚拟机,但你可以随时说,“暂停这个虚拟机”,它将立即停止。它将不再执行任何操作。然后你可以说,“现在将你的内存写入磁盘”。

然后稍后,例如一天后,你可以说,“从你写入磁盘的内存中创建一个新的虚拟机”,它将从中断的地方继续执行。它可能处于一个操作的中间,例如计算斐波那契数列,它将继续执行。没关系。这太有趣了。它非常,我想说它非常类似于,如果你关闭你的笔记本电脑。

然后你一天后打开它,它也会继续执行。即使你有一个XJS服务器正在运行,并且它正在进行编译,你也可以关闭你的笔记本电脑,一天后你打开它,它将从中断的地方继续执行。但是关于这一点有趣的是,人们对CodeSandbox的初始版本感到的一件事

使用服务器,它很慢。因为当你打开一个很长时间没有打开的项目时,你必须等待create React app服务器启动。你可能需要运行npm install。在你实际看到预览之前,可能需要很长时间。而且,当你按下fork时,我们必须创建一个文件系统的副本,并且我们必须再次执行相同的过程。而且

使用这种方法,我们同时解决了这两个问题。因为每当有人离开虚拟机时,我们都会暂停它并将内存保存到磁盘。然后,当有人在两天后打开该虚拟机时,我们将能够从暂停时,从它停止的地方恢复虚拟机,并且它将在大约一秒钟内恢复。所以这就是第一个问题得到解决。

这也极大地帮助了扩展,因为我们现在有一个规则,例如,如果有人五分钟没有查看虚拟机,那么我们就已经休眠了,因为如果我们休眠,人们不会注意到,因为恢复非常无缝。现在做的第二件事是,当有人按下fork时,我们还会创建原始虚拟机的快照,并使用该快照来恢复创建的新虚拟机。所以当你按下fork时,

你可以创建一个精确的副本,因为它将从最后一个虚拟机停止的地方继续执行,并且

后来,我们进行了优化,虚拟机甚至共享内存。所以如果你有一个从快照启动的虚拟机,并且有人按下fork,那么新的虚拟机将共享旧虚拟机的内存。所以如果两个虚拟机使用2GB内存,那么总内存使用量可能是2GB,因为它们引用相同的共享内存。这些小技巧使得……

虚拟机扩展成为可能。这是我从事过的最具挑战性的工作,因为它比沙盒更具挑战性,因为对于沙盒,我们将所有内容都在浏览器中运行。所以我们不必运行服务器来运行用户的代码。例如,我们只需要提供文件,所有执行都在用户端进行。但在这种情况下,我们必须创建一个快速的服务器,……

可以运行代码,但也要安全,因为人们不应该能够突破该环境。我们实际上是将远程代码执行作为一项服务提供给CodeSandbox。这是一个非常困难的问题。当我在Code Academy时,我们遇到了人们进行大量计算的问题,我们必须进行所有这些……

技巧和巧妙的解决方法,例如加密比特币挖掘。但你不仅有这个,你还有意地让人们能够在服务器上调用网络。那么,你究竟如何使你的盒子安全呢?

是的,这很有挑战性。盒子本身非常安全,它们最终使用了AWS Lambda和AWS Fargate使用的相同技术。所以每个虚拟机都有它自己的Unix用户。我们使用一个监禁器来确保所有内容都在它自己的环境中。但是人们仍然可以滥用……

例如,有人可以在服务器上运行加密矿机。有人可以在CodeSandbox上创建一个帐户,创建20个虚拟机,这将很快。我们可以非常快速地启动这20个虚拟机,这使得他们很容易做到。他们可以开始挖掘加密货币。加密矿工是最令人沮丧的人。他们非常有创造力。他们有很多时间。我们现在所做的是,我们有一个检测启发式方法,

每分钟在虚拟机内部运行一次。

以检测虚拟机是否正在运行。我必须说,现在它有很多if语句和else语句,基于我们之前看到的现有加密矿工及其行为。我们现在正在尝试训练一个小型神经网络,该网络可以根据网络调用和进程行为自动检测加密行为。但这是一种猫捉老鼠的游戏。我们遇到的另一个问题是网络钓鱼。

人们大量使用CodeSandbox进行网络钓鱼。他们用它来创建虚假的银行登录页面。他们用它来创建虚假的微软登录页面。我们与之斗争了很长时间。我们还因为网络钓鱼而看到了CodeSandbox作为一项服务的破坏。因为,例如……

谷歌可以,例如,阻止我们的预览域csb.app。他们可以只阻止整个域,因为自动检查说,“哦,这个域上有两个网络钓鱼网站”。然后整个域被阻止了。然后因为这个原因,我们停机了大约三个小时。然后我们不得不回退到其他域。或者仍然存在一个持续存在的问题,即……

土耳其,土耳其的一些ISP,他们已经阻止了CodeSandbox,例如预览域,仅仅是因为他们看到了一些网络钓鱼页面。最初,我们也为此应用了AI。我们创建了所有这些公共沙盒的屏幕截图,并试图确定它是否是网络钓鱼沙盒。然后我们会向用户显示警告,或者我们会主动阻止这些沙盒。

如今,我们某种程度上放弃了斗争,因为每当有人第一次访问 CodeSymox 预览时,它是一个独立的预览,所以他们不是从编辑器中打开它,而是例如从电子邮件中打开它。

然后我们会首先显示一个大型的中间页,警告说:小心,这是一个代码沙箱预览,它不是银行登录页面,它用于开发目的。然后他们必须按下一个按钮说:“我明白了”,然后他们才能进入预览,并且,

它确实会影响 CodeSandbox 的体验。例如,当您与某人共享一个预览到真实内容时,他们仍然必须先通过这个中间页才能访问该页面。但是部署之后,CodeSandbox 上的钓鱼页面数量大幅减少。钓鱼者可能正在寻找新的目标,寻找没有类似功能的地方。

我们有时仍然会收到这些检测钓鱼页面的服务的电子邮件,但我们现在甚至可以自动处理这些电子邮件。例如,我们会扫描所有电子邮件,如果它来自我们已知的钓鱼检测器的域名或电子邮件,我们会自动禁止该服务。

沙箱时,他们会在其中添加链接。是的,这很难。这里没有正确的答案,对吧?例如,如果我是一个训练营,我正在教我的学生如何用任何前端语言编写一个完整的页面,而示例应用程序是一个登录页面,一个恰好看起来像谷歌登录页面的页面。你怎么知道这是合法的,而不是骗子?是的,这些是最难处理的案例。这就是为什么我们更倾向于显示警告而不是主动禁止沙箱。

在这一点上,它变得容易得多,因为现在我们只是向所有人显示这个中间页。如果您信任发送该页面的人,那么您可以打开它。如果您从不知名的短信中收到此页面,然后收到此中间页面的警告,不要信任此页面上的任何登录表单,那么这将涵盖许多情况。

这是另一个例子,你尝试了复杂的方法,比如 AI 扫描来检测诈骗,而简单、可扩展、廉价的方法实际上非常有效。是的,我没有考虑这一点,但你是对的。这种简单的方法解决了所有问题,它也是最简单的方法。没有花哨的 AI 或检测启发式方法。

隆重推出 Hyte,唯一一款自主项目管理工具。积压梳理、错误分类、保持文档最新。这些都不是你从事产品构建的原因,对吧?Hyte 会为你处理所有这些繁琐的工作。Hyte 使用首创的 AI 方法,主动处理耗时的工作流程,而无需你动手。Hyte 识别到你已同意缩减范围,并负责将必要的编辑映射回你的产品简介。

当新的工单添加到你的积压工作中时,Hype 会仔细检查它们,添加功能标签、时间估计等等。这不仅仅是你。你的团队中的每个人都管理项目,跟踪更新、确定工作范围、平衡优先级。但是,你的产品是否成功不应该取决于项目管理。使用 Hype,自主工作流程处理那些日常维护工作,以便你的团队能够专注于构建优秀的产品。如果你准备停止管理项目,那么是时候使用 Hype 了。

加入新时代的产品构建,让项目自行管理。访问 height.app/SEDaily 开始使用。

在我们继续讨论客户端代码运行开发堆栈的整个代码沙箱部分之前,我还想问一个关于后端的问题。在 Codecademy,我一直想构建一些东西,如果我们检测到有人正在进行加密货币挖掘,我们会让他们继续挖掘,然后窃取他们的加密货币,并给他们一些假的作为回应,以此来狠狠地打击他们。你尝试过类似的事情吗?你愿意谈谈吗?

我也幻想过这个。是的,我考虑过。但从未做过。曾经有过这样的情况,人们不仅将其用于加密货币,而且有时仍在使用它来观看广告并从中赚钱。这非常有趣。他们在虚拟机内部启动一个浏览器,然后他们有一个 VNC 连接到它,以便你可以看到浏览器。

然后他们同时启动大约 20 个虚拟机。他们开始访问不同的页面观看广告,然后他们会因为观看这些广告而获得回报。这非常有趣。我曾经……

我找到了这个,我找到了其中一个虚拟机,这个虚拟机是公开的,所以我可以打开它。我看到 VMC 窗口在预览中打开。所以我开始在那个 VMC 中做很多事情。例如,我打开了记事本,发送了一条消息,我可以看到他们在某个时刻查看该沙箱,感到非常困惑并关闭所有窗口,因为他们感觉自己被抓住了。是的。

那很有趣。是的,我们的后端团队,我听说他们过去会做一些事情来戏弄人们,使他们不值得滥用该平台。这是一个阻止人们的好方法。同样,当我们检测到加密货币矿工一段时间后,我们只是限制了他们的沙箱,他们的开发箱。这样他们就会觉得他们可以挖掘加密货币,一切仍然可以工作。一切都会继续运行,但它们的运行速度只有完整虚拟机速度的 5%。

所以这是另一种让他们困惑的方法,我想。我喜欢它。但是,让我们更接近前端。所以让我们暂时坚持使用原始代码沙箱。你的 Postgres 数据库继续出色地扩展。你向用户提供了文件内容。现在用户的浏览器中会发生什么?是的。

是的。当我们启动 CodeSum 时,我们的预算非常低。所以使用服务器来运行代码是不可能的。我们还是学生,每月预算只有 100 美元。这是我们所能承受的最大限度。无论如何,这都是来自助学贷款的。所以我开始研究我是否可以在浏览器中运行 Webpack。Webpack 当时是迄今为止最流行的捆绑器。最初,我让 Webpack 运行了,但 Webpack 本身的包大小非常大。大约 8 MB,对于 2017 年来说,这甚至更大。这太大了。所以我开始研究这些不同的代码片段是如何执行的。我开始尝试自己执行代码,尝试构建一个非常简单的 Webpack 版本,该版本可以在浏览器中运行以执行代码。从本质上讲,它都围绕着 eval,即 JavaScript 函数 eval,你可以向它提供一个字符串,它将评估该代码。

每个人都说你永远不应该使用 eval,但这是 CodeSemmle 的核心功能。这就是我们围绕它构建启动公司的方式。发生的事情是我们接收所有代码。我们做的第一件事是解析所有代码。我们试图了解使用了哪些文件以及哪些文件导入哪些其他文件。

这会产生一个所谓的依赖关系图。使用此图,我们将转换所有代码。例如,你的源代码可以是 TypeScript 或 JavaScript,但还不适合在浏览器中运行。因此,我们将把该代码转换为可在浏览器中运行的代码。然后稍后,一旦所有内容都被转换,我们将使用 eval 执行该代码。

这些代码片段可以导入其他文件。它们将使用 require 函数调用来执行此操作,这是运行代码的常用 JS 方法。

我们会做的是,每当我们评估代码时,我们都会将所有内容包装在一个函数中,在这个函数中我们提供 require 作为函数。因此,我们将用我们自己的函数覆盖 require 函数。每当它调用 require 时,我们将解析该代码,并对该代码运行 eval,如果存在无限导入,则会创建这种无限循环。

这就是最终的工作方式。逻辑本身并不极其复杂。我还做过一次演讲,我认为我还写过一篇关于其工作原理的博客文章。我还拥有一个沙箱,其中实现了迷你捆绑器。简而言之,这就是全部内容。

它的工作原理。它变得更加先进,因为还有更大的挑战。例如,你将如何支持 node 模块?仅安装依赖项,每个人都会开玩笑说 node 模块比宇宙还大。那么你如何提高效率呢?这本身就是一个挑战,但核心功能本质上是创建依赖关系图、转换该依赖关系图中的所有文件,然后使用对代码的已获取覆盖调用 eval 的循环。

所以代码沙箱以具有美丽的视觉效果而闻名,对吧?那么它如何与 DOM 或 HTML 页面交互呢?好的。所以代码沙箱,如果你正在查看编辑器页面,你实际上正在查看两个应用程序。你正在查看编辑器本身。这是一个 create React app 应用程序。但是右侧的预览是一个完全不同的应用程序,它是在 iframe 内呈现的。该 iframe 指向一个不同的入口点(可以说是)。

该入口点是捆绑器。当我们编辑器从我们的 Postgres API 服务器下载所有代码时。

然后编辑器将该代码发送到预览 iframe 的 iframe。它将调用 post message 将所有文件发送到它。我们必须在 iframe 中运行所有内容的原因有两个。一个是它将用户应用程序与我们的编辑器完全隔离,因此他们无法干扰我们的编辑器。但另一个原因是安全性,因为如果

我们最终正在运行用户代码,因此他们不应该能够访问我们的 cookie 或我们的本地存储,这些事情。因此,编辑器将在 iframe 上调用 post message,将用户代码发送到该预览。在预览中,捆绑器将处于空闲状态,并侦听传入的任何消息。当它收到消息时,它将执行执行代码的循环。这最终将填充预览。

每当用户更改代码时,我们都会将整个包(从编辑器到预览 iframe 的所有内容)再次发送回预览 iframe。然后,预览 iframe 中的捆绑器将进行差异比较。它将查看代码的先前版本和新版本,并比较所有内容。然后,对于每个更改的文件,它将重新评估这些文件。它只会对这些文件及其父文件运行 eval。

所以你正在使用,让我弄清楚,eval。

iframe 和 window.postMessage。是的,这是核心功能。是的,听起来违反直觉,对吧?是的,但在内部,你还在构建一个完整的依赖关系图,并根据编辑器中受影响的更改动态重新加载该图。因此,你拥有这种令人难以置信的混合体,它将 2017 年之前的时代技术与非常出色的计算机科学概念相结合,以实现高效的重新部署。

是的,这是有趣的部分,因为你实际上是在构建两件事。你正在构建一个,我不会说硬核的,但像 Webpack 这样的纯开发人员工具,但你还在围绕它构建一个 UI,比如围绕它的开发人员体验。这会带来一些独特的机会,因为你拥有整个堆栈,你控制整个堆栈。例如,我们所做的一件简单的事情是,每当我们在捆绑器中遇到错误时……

它无法解析依赖项。假设你开始导入 Lodash,但你尚未安装 Lodash。我们将在捆绑器中创建一个专门的错误消息。将有一个按钮说:“哦,我们无法解析 Lodash。”然后将会有一个你可以点击的建议,上面写着“安装 Lodash”。当你点击“安装 Lodash”时,

当你点击该按钮时,捆绑器将向编辑器发送 post message,说我们需要安装 Lodash。然后编辑器将创建,将显示安装 Lodash 的 UI。它将安装 Lodash 并调用捆绑器的重新评估。这只是其中一个例子,因为你控制了整个体验,所以你可以创造一个非常好的体验。另一个例子是,我们 Discord 中的某人说,

感到沮丧,因为他们正在使用代码沙箱进行工作面试,他们没有大写他们的组件,React 组件,并且他们的 React 组件无法工作,我认为这可以追溯到 React 组件必须大写才能工作的那一天

正因为如此,他们面试失败了。因此,作为回应,我也为此创建了一个小的检测启发式方法,如果我们检测到存在关于不是默认 HTML 元素的自定义组件的错误,并且 React 会引发该错误,那么我们将显示一个建议,例如,“你是否大写了”

你的组件,然后我们将有一个按钮“大写组件”,当你点击它时,我们将更新代码以大写组件来捕捉这些事情,这对我来说是最令人兴奋的,因为它混合了核心开发人员工具构建捆绑器,但也存在你可以根据捆绑器返回的内容来改进的开发人员体验和用户体验。这个人后来有没有回复说他们找到了工作

之后,或者这是否帮助了他们?之后没有联系。我没有实现任何分析来了解该按钮被按下多少次。也许之后没有人看到它。但谁知道呢?只是一个关于技术领域的澄清点。当你提到安装时,客户端正在安装什么?是的,安装依赖项。

它随着时间的推移而发生了变化,但最大的挑战是安装 NPM 依赖项,因为 NPM 依赖项往往非常大。有时,一个库,一个 NPM 依赖项可能是 2 MB,这本身并不是什么大问题,但该依赖项也可能说,我有 20 个其他依赖项,而这些依赖项也可能是 2 MB。突然间,你必须下载 80 MB 的依赖项。所以,

我们通过创建一个单独的服务,一个 AWS Lambda 服务来添加对 NPM 依赖项的支持。对于这个 Lambda 服务,我们会说,例如,我想要 Lodash。Lambda 将安装 Lodash。然后它将查看哪些文件很可能需要运行依赖项。所以它会查看入口点。

例如,Lodash 会说,我的入口点在 source/index 中。然后我们将查看该文件,并查看该文件中的所有这些导入。我们将再次经历创建依赖关系图的相同过程。我们将确保只包含运行主依赖项所需的文件。我们还将将其作为 JSON 发送回捆绑器本身。

如果用户随后需要此包中未包含的文件,那么我们将从名为 Unpackage 的服务手动下载该单个文件,该服务托管 NPM 依赖项的文件。所以当我提到安装依赖项时,

编辑器唯一要做的事情是将 Lodash 添加到依赖项列表中。但最终,捆绑器是调用服务下载该依赖项所需文件的一个。所有这些都缓存在 Redis 中吗?这缓存在 S3 中。是的,这是后来才出现的。它的工作方式非常有趣。

因为处理依赖项本身就是一个非常有趣的挑战。例如,如果你安装依赖项 A,它需要 Lodash 版本 2,然后你安装依赖项 B,它需要 Lodash 版本 3,你如何才能使其工作?或者如果你安装依赖项 A,它需要 Lodash 版本 3。

任何 2 中的版本,然后你安装依赖项 B,它需要 Lodash,特别是版本 2.5。你将如何确保这两个版本都获得 Lodash 2.5 以在下载方面最有效率?因此,构建这个动态

npm install 服务存在一些非常有趣的挑战。因此,我们不仅仅缓存单个依赖项。我们还缓存依赖项的组合,例如 React 和 React DOM。我们缓存了组合的、合并的包。但我们还缓存了 React、React DOM、Lodash 和 React 图标,例如,作为组合包,这样我们就不必每次都重新计算这些组合。是的,这个存储桶很大。我认为它有几 TB。是的。

因此,用户使用常见的包组合会带来好处。例如,如果我使用 React 和 React DOM 的方式与其他人相同,那么在我发出安装请求之前,它就已经预先缓存了。是的,当然。而且人们经常会使用,我认为 React 和 React DOM 是最常见的组合。所有这些,整个 S3 存储桶都被缓存了,Cloudflare 位于它的前面。

因此,由于这个原因,我们对 S3 的请求也很多。所以依赖项安装非常有趣。如果你尝试安装,如果你想使用之前被其他用户使用过的依赖项组合运行沙箱,那么……

安装将在 1 秒内完成。这只是从 S3 存储桶下载文件的问题。它已经被预先捆绑了。有时我们甚至会对源文件进行预转换,以使其运行速度更快,这样捆绑器就不必再对其进行转换了。我们甚至会为每个文件存储信息,例如什么

依赖关系图,你还可以将依赖关系图嵌入到依赖关系中,以了解哪个文件导入哪个文件。因此,捆绑器也将节省工作。捆绑器不必再解析所有这些文件来运行代码了。这是有趣的事情。你可以将其视为超快的 NPM,因为依赖项组合……

你很可能正在使用之前被其他人使用过的依赖项组合。在这种情况下,你只需要从 S3 存储桶下载该文件即可。好的,我们已经涵盖了大部分堆栈。我们快结束了。我们有数据库以及围绕它的相关 S3 和 Redis 缓存。当我发出安装请求时,你那里有一堆启发式方法和策略,所有这些都以某种转换后的捆绑形式发送到客户端。

然后你在客户端有两个应用程序,编辑器和预览器或查看器。每当编辑器导致文件更改时,我们都会向 iframe 发送 post message 以根据需要评估代码。我想最后一点我想谈谈编辑器本身,因为这本身就是一个完全独立的复杂且有趣的应用程序。在浏览器中工作的代码编辑器,它是如何工作的?

我认为这是该特定堆栈中最复杂的部分。编辑器的第一个版本非常简单。它都是 React 组件。例如文件资源管理器是 React 组件。编辑器本身,代码编辑器是 CodeMirror,这是一个由荷兰人创建的库。后来,我们将代码编辑器迁移到 Monaco。Monaco 是 VS Code 的一小部分。VS Code……

拥有令人难以置信的代码库,是我见过的最好的代码库之一。它具有非常好的构成。它具有非常好的 API。你已经可以看到它如此出色

因为他们能够从 VS Code 中提取核心编辑器并将其制成库,并相对轻松地使其与 VS Code 保持同步。所以 Monaco 就是这样。它本质上是 VS Code 编辑器,但作为库公开。

它没有 VS Code 的所有花哨功能,例如扩展支持或文件资源管理器或所有这些。它只有编辑部分,但它可以工作,而且工作得非常好。所以我们迁移到 Monaco,因为它具有更好的,嗯,它为所有使用 VS Code 的人提供了更熟悉的体验。当 CodeSumbo 启动时,

Atom 是最流行的编辑器,但后来 VS Code 成为最流行的编辑器。但总有一些情况,人们想知道他们是否可以像 VS Code 一样做同样的事情。代码编辑器是一项极其复杂的技术。你拥有诸如命令面板之类的功能,你拥有键绑定,你拥有主题,因为开发人员想要主题。你拥有所有小事物的设置,例如行高、字体大小、字体本身以及

当按下所有键时编辑器应该如何表现

Alt 并移动光标。多光标应该如何工作?所有这些,有很多设置。然后你拥有扩展,扩展会改变编辑器行为或添加新的编辑器行为。因此,代码编辑器是有史以来最雄心勃勃的 UI 之一。这是一件令人难以置信的事情。你学到了很多东西。哦,还有性能。仅仅使其具有高性能,例如当你点击一个文件时,它可以在 10 毫秒内打开该文件。非常困难。

最初,我们使用 Monaco 完成所有工作。我们围绕它构建了自己的 UI。Monaco 是核心编辑器,但我们有自己的 UI。正因为如此,我们能够创造许多自定义体验。但后来,我开始越来越关注 VS Code。在 2018 年,在我 Facebook 实习期间,我正在寻找一种方法让 VS Code 在浏览器中运行。

VS Code 当时无法在浏览器中运行。最初,VS Code 是为了在浏览器中运行而构建的,但它的性能不够好。所以他们将 VS Code 制成一个 Electron 应用程序。它使用 Web 技术来呈现 VS Code 的 UI,但它没有在浏览器中运行,因为它确实使用了诸如 Node 文件系统、许多 Node API 之类的东西。

所以我正在研究我们是否可以使用 VS Code 代码示例,因为这将节省大量工作。它将为开发人员创造熟悉感,例如他们自己的自定义键绑定,这些事情。我们将开始允许扩展。它会更快,因为最终 VS Code 比 React 快得多,主要是因为 VS Code 是命令式的而不是声明式的。它将有很多好处。

因此,让 VS Code 在浏览器中运行最终归结为在浏览器中模拟 Node,因为 Node 最终是带有原生 Node 模块的 JavaScript。例如,文件系统、网络、HTTP、操作系统,所有这些 Node 模块。如果你创建一个可以在浏览器中运行的浏览器等效版本,那么你实际上是在重新实现 Node,并且你正在欺骗 VS Code 认为它正在你的本地计算机上运行,但它正在浏览器中运行。

所以最初我这样做是为了让 VS Code 在浏览器中运行。后来,VS Code 团队实际上将 VS Code 移植回浏览器。现在使用 Code Sandbox,我们正在运行 VS Code 的浏览器版本。

我们仍在模拟一些节点组件,有时在浏览器中运行扩展。但是,例如,如果存在虚拟机,那么我们将使用 VS Code Server,以便你拥有原生的 VS Code 体验。但我们确实有一个小的附加组件添加到 VS Code 上,它允许我们在 VS Code UI 中呈现 React 组件。这允许我们仍然使用 React 创建自定义体验。

但在 VS Code 的上下文中。那么这如何与类型信息一起工作呢?假设我想将鼠标悬停在 Lodash 上,从 Lodash 导入它,并查看其下可用的方法。

是的,这是一个非常有趣的问题。因此,如果我们查看 Devbooks 版本,它非常简单,因为 VS Code Server 从文件系统获取文件。事实上,扩展,TypeScript 扩展在服务器本身运行,它将读取文件。这有点像一个已解决的问题。但是对于完全在浏览器中运行的沙箱,我们有一个稍微有趣一点的解决方案。

我们在浏览器中运行 VS Code 扩展。这些 VS Code 扩展程序期望在节点环境中运行。他们期望拥有。当他们执行 require FS 时,他们期望 FS 模块可用。他们希望能够运行读取文件、读取文件、读取目录、写入文件,所有这些事情。

所以我们做的第一件事是实现文件系统,然后在浏览器中运行。所以我们可以在浏览器中运行 VS Code 扩展。他们会认为他们在 Node 环境中,但他们正在浏览器中运行。第二件事是,每当你安装像 Lodash 这样的依赖项时,我们都会做与我们为捆绑器所做的事情相同的事情。我们有一个服务,它

调用 Lodash 的 npm install。然后它查看安装的所有类型文件。它将再次创建一个 JSON 包,该包只包含所有类型文件。所以只有 .ts 文件或 .ts 文件。然后在浏览器中,我们将下载此包,并将所有这些文件写入我们的内存文件系统,我们称之为内存文件系统。所以这是我们在浏览器中创建的伪文件系统。

然后当 TypeScript 扩展运行时,它将再次认为它在 Node 环境中,并且它将从 Node 模块读取文件。这些文件,所有这些文件都来自这个浏览器内文件系统,该文件系统是由这个依赖项打包程序填充的。为了澄清,这与运行时 JS 文件服务是不同的服务吗?是的,是的。但它共享了很多代码。

我实际上是从依赖项包中复制了代码,然后更改了一些内容以使其更适合类型获取。我必须说,这就是它在过去六年的工作方式。而最近我做了一个改变,我们实际上直接从 NPM 下载 tar 文件。成千上万的文件变得越来越好。在这一点上,

在浏览器中解压 gzip tar 文件非常快。因此,对于许多依赖项,我们不再访问我们自己的服务器了。我们实际上直接从 npm 注册表下载 tar 文件,然后在内存中解压它,然后保存它。效率略低,但我们必须这样做,因为我们一半的带宽使用量都来自这个类型因子。

Cloudflare 告诉我们必须升级到更昂贵的套餐。我当时想,如果我们直接从 NPM 注册表下载,是不是就不需要为这些 bundle 的带宽付费了?有趣的是,

正因为如此,我们大幅降低了 Cloudflare 的账单。但 Cloudflare 支持 NPM 注册表。所以 Cloudflare 本身并没有注意到带宽的变化。事实上,带宽增加了,因为现在 tar 文件不会创建这些完美的类型 bundle。但至少我们不用为那部分带宽付费了。微软拥有 NPM。如果他们想减少这部分费用,他们可以随时向 NPM 添加一个功能来帮助你。

是的,这是真的。这很有趣。在 2017 年或 2018 年,解压 GZIP tar 文件肯定非常低效。但现在你有了,我认为这是一个浏览器功能,叫做解压缩流之类的东西,这使得它非常快,因为最终它使用了计算机的原生解压缩。浏览器是如何让这些事情成为可能的,这真的很棒。而且随着时间的推移,越来越多的堆栈正在内置。没错。

我甚至要说,如果我今天要重建 CodeSandbox,我可能不会像今天这样构建 bundler,因为现在一切都基于 common JS 和这个 require 覆盖。我认为如果我今天构建它,我会使用浏览器的 ES 模块功能

然后也许使用一个类似于 feed dev server 的 service worker。每当你尝试下载一个文件,一个 JavaScript 文件时,我们的 service worker 可能会转换该文件并将其返回。但是执行和捆绑是由浏览器完成的。不再是我们了。我们甚至不会使用 eval。是的,它本质上将是完全的 ESM。它就像,

一个 Vite。如果我要重写所有内容,我会这样做,因为它更适合浏览器,而且无论如何世界都在转向 ESM。最终。对。最终会这样。这需要一段时间。你认为你将来几年会有时间尝试一下 CodeSandbox 的完全浏览器 bundle 和 transpiler 吗?是的。如果没有人做过的话。

这也是一个很大的问题,因为我认为这是一个很大的机会,我可以理解人们会去探索它。目前,bundler 的工作方式非常好。我有点担心,如果我完全使用这个重写它,我们会引入 bug。这仍然是一个有趣的实验。

是的,这是我想探索的事情。我已经考虑过一段时间了,但我不知道什么时候会去探索它。你还有什么长期探索的目标,如果你有时间的话?嗯。

我发现我们现在拥有的用于开发环境的整个 firecracker 堆栈非常有趣的一点是,我认为我们可以在一秒钟内克隆一个虚拟机,我们可以在一秒钟内恢复一个虚拟机,这是一项非常强大的技术。

这不仅适用于开发环境,也适用于 CI/CD 系统,甚至部署。是的,我认为这项技术有很多不同的用例。我很想将这个基础设施泛化,以便人们可以将其用于其他目的。

这超出了云开发环境的范围。是的,我认为它非常强大。它可以用于更多用途。所以这是我发现非常有趣的事情,例如,使我们今天拥有的基础设施开源,使它足够通用,以便人们可以将其用于他们自己的用例。许多公司,许多项目都有项目

CI/CD 时间,你有一些,比如说六个任务。每个任务在 NPM 或 PNPM 或 yarn install 中花费 20 秒,然后在任务本身中花费 3 秒。这非常令人沮丧。这是非常浪费的。是的。而这项技术,我当时在想,你可以,例如,你可以做的一件事是

你可以完成 CI/CD 需要做的所有准备工作,然后创建一个快照。每当你需要进行 CI/CD 运行时,它将从该快照继续执行。它只会拉取最新的代码,然后运行测试。但对于并行化也是如此,例如,如果你想在一个 12 个不同的 worker 上运行测试套件,你可以做的是创建一个快照。你可以在一个虚拟机上完成所有准备工作。

之后,你将这个虚拟机克隆 12 次,所有这 12 个虚拟机并行运行测试套件的不同部分。我们甚至支持的一件事,或者我们从未部署过,但它是一个我构建的实验,就是你甚至可以通过网络克隆虚拟机。所以你在一台机器上运行一个虚拟机,然后

另一台机器启动该虚拟机的克隆,它们使用网络来同步虚拟机之间的内存。这也是一种能力。然后你真的可以考虑,如果你有一个 CI/CD 集群,比如说有 20 台服务器那么大,你可以在一台

在一台机器上进行准备,然后将该机器克隆到其他 20 台机器,它们使用单个服务器完成的准备工作的结果来运行所有 1/20 的测试堆栈。这样做实际上在时间和计算方面都是值得的。是的,我认为是这样。这只是一个想法。就像你可能会发现一些在实践中行不通的东西,但这在尝试事情时总是会发生。我还想知道,例如,现在

正在进行大量的研究,研究如何使用数百台服务器同时高效地训练 AI 模型。因为最终这是最大的挑战。例如,如何在数据中心扩展如此之多、如此多的计算和数据传输?我认为他们面临的挑战并不相同,但它们在类似的方面,至少这是一个有趣的、有趣的领域。

鉴于你所有的缓存,我多久才能在我的 CodeSandbox 上运行我的 CI 作业?我认为不会很快。最好探索不同的用例并改进堆栈本身的不同功能。事实上,你今天已经可以运行你的 CI/CD 了。只是该平台还没有为此而构建,但我们可以公开一个 API,或者你甚至可以创建一个运行 CI/CD 的开发盒。让我们拭目以待。

假设明年。明年你可以问我,我可以运行 CI/CD 吗?然后我会说,是的,我们有这个 API。然后你可以给它一个 Docker 镜像,它将运行你的代码。我们一年后再见。

AI 模型也是如此。这次对话已经比我们典型的 SED 采访时间长了,因为你有太多令人着迷的技术要谈论。我想以一个不太技术性,也许仍然令人着迷的关于你个人观点的说明来结束。你能告诉我们一些关于排球以及为什么它是一项如此棒的运动吗?

是的,我之前提到过。在我的空闲时间,我做了很多排球运动。排球是我大约九岁的时候开始做的。我做了很多。在高中期间,我做了非常非常多。如果用文字来表达的话,我认为我每周训练六次。高中期间我有点厌倦了。我有点,我想,太有竞争力了。

所以我停了一段时间,没有做多少排球。但我最近又开始做了,我想是一年前。是的,大约一年前。打排球真是太好了,因为当我训练或比赛的时候,我完全忘记了一切。就像周围的一切。比如我可能会担心一些事情,但是当我打排球的时候,我什么都不担心。我只担心球。所以从心理学的角度来看,这非常好。

优势,而且我现在也更健康了。第二天因为运动我感觉更有活力。所以是的,我很喜欢排球。这对我来说是一种提醒,提醒我不仅要整天编程或开会。最终,保持健康和锻炼也很重要。

我认为很多人可能打过高中排球,只是在体育馆里闲逛,也许和朋友们一起打过一些休闲沙滩排球。你所参与的排球领域和品牌与我们只是尴尬地站在那里等待球过来有什么不同?哦,你的意思是是什么让它变得很快?是什么让它成为一个很好的锻炼?你知道,你在做什么?

当我打排球时,我大部分时间都在地上,我想。有很多跳水动作。比如,如果你想拿到一个球,而它刚好够不着,你就会跳。最近我也开始……

在打排球时追踪我的心率,看看它有多剧烈。我现在已经做过两次了,当我打排球时,我的心率会达到 195。这真的,尤其是在网前,你也会跳很多,例如,当我们打排球时,如果我打中路,你要做的事情是,每当二传手拿到排球时,就像每当球传给二传手时,你必须跳起来

假装进攻。所以每当二传手拿到球时,你都要跳,因为这样你就可以迷惑对手,让他们搞不清楚球会从哪里进攻,从而迷惑拦网手。所以你可以跳……

在一轮比赛中,你可以跳两三次,然后有 40 轮比赛,那就是四次,160 次。是的,在一场比赛中你会跳 350 次左右。从这个意义上说,它非常激烈。它非常具有爆发力。没有长时间的奔跑,但是……

它需要很多短时间的能量爆发。听起来很激烈。它也很有心理策略性。你并没有关闭你的大脑。你仍在思考。是的,这是真的。有很多预测在进行。比如你可以迷惑你的对手。他们可以迷惑你。但我最喜欢的是它的竞争性。比如,

赢得比赛或输掉比赛。这使得它比例如跑步更有趣。我现在也经常跑步,但是对我来说,就运动而言,我发现只有当它是一场竞争时,才会让我兴奋,我想。很好。这次采访绝对精彩绝伦。Ivis,非常感谢你向我们介绍 CodeSandbox 的启动、后端、数据库、缓存层、

前端,这些东西太多了,如果大家想了解更多关于你和 CodeSandbox 的信息,你会把他们引向哪里?我的 Twitter 是我最活跃的地方,我认为那是 computeives c-o-m-p-u-i-v-e-s

那是我的 Twitter。CodeSandbox 可以在 CodeSandbox.io 或 CodeSandbox.com 或 CodeSandbox.org 上找到。这是一个小细节。我们选择了 CodeSandbox.io,因为该域名只有 30 美元,而 CodeSandbox.com 是 3000 美元。但后来,一位学习使用 CodeSandbox 编程的律师将 CodeSandbox.com 域名赠送给了我们。这就是我们最终获得 CodeSandbox.com 域名的方式。好吧……

总而言之,这是 Josh Kulberg 和 Yves Van Horne 与 Software Engineering Daily 的对话。谢谢大家。干杯。谢谢。