Placeholder Image

字幕列表 影片播放

由 AI 自動生成
  • The first stage of VEET really was like, let's just make things work and make it better than the status quo, but underneath there might be a lot of, you know, hacks and things we want to improve in the future.

    VEET 的第一階段就像是,讓我們把事情做好,讓它比現狀更好,但在這背後可能有很多,你知道的,黑客和我們希望在未來改進的東西。

  • And now it's the proper time to do it.

    現在正是時候。

  • Hello, welcome to DevTools FM.

    您好,歡迎來到 DevTools FM。

  • This is a podcast about developer tools and the people who make them.

    這是一個關於開發者工具和開發者的播客。

  • I'm Andrew.

    我叫安德魯

  • And this is my cohost, Justin.

    這是我的搭檔,賈斯汀。

  • Hey everyone.

    大家好

  • We're really excited to have Evan Yu joining us again.

    埃文-於(Evan Yu)能再次加入我們,我們感到非常興奮。

  • Evan, you were with us on episode 12 back a few years ago talking about VUE and VEET.

    埃文,幾年前,你曾在第 12 集裡和我們一起談論過 VUE 和 VEET。

  • And we are now like 119 as of recording.

    目前,我們已經錄製了 119 個節目。

  • So over a hundred episodes ago.

    那就是一百多集以前的事了。

  • Wow.

  • That's, that's a lot of episodes.

    這是,這是很多集。

  • We've been doing it a while, but it's, it's so fantastic to have you back.

    我們已經做了一段時間了,但你能回來真是太好了。

  • We are continually big fans of your work and how it shapes the ecosystem.

    我們一直非常欣賞您的作品,以及您的作品對生態系統的影響。

  • So excited to chat again.

    很高興能再次哈拉。

  • And we're going to talk about what you're up to these days.

    我們要談談你最近在忙什麼。

  • But before we dive into that, would you like to tell our listeners a little bit more about yourself?

    在我們深入探討之前,您願意向聽眾介紹一下您自己嗎?

  • Sure.

    當然。

  • Hi, I'm Evan.

    嗨,我是埃文

  • I am, I have been an independent open source developer since 2016.

    我是,我從 2016 年開始成為一名獨立的開源開發者。

  • And I worked on VUE.

    我在 VUE 工作過。

  • I still actually still work on VUE.

    實際上,我現在還在為 VUE 工作。

  • I work on VEET.

    我在 VEET 工作。

  • And just recently we started a company called Void Zero and focus a bit deep, even deeper that goes into, you know, the full JavaScript tool chain, starting from servers, no, no, no, starting from parsers to linters, formatters, bundlers, transformers, everything that supports higher level tooling.

    就在最近,我們成立了一家名為 Void Zero 的公司,專注於更深入的領域,你知道,整個 JavaScript 工具鏈,從服務器開始,不,不,不,從解析器到精簡器、格式化器、捆綁器、轉換器,所有支持更高級工具的東西。

  • So the bundler we're building called Rodan is going to support VEET in the future.

    是以,我們正在構建的名為 "Rodan "的捆綁程序未來將支持 VEET。

  • And VEET is now supporting a lot of other frameworks.

    VEET 現在還支持許多其他框架。

  • So essentially we're trying to build this vertical unified tool chain that can support all the frameworks that depend on VEET today and hopefully make everyone's development experience better.

    是以,從本質上講,我們正試圖構建一個垂直統一的工具鏈,以支持目前依賴 VEET 的所有框架,並希望讓每個人都能獲得更好的開發體驗。

  • So back, back on that old episode, a long ago, you had actually just released VEET.

    在很久以前的那期節目中,你剛剛發佈了《VEET》。

  • And since then it's really become like a pillar of the industry.

    從那時起,它就真正成為了行業的支柱。

  • Like many a meta framework is based on it now.

    就像現在很多元框架都以它為基礎一樣。

  • And it's like the starter pack for everything.

    它就像是一切的入門包。

  • What was the journey from getting, going from VEET to, oh, we actually have to rebuild most of what's below the surface level and form a company around that?

    從獲得 VEET 到 "哦,我們實際上必須重建大部分地表以下的東西,並以此為基礎成立一家公司",這中間經歷了怎樣的過程?

  • Yeah.

    是啊

  • I think the idea started at one point because when I first started VEET, I was just doing a prototype, honestly, right?

    我認為這個想法始於某個時刻,因為當我第一次啟動 VEET 時,老實說,我只是在做一個原型,對吧?

  • So I pretty much just took whatever that's available out there and try to fulfill the goals.

    是以,我幾乎是隨心所欲,想方設法實現目標。

  • And there were a lot of trade-offs and nowadays I consider them kind of hacks because I didn't have the, you know, the bandwidth to do all the things myself.

    這其中有很多取捨,如今我認為這些都是 "黑客",因為我沒有足夠的帶寬來自己完成所有的事情。

  • So I have to use what other people have built.

    是以,我必須使用別人的成果。

  • And that's, I think that's typically what we've been doing in the Java ecosystem because we feel like, okay, like we don't want to necessarily reinvent the wheels.

    我認為,這就是我們在 Java 生態系統中一直在做的事情,因為我們覺得,好吧,我們不一定要重新發明輪子。

  • Why not just use things people have already done?

    為什麼不利用人們已經做過的事情呢?

  • So in the beginning we were, I was using Rollup because I've always liked Rollup's

    所以,一開始我們使用 Rollup,因為我一直喜歡 Rollup 的

  • API and then we ran into performance issues because, so the first step of VEET was to have a native ESM dev server, right?

    API 然後我們遇到了性能問題,因為 VEET 的第一步就是要有一個在地的 ESM 開發服務器,對嗎?

  • That sounds simple.

    聽起來很簡單。

  • And then we use Rollup to try to handle the dependencies because some dependencies are in CJS.

    然後我們使用 Rollup 來嘗試處理依賴關係,因為有些依賴關係在 CJS 中。

  • We want to convert them to ESM so they can load in the browser.

    我們希望將它們轉換為 ESM,以便在瀏覽器中加載。

  • But Rollup was actually quite slow if you have large dependencies.

    但如果有大量的依賴關係,Rollup 的運行速度實際上相當慢。

  • And so we started using ESBuild for that purpose.

    為此,我們開始使用 ESBuild。

  • And then we tried using ESBuild for production bundling and it was not satisfactory because it has no control over how the chunks are split.

    然後,我們嘗試使用 ESBuild 進行生產捆綁,但效果並不理想,因為它無法控制如何分割分塊。

  • And the way ESBuild splits code is just a bit counterintuitive if you're building applications.

    如果你正在構建應用程序,那麼 ESBuild 分割代碼的方式就有點違反直覺了。

  • So we're like, okay, now we need to think about, okay, we use ESBuild for development and pre-bundling, but we use Rollup for production bundling.

    所以我們想,好吧,現在我們需要考慮一下,好吧,我們使用 ESBuild 進行開發和預捆綁,但使用 Rollup 進行生產捆綁。

  • And we kind of smoothed over the surface to make them work kind of the same way.

    我們對錶面進行了平滑處理,使它們以同樣的方式工作。

  • Right?

    對不對?

  • And later on when people started building real applications with VEET, for example, when people are using VEET with React and previously everyone was using Babel because Babel was supported.

    後來,當人們開始使用 VEET 構建真正的應用時,例如,當人們將 VEET 與 React 結合使用時,而之前大家都在使用 Babel,因為 Babel 得到了支持。

  • Interestingly, if you use VEET by default and you write JSX in TypeScript, they are transformed using ESBuild, which is quite fast.

    有趣的是,如果您默認使用 VEET,並用 TypeScript 編寫 JSX,那麼它們會使用 ESBuild 進行轉換,速度相當快。

  • But the moment you want hot module replacement for React, now you need to use Babel because ESBuild does not support hot module replacement transforms.

    但是,一旦你想對 React 進行熱模塊替換,現在就需要使用 Babel,因為 ESBuild 不支持熱模塊替換轉換。

  • So then Babel, again, made everything slow.

    於是,巴別塔又一次讓一切變得緩慢。

  • So people also came up with an SWC version of the React plugin.

    是以,人們還開發了一個 SWC 版本的 React 插件。

  • So you see the problem here is there are great tools out there, but some of them do this, some of them do that.

    是以,你會發現問題所在,現在有很多很棒的工具,但其中有些會做這個,有些會做那個。

  • And now some of the things they both do, they decide to do them differently.

    現在,他們都會做的一些事情,他們決定用不同的方式去做。

  • And that's the reality that we're kind of dealing with in a JavaScript tooling ecosystem.

    這就是我們在 JavaScript 工具生態系統中所要面對的現實。

  • I'm pretty sure if you've worked with custom build stacks long enough, you understand what I'm saying, right?

    我敢肯定,如果你使用自定義堆棧的時間足夠長,你就會明白我在說什麼,對嗎?

  • So in a lot of ways, the reason people love VEET is because we kind of hide this complexity away from them and try to give you a very smooth and consistent entry point so that you don't need to think about these things.

    是以,從很多方面來看,人們之所以喜歡 VEET,是因為我們將這種複雜性隱藏起來,並試圖為您提供一個非常順暢和一致的切入點,這樣您就不需要考慮這些事情了。

  • But we're kind of, for me, I think we achieved this goal with the initial version of VEET, but long term wise, when people are starting putting more and more dependence on VEET, right, we've seen more and more frameworks moving over to use

    對我來說,我認為我們通過 VEET 的初始版本實現了這一目標,但從長遠來看,當人們開始越來越依賴 VEET 時,我們已經看到越來越多的框架轉而使用 VEET。

  • VEET as the base layer, I kind of start to worry because I feel like, you know, the internal is not as pretty as it should be.

    VEET 作為基礎層,我開始有點擔心,因為我覺得,你知道,內部並不那麼漂亮。

  • And we kind of just swept all the deeper problems under the rug and pretend everything is great.

    我們把所有深層次的問題都掩蓋起來,假裝一切都很好。

  • So I guess deep down, you know, along with VEET's growth and adoption, I've always had this, like, inner urge to say, like, is it really up to the task of being the future of all these, like, next generation frameworks serving as the infrastructure?

    是以,我想在內心深處,你知道,隨著 VEET 的發展和採用,我一直有這樣一種內心的衝動,比如說,它真的能勝任作為所有這些下一代框架基礎設施的未來任務嗎?

  • Will VEET be able to live up to that expectation?

    VEET 能否不負眾望?

  • And I don't think it will if we just keep using this sort of fragmented internals and try to stitch things together and smooth all of the inconsistencies.

    我認為,如果我們繼續使用這種支離破碎的內部結構,並試圖將所有東西拼接在一起,消除所有不一致的地方,那是不可能的。

  • In a way, the tool chain we're building right now at Voice Zero is an attempt to kind of attack this problem more fundamentally.

    從某種程度上說,我們現在在 "零點之聲 "建立的工具鏈就是試圖從根本上解決這個問題。

  • Let's say, like, if we want to solve all the problems we want to fix in VEET, what do we need? We need a bundler that actually is designed for it.

    比方說,如果我們想解決我們想在 VEET 中解決的所有問題,我們需要什麼?我們需要一個真正為此而設計的捆綁程序。

  • And we need this bundler to be also built on top of a tool chain that can, you know, handle all the different concerns, like starting from the AST all the way to minification and production, bundling, right, through a consistent system.

    我們需要這個捆綁程序建立在一個工具鏈之上,這個工具鏈可以處理所有不同的問題,比如從 AST 開始,一直到最小化、製作、捆綁,對吧,通過一個一致的系統。

  • And at the same time, we also want to make each part of this tool chain individually usable.

    與此同時,我們還希望這個工具鏈的每個部分都能單獨使用。

  • So let's say you want to just take the parser and do something crazy with it.

    比方說,你想利用解析器做些瘋狂的事情。

  • You can totally, you should be able to do that, right?

    你完全可以,你應該可以做到,對嗎?

  • This tool chain, although it's unified and it's a coherent system, it should not be a black box, right?

    這個工具鏈雖然是統一的,是一個連貫的系統,但它不應該是一個黑盒子,對嗎?

  • You should not have to say, like, you either take it all or you can never use it.

    你不應該說,要麼全拿走,要麼就永遠用不上。

  • So I think that's, these are the two main premises that we're sort of centering the tool chain around is unification, but without sacrificing the ability to, of composability.

    是以,我認為這是我們將工具鏈置於中心位置的兩個主要前提,即統一,但又不犧牲可組合性。

  • We'd like to stop and thank our sponsor for the week, Mux.

    在此,我們要感謝本週的贊助商 Mux。

  • If you haven't heard of Mux, Mux is an awesome platform that makes adding video to your product easy as adding a few libraries.

    如果你還沒聽說過 Mux,Mux 是一個非常棒的平臺,它能讓你輕鬆地為產品添加視頻,就像添加幾個庫一樣簡單。

  • If you never had to add video to a product, you don't know how many pits of failure there are, whether it's file formats, delivery, uploads, or even playback.

    如果你從未在產品中添加過視頻,你就不會知道有多少失敗的隱患,無論是文件格式、傳輸、上傳,甚至是回放。

  • There's so much to worry about and so much that will bog your team down while trying to ship a stellar product.

    有太多需要擔心的事情,有太多的事情會讓您的團隊在努力推出一流產品的同時陷入困境。

  • So that's where Mux comes in.

    這就是 Mux 的用武之地。

  • They have a set of APIs and components that make adding video playback to your app or platform super easy.

    它們擁有一套 API 和組件,可讓您在應用程序或平臺中添加視頻播放功能變得超級簡單。

  • And since there are a bunch of experts that know video inside and out, they'll have so many different features that your team would never have the time to get to.

    由於有一群對視頻瞭如指掌的專家,他們會提供許多不同的功能,而你的團隊根本沒有時間去了解這些功能。

  • One of those things being metrics, they have all sorts of different fancy metric dashboards to understand how people are consuming video in the apps that you ship.

    其中之一就是衡量標準,他們有各種不同的花哨的衡量標準儀表板,可以瞭解人們是如何在您所提供的應用程序中消費視頻的。

  • Recently, they've been adding even more capabilities to their platform.

    最近,他們正在為自己的平臺增加更多的功能。

  • Now you can see when viewers dropped from your videos, so you can gain better insight into how people are consuming those videos.

    現在,您可以看到觀眾何時從您的視頻中退出,從而更好地瞭解人們是如何觀看這些視頻的。

  • So if you want to add video to your platform and you don't want to spend weeks to months doing it, head over to Mux.com.

    是以,如果您想在自己的平臺上添加視頻,又不想花費數週至數月的時間,請訪問 Mux.com。

  • And with that, let's get back to the episode.

    接下來,讓我們回到本期節目。

  • So you've been a independent developer for a while and probably one of the most successful, being able to work on a lot of open source projects and produce a lot of very successful open source projects while working mostly on your own.

    你做獨立開發者已經有一段時間了,而且可能是最成功的獨立開發者之一,能夠參與很多開源項目,並開發出很多非常成功的開源項目,同時大部分工作都是自己完成的。

  • And now you're going this route of, so you've raised some VC, you're forming Void

    而現在你要走的這條路是,你籌集了一些風險投資,你正在組建 Void

  • Zero, you have a few people coming to join you to like work on this ecosystem tooling.

    總部,有幾個人要加入你們,一起研究這個生態系統工具。

  • So why did you decide to make that transition from independent developer to starting a company?

    那麼,您為什麼決定從獨立開發者轉型為創辦公司呢?

  • And like, what about the timing or the circumstances made this a different choice?

    比如,是什麼時機或環境讓你做出了不同的選擇?

  • So I think overall, I would actually consider myself a pretty risk averse person.

    是以,我認為總的來說,我是一個非常厭惡風險的人。

  • Some of the biggest decisions I'd made in my life, I kind of feel like I just swinged it, but like going fully independent to work on Vue, I didn't really know what that would entail. Luckily, I think I built a lifestyle entrepreneurship, kind of lifestyle business thing around Vue.

    我人生中做過的一些重大決定,我覺得我就這樣做了,但就像完全獨立去做 Vue,我真的不知道那會帶來什麼。幸運的是,我想我建立了一種生活方式創業,一種圍繞 Vue 的生活方式商業。

  • So that is enough to sort of support me and make my life sustainable.

    是以,這足以支撐我的生活,使我的生活能夠持續下去。

  • So on top of that, right, I'm not starting a company because like, oh, we need to make more money. So that situation.

    除此之外,我開公司不是因為我們需要賺更多的錢。所以這種情況。

  • It's more about starting the company is the more realistic way to essentially fulfill the vision that I'm trying to achieve.

    更重要的是,創辦公司是實現我的願景的更現實的方式。

  • So it's also partly based on the experience of working as an independent developer.

    是以,這部分也是基於獨立開發人員的工作經驗。

  • I kind of know where the limit of the current model can go.

    我算是知道當前模式的極限在哪裡了。

  • I think a lot of people kind of use Vue and use me as a success story example for sustainability of any kind of projects.

    我認為,很多人都把 Vue 當作任何項目可持續發展的成功範例。

  • But at the same time, if you consider the scale, the scope of Vue, like we have more than two million users supported by, I think at max, we had like three people working full time on Vue related stuff.

    但與此同時,如果考慮到 Vue 的規模和範圍,比如我們有超過 200 萬用戶,我想最多的時候,我們有三個人全職從事與 Vue 相關的工作。

  • Like now it's probably still around three people that's actually full time on Vue.

    就像現在,真正全職負責 Vue 的人可能還只有三個左右。

  • And then a bunch of part time contributors that we sponsor.

    我們還贊助了一些兼職貢獻者。

  • So it's sustainable.

    是以,它是可持續的。

  • But at the same time, we don't really see it growing, say, to the scale where we can have like a team of 10 people working on it full time, right?

    但與此同時,我們並不認為它能發展到擁有 10 人團隊全職工作的規模,對嗎?

  • Because I intentionally try to build the business around Vue to be as passive and carefree as possible as a lifestyle choice.

    因為我有意將圍繞 Vue 開展的業務作為一種生活方式,儘可能做到被動和無憂無慮。

  • But also that means the conversion rate, because it's not a for-profit business, like we don't do aggressive marketing or we don't push features to sort of drive profit or revenue.

    但這也意味著轉換率,因為這不是一個以盈利為目的的企業,比如我們不會做激進的營銷,也不會為了推動利潤或收入而推送功能。

  • So in a lot of ways, the conversion rate compared to the user kind of view is extremely slow, extremely low, right?

    是以,在很多方面,與用戶的觀點相比,轉換率非常緩慢,非常低,對嗎?

  • And I'm not saying that's a bad thing.

    我並不是說這是件壞事。

  • For me, there's no sort of this or that in terms of open source sustainability or monetization.

    對我來說,在開源的可持續性或貨幣化方面,不存在這樣或那樣的問題。

  • I think it all comes down to the goal you're trying to achieve.

    我認為這取決於你想要達到的目標。

  • For me, Vue is a lifestyle business thing, and I think that's working very, very well for me, right?

    對我來說,Vue 是一種生活方式,我認為這對我來說非常有效,對嗎?

  • I'm happy about that.

    我為此感到高興。

  • But on the other hand, when I think about where Vite is going and thinking about the potential that Vite has and thinking about how we can actually maximize that potential and make the thing, you know, we hope it can be.

    但另一方面,當我想到維特公司的發展方向,想到維特公司所具有的潛力,想到我們如何才能真正最大限度地發揮這種潛力,讓我們希望的東西成為現實。

  • And I don't see it happening with this sort of more passive model of like just hoping people donate, helping people sponsor, or hoping someone comes up with a business and decides to donate back to Vite, right?

    我不認為這種比較被動的模式會發生,比如只是希望人們捐款,幫助人們贊助,或者希望有人做成生意並決定回饋給 Vite,對嗎?

  • That actually has a lot to do with, I think, partly with luck.

    實際上,我認為這與運氣有很大關係。

  • It takes time.

    這需要時間。

  • It also has a lot to do with what layer the project stands on.

    這也與項目所處的層級有很大關係。

  • For example, because Vue is a very user-facing framework, so most of the income that's generated by Vue is due to the exposure, due to the high exposure and documentation.

    例如,由於 Vue 是一個非常面向用戶的框架,是以 Vue 所帶來的大部分收入都來自於高曝光率和文檔。

  • And because when people use frameworks, they would likely interact with the documentation very, very constantly.

    因為當人們使用框架時,他們可能會經常與文檔進行交互。

  • BuildTools is quite different, right?

    BuildTools 有很大不同,對嗎?

  • It usually sits one layer below the framework.

    它通常位於框架下面一層。

  • And also, when you set up BuildTools, once you get it working, you're happy with it.

    此外,當你設置 BuildTools 時,一旦你能使用它,你就會對它感到滿意。

  • You really have to actually look at the docs every day.

    你真的必須每天都看文件。

  • So when we go even lower, say like we're building parsers and toolchains like that,

    是以,當我們在構建解析器和工具鏈等更低級的工具時、

  • I've seen how projects like Babel struggle with funding despite such wide, almost universal adoption across the ecosystem.

    我看到過像巴別塔這樣的項目是如何在整個生態系統中幾乎被廣泛採用的情況下,卻在資金方面舉步維艱。

  • So I don't think that model is going to work for the things we want to build.

    是以,我認為這種模式無法滿足我們的需求。

  • But at the same time, this is quite an ambitious goal.

    但與此同時,這也是一個相當宏大的目標。

  • So I can't imagine it being done with part-time efforts from just contributors who are like, oh, we want to work on this together.

    是以,我無法想象僅靠那些 "哦,我們想一起工作 "的貢獻者的兼職努力就能完成這項工作。

  • I don't think that's going to happen, or at least it's not going to happen soon enough.

    我認為這不會發生,至少不會很快發生。

  • So I think the only realistic way for us to actually do it is to have enough resource, capital, to get people paid properly to work on a full-time and as a team, right?

    是以,我認為我們要真正做到這一點,唯一現實的辦法就是擁有足夠的資源和資本,讓人們獲得適當的報酬,以全職和團隊的形式工作,對嗎?

  • So we have a common mission, a common goal, and it's much more serious than your, let's contribute to open source after work on weekends, right?

    是以,我們有一個共同的使命、共同的目標,它比你的 "週末下班後一起為開源做貢獻 "要嚴肅得多,對嗎?

  • It's different.

    這是不同的。

  • So that also inevitably brings in a question of expectations from investments and returns.

    是以,這也不可避免地帶來了投資和回報預期的問題。

  • And I think one of the other goals of starting the company is because I always felt like it's a bit sad that the JavaScript ecosystem is relying on a lot of critical infrastructure that's maintained by people that's either underpaid or just as labor of love, right?

    我認為創辦這家公司的另一個目的是,我總覺得 JavaScript 生態系統依賴於大量重要的基礎設施,而這些基礎設施的維護者要麼收入微薄,要麼只是出於熱愛而工作,這讓人感到有些悲哀,對嗎?

  • In a way, the ideal situation is we hope, okay, like big companies using these open source projects, making a lot of money, they should donate back, they should sponsor.

    在某種程度上,理想的情況是我們希望,好吧,就像大公司使用這些開源項目,賺了很多錢,他們應該回饋,應該贊助。

  • And I think it's difficult because there is so much logistics that you have to go through to actually set up the proper organization like a foundations and align the incentives.

    我認為這很困難,因為要建立像基金會這樣的適當組織,並調整激勵機制,你必須經歷大量的後勤工作。

  • And there's a lot of lobbying, a lot of like just talking to people and getting people on the same page and to make things like that happen.

    我們需要做大量的遊說工作,需要與人們交談,讓人們站在同一戰線上,才能實現這樣的目標。

  • And smaller open source project authors really don't have the leverage or the time and the energy to make that kind of thing happen.

    而規模較小的開源項目作者確實沒有足夠的籌碼、時間和精力去做這樣的事情。

  • And it's uphill battle before you absolutely become kind of the critical infrastructure the entire ecosystem relies on, right?

    在你絕對成為整個生態系統所依賴的關鍵基礎設施之前,這是一場艱苦的戰鬥,對嗎?

  • So I think Voice Zero is also a different attempt where the end goal we hold is we have a sustainable business model that's mostly coming from bigger companies, enterprise, that's paying money that allows us to keep improving these open source parts and keep it free and open source for individual users, for smaller companies, startups, so that more people have, more JavaScript developers have free access to high quality tools.

    是以,我認為 Voice Zero 也是一種不同的嘗試,我們的最終目標是建立一種可持續的商業模式,這種模式主要來自大公司和企業,它們支付的資金可以讓我們不斷改進這些開源部分,併為個人用戶、小公司和初創公司提供免費開源服務,從而讓更多人,讓更多 JavaScript 開發人員免費獲得高質量的工具。

  • At the same time, the tools should also be well sustained and maintained.

    與此同時,這些工具還應得到良好的維護和保養。

  • So is your plan for monetization, like charging bigger companies to use the tools and then like letting it be open source free for everybody else?

    那麼你們的貨幣化計劃是,向使用這些工具的大公司收費,然後讓其他所有人都能免費開源?

  • Not exactly.

    也不盡然。

  • So we want to draw a line where if the code runs on your machine, it should be open source and free, right?

    是以,我們要劃清界限,如果代碼在你的機器上運行,它就應該是開源和免費的,對嗎?

  • We don't want to do things like, so one thing we definitely don't do is to ship something as open source and change the license later and hope people pay for it.

    我們不想做這樣的事情,所以我們絕對不會做的一件事是,將某些東西作為開放源代碼發佈,然後更改許可證,並希望人們為此付費。

  • That's just not the plan.

    計劃不是這樣的。

  • The plan is likely to build, so we do have plans on building associated services that's tied into each step of the way, because when you have a toolchain, you have natural tie into a lot of metadata every step of the way.

    我們的計劃很可能是建立相關服務,並將其與每個步驟聯繫起來,因為當你擁有一個工具鏈時,你必須自然地將每個步驟與大量元數據聯繫起來。

  • And how do you get deeper insights from these metadata?

    如何從這些元數據中獲得更深入的見解?

  • And how can we get higher quality metadata for each task you're performing on your code base, right?

    我們如何才能為你在代碼庫中執行的每項任務獲取更高質量的元數據呢?

  • Overall, I think there's good opportunity to have, to improve upon what we're currently doing. For example, like how deep, how much deeper insights can we get from our bundles?

    總的來說,我認為我們有很好的機會來改進我們目前正在做的事情。例如,我們能從捆綁產品中獲得多深入的見解?

  • Like, is your tree shaking accidentally failing?

    比如,你的搖樹機是不是意外失靈了?

  • Is your chunk cache invalidation working consistently?

    您的塊緩存失效是否始終有效?

  • Are you bundling things that shouldn't really be in the production bundle?

    您是否捆綁了生產捆綁中不應捆綁的內容?

  • And is your code, after your code is transformed by all these tools, is it still as secure as the source code pretends to be?

    那麼,你的代碼在經過所有這些工具的轉換後,是否還像源代碼假裝的那樣安全呢?

  • There are a lot of questions that's hard to answer if you don't actually own the toolchain and be able to look at the source code from start, all the way back, all the way to minified in production that you actually ship to the users.

    如果你不能真正擁有工具鏈,不能從頭到尾查看源代碼,不能在生產過程中對源代碼進行最小化並實際交付給用戶,那麼很多問題都很難回答。

  • So I think there's quite a bit of opportunity here, and we're intended to essentially build services that center around this space.

    是以,我認為這裡蘊藏著巨大商機,而我們的目標就是圍繞這一領域提供服務。

  • I can't do, I don't want to be too specific right now because there's obviously a lot of things that can change.

    我做不到,我現在不想說得太具體,因為顯然有很多事情會發生變化。

  • There's obviously, you know, some details we're still working on.

    顯然,我們還在研究一些細節。

  • But the idea here is there will be, if we make money, it's from services.

    但我們的想法是,如果我們能賺錢,那也是靠服務。

  • It's not going to be from the open source stuff that we built directly.

    這不會是我們直接構建的開放源代碼。

  • And the open source toolchain obviously serves as the funnel and the mode for the services that we built. And that's the ideal outcome.

    而開源工具鏈顯然是我們構建服務的漏斗和模式。這就是理想的結果。

  • I think that makes a lot of sense.

    我認為這很有道理。

  • There is this like real thing of like big companies using open source tooling.

    大公司使用開放源碼工具的現象比比皆是。

  • It usually doesn't scale super well.

    它通常不能很好地擴展。

  • And if you've worked in a semi-large company and you've used Webpack, for example, and you know, like, oh, we have like a five to ten minute Webpack build.

    如果你曾在一家半大型公司工作過,並且使用過 Webpack,你就會知道,比如,哦,我們有一個五到十分鐘的 Webpack 構建。

  • Well, like most people don't experience that because their apps are too small.

    好吧,就像大多數人不會體驗到這一點一樣,因為他們的應用程序太小了。

  • But like if you're a really large organization and you're doing, you're bundling a lot of code and you're like running a lot of transforms and doing a lot of custom stuff, you start hitting in those things.

    但是,如果你是一個非常龐大的組織,你正在捆綁大量的代碼,你正在運行大量的轉換,做大量的自定義工作,你就會開始遇到這些問題。

  • So I think it makes sense to a large degree to say, hey, you've just got more needs and we have tools to sort of solve those needs, whereas, you know, 80 percent of people won't ever hit that scaling point.

    是以,我認為在很大程度上,說 "嘿,你有更多的需求,我們有工具來解決這些需求 "是有道理的。

  • Totally.

    完全是

  • Yeah.

    是啊

  • What a part of the part of the reasons we believe there is a market for this is because half the team is have worked at ByteDance on their Web Infra team, and they support some of the largest scale JavaScript applications that we have ever heard of in the industry.

    我們之所以相信它有市場的部分原因是,團隊中有一半人曾在 ByteDance 的 Web Infra 團隊工作過,他們支持一些我們在業內聽說過的規模最大的 JavaScript 應用程序。

  • And, you know, some code bases with a hundred hundred thousand lines of JavaScript code and takes half an hour to to build.

    要知道,有些代碼庫的 JavaScript 代碼多達十萬行,構建起來需要半個小時。

  • So scale that not every developer would have to ever deal with.

    這樣的規模,不是每個開發人員都必須面對的。

  • And but, you know, that's that's why a lot of the tools that we are building, like the starting from the OXC parser is like we are obsessed with the highest level of performance so that these tool can still handle the scale.

    但是,你知道,這就是為什麼我們正在構建的很多工具,比如從 OXC 解析器開始,我們就執著於最高級別的性能,以便這些工具仍能處理大規模問題。

  • The biggest scale application you can throw at it should be able to still do it with decent development experience.

    只要有豐富的開發經驗,再大規模的應用程序也能勝任。

  • So speaking of the OXC parser, I kind of find it funny that it seems like that project in itself started in the same way where like you were just creating a thing to for a side project.

    說到 OXC 解析器,我覺得很有趣,似乎這個項目本身也是以同樣的方式開始的,就像你只是在為一個副項目創建一個東西。

  • And I think Ocean, the guy behind OXC, was just kind of creating a reference implementation of a parser in Rust.

    我認為 OXC 的幕後推手 Ocean 只是在用 Rust 創建一個解析器的參考實現。

  • So how do we get from there to this is now like that one little Lego block at the bottom of the big structure that is void zero?

    那麼,我們是如何從那裡到達現在這個就像在虛空零這個大結構底部的一個小樂高積木一樣的地方的呢?

  • Yeah, I think a lot of it is me when we when I was thinking about, OK, we need to we need to write our own bundler for Vite.

    是的,我認為這在很大程度上是我的功勞,當時我在想,好吧,我們需要為 Vite 編寫自己的捆綁程序。

  • And what do we base the bundler on top of?

    捆綁程序的基礎是什麼?

  • And we looked at so there are multiple ways of thinking about this, right?

    我們研究了有多種思考方式,對嗎?

  • So rewriting JavaScript, no, because it's going to be too slow.

    所以重寫 JavaScript 不行,因為速度太慢。

  • So we want to do it in a comparative native language.

    是以,我們想用比較母語來做。

  • And we looked at Go, there's already ESBuild, which is a great project.

    我們研究了 Go,已經有了 ESBuild,這是一個很棒的項目。

  • I think the downside of ESBuild is in order to achieve the maximum performance, ESBuild is architected in a way where many different concerns are layered across as few AST passes as possible.

    我認為 ESBuild 的缺點在於,為了實現最高性能,ESBuild 在架構上將許多不同的關注點分層,儘可能減少 AST 的傳遞次數。

  • So it's like it's minification logic is actually spread across multiple passes.

    是以,它的最小化邏輯實際上是分散在多個通道中的。

  • And it's not like minification is minification.

    而且,"最小化 "並不就是 "最小化"。

  • It's like in the same AST pass, you would see some branches dealing with minification, some branches dealing with transforms.

    就像在同一個 AST 通道中,你會看到一些分支處理縮減,一些分支處理轉換。

  • And that making external contribute making like basically extending ESBuild in a reasonable way quite difficult, because you're going to be adding more branches in these AST passes.

    這就使得外部貢獻,比如以合理的方式擴展 ESBuild 變得相當困難,因為你將在這些 AST 過程中添加更多分支。

  • And it's going to be very difficult for for us to manage it.

    我們將很難應付。

  • Like Evan Wallace is obviously brilliant, and he has everything in his brain, and he can sort of improve ESBuild with this architecture, because that's his intentional decision.

    埃文-華萊士(Evan Wallace)顯然是個聰明人,他的大腦裡什麼都有,他可以用這種架構來改進 ESBuild,因為這是他有意為之的決定。

  • But we just feel like it's not a good foundation for us to if we want to ever extend on top of it.

    但我們覺得,如果我們想在此基礎上繼續發展,這並不是一個很好的基礎。

  • And also, we do want to make each part sort of well isolated so that people can use it as individual dependencies instead of having to opt into the whole thing at once.

    此外,我們還希望將每個部分都很好地隔離開來,這樣人們就可以將其作為單獨的依賴項來使用,而不必一次性選擇加入整個系統。

  • So then we turn to Rust.

    於是,我們轉向 Rust。

  • And so Fortune actually also contributed to RSPack at Bidens.

    是以,《財富》實際上也為 Bidens 的 RSPack 做出了貢獻。

  • And there are some technical decisions in RSPack that made it essentially too late for them to switch to RxE, because it's already kind of built on top of SFC for a very long time before RxE was even usable.

    RSPack 中的一些技術決策使得他們轉用 RxE 基本上為時已晚,因為在 RxE 可用之前,RSPack 已經在 SFC 的基礎上構建了很長時間。

  • But I have been keeping an eye on RxE for a very long time.

    但我關注 RxE 已經很久了。

  • And I think it is important that for the new toolchain to be based on something that kind of learns from a lot of the things that we've done in the past.

    我認為,新的工具鏈必須建立在從我們過去所做的大量工作中吸取經驗教訓的基礎之上。

  • Because when Boxu worked on RxE, he had contributed to Roam slash Vilem in the past as well.

    因為博克蘇在開發《RxE》時,也曾為《Roam slash Vilem》做出過貢獻。

  • They had to contribute to sRubyC and deal with sRubyC during RSPack development as well.

    他們還必須為 sRubyC 做出貢獻,並在 RSPack 開發過程中與 sRubyC 打交道。

  • So the team at WebInfra has a lot of experience dealing with, you know, Rust language toolchains and systems.

    是以,WebInfra 的團隊在處理 Rust 語言工具鏈和系統方面擁有豐富的經驗。

  • And I think he distilled a lot of the learnings into the development of RxE initially as a proof of concept.

    我認為,他在開發 RxE 的過程中提煉了很多經驗,最初只是作為概念驗證。

  • And when it became a bit more production ready, it showed that, okay, all these things did pay off, like both sRubyC and RxE are written in Rust, but there is a pretty significant performance advantage that RxE has.

    當它的生產準備就緒時,它顯示出,好吧,所有這些事情都有了回報,比如 sRubyC 和 RxE 都是用 Rust 編寫的,但 RxE 在性能上有相當大的優勢。

  • And there are some other design decisions that's a bit more detailed.

    還有一些其他的設計決定,就更詳細了。

  • For example, when using this language toolchain to support the bundler, there are a lot of semantic analysis that we have to do, for example, like determining whether this variable is referenced in this current scope, or is it, you know, shadowing the outer variable, or is it used and exported by and used in another module?

    例如,在使用該語言工具鏈支持捆綁程序時,我們必須進行大量語義分析,比如,確定該變量是否在當前範圍內被引用,或者,你知道,它是否對外部變量有陰影,或者它是否被另一個模塊使用和導出?

  • A lot of these kind of things, you have to do the analyzation, right?

    很多這樣的事情,你必須做分析,對嗎?

  • So in JavaScript, most of the parsers just, like, stops at giving you the AST, and they're done.

    是以,在 JavaScript 中,大多數解析器都是在給出 AST 之後就結束了。

  • So when we are dealing with, say, I think Babel probably provides a bit more infrastructure for that.

    是以,當我們處理比方說,我認為巴別塔可能為此提供了更多的基礎設施。

  • But in my own work, for example, in the Vue compiler, we have to do a lot of these semantics analysis ourselves.

    但在我自己的工作中,例如在 Vue 編譯器中,我們必須自己進行大量語義分析。

  • I think in Excel, Rich Harris has also written quite a few tools around this.

    我想在 Excel 中,Rich Harris 也編寫了不少相關工具。

  • But I believe that should be a first-party concern of a language toolchain.

    但我認為,這應該是語言工具鏈的第一關注點。

  • So RxE actually comes with a semantic analysis API that allows you to query this information after the parsing is done, because as you parse, it also collects and stores this information already.

    是以,RxE 實際上配備了一個語義分析 API,可以讓你在解析完成後查詢這些資訊,因為在你解析的同時,它已經收集並存儲了這些資訊。

  • So you don't have to do the traversal yourself to figure out this information.

    是以,你不必自己進行遍歷來找出這些資訊。

  • You can just ask, right?

    你可以直接問,對吧?

  • So this is also slightly different from, say, you know, the way SWAC works.

    是以,這也與西南航空的工作方式略有不同。

  • In a way, like, I don't want to bash SWAC, because it is the first JavaScript Rust toolchain, right?

    在某種程度上,我並不想抨擊 SWAC,因為它是第一個 JavaScript Rust 工具鏈,對嗎?

  • And I think it serves its purpose really, really well.

    我認為它的作用非常非常好。

  • A lot of people are still using it.

    很多人仍在使用它。

  • It's great.

    太棒了

  • But I think there are things we can learn from it.

    但我認為,我們可以從中學到一些東西。

  • Learn from the past efforts.

    從過去的努力中吸取經驗教訓。

  • And we believe RxE is just a better foundation if we want to build more ambitious features on top of it.

    我們相信,如果我們想在 RxE 的基礎上構建更多雄心勃勃的功能,RxE 只是一個更好的基礎。

  • So yeah, so Rodown essentially started out with RxE as the base.

    是以,Rodown 一開始基本上是以 RxE 為基礎的。

  • And so far, we are happy that the performance is turning out to be, you know, living up to our expectations.

    到目前為止,我們很高興,我們的表現沒有辜負我們的期望。

  • Something I've always admired about your approach to projects is that very iterative style.

    我一直很欣賞你處理項目的方法,那就是迭代風格。

  • So I remember when I first discovered Vue, you were just making the transition from Vue 1 to Vue 2, introducing virtual DOM, learning a lot of lessons from React.

    我記得當我第一次發現 Vue 時,你們剛剛從 Vue 1 過渡到 Vue 2,引入了虛擬 DOM,從 React 那裡學到了很多經驗。

  • And that always struck me, and I feel like you've sort of had a pattern doing that over the years.

    這一點一直讓我印象深刻,我覺得這些年來你一直都是這樣做的。

  • So I'm curious to tie into the sort of incremental approach that you're taking now.

    所以,我很想知道你們現在採取的這種漸進式方法。

  • What have you learned from projects like Biome and Roam, for example, who have tried to tackle somewhat similar problems, but maybe from a different angle?

    生物群落》和《漫遊》等項目試圖從不同角度解決類似的問題,你們從這些項目中學到了什麼?

  • And SWC probably is in the same category.

    深港西部通道可能也屬於這一類。

  • They're trying to tackle some performance problems.

    他們正在努力解決一些性能問題。

  • What are the big lessons and takeaways and things that you're trying to do differently than those projects might have tackled?

    與這些項目相比,您有哪些重要的經驗和教訓,以及您正在嘗試以不同的方式做哪些事情?

  • I think in terms of the end vision, it's very obvious that Void Zero has a lot of similarity to what Roam wanted to do.

    我認為,就最終願景而言,《虛空零號》顯然與《漫遊》想做的事情有很多相似之處。

  • I think there are two major differences.

    我認為主要有兩點不同。

  • First is, we decided to work on the toolchain for Void Zero, mostly because we already have

    首先,我們決定開發 Void Zero 的工具鏈,主要是因為我們已經有了

  • Vite serving as sort of a point of convergence.

    Vite 是一個匯聚點。

  • If we don't have Vite as the leverage, then the chance of success will be much slimmer.

    如果我們沒有維特作為籌碼,那麼成功的機會就會渺茫得多。

  • And Roam really didn't have anything like that.

    而《漫遊》確實沒有這樣的東西。

  • They started out with something that's completely from scratch.

    他們一開始完全是從零開始。

  • So for Roam, I think the biggest challenge is just going from zero to one.

    是以,對於 Roam 來說,我認為最大的挑戰就是從零到一。

  • How do you make people adopt it?

    如何讓人們接受它?

  • They started out with a formatter, which kind of makes sense because formatter is probably the least intrusive piece of task in the overall development flow.

    他們一開始使用的是格式化器,這有點說得通,因為格式化器可能是整個開發流程中侵入性最小的任務。

  • In a way, it's completely coupled from everything else.

    在某種程度上,它與其他一切完全耦合。

  • That makes it easier for people to switch to and adopt.

    這讓人們更容易轉而採用。

  • The downside of that is it's also not a strong leverage to have, because it's not really related to the rest of the tasks people are doing.

    這樣做的弊端是,它也不是一個強有力的槓桿,因為它與人們正在做的其他任務並沒有真正的聯繫。

  • I think the angle where you get the adoption from, this is more like a strategic difference,

    我認為,從採用的角度來看,這更像是一種戰略差異、

  • I think.

    我想是的

  • Another more technical difference is, I think Roam's implementation or Biome's Rust codebase was initially designed to be more intended for an IDE use case scenario.

    另一個更具技術性的區別是,我認為 Roam 的實現或 Biome 的 Rust 代碼庫最初的設計更傾向於 IDE 用例場景。

  • They focused a lot on the IDE story.

    他們非常關注 IDE 的故事。

  • So they essentially built something, they used something called CST, Concrete Syntax

    是以,他們從本質上構建了一些東西,他們使用了一種叫做 CST 的東西,具體文法

  • Tree, because they want to preserve the shape of the original code as much as possible, and they want to be resumable and more error resilient.

    樹,因為它們希望儘可能地保留原始代碼的形狀,而且它們希望可以恢復,並具有更強的抗錯能力。

  • A lot of these are great for IDE use cases, but not necessarily best if you want to do the other tasks, for example, get the fastest possible transforms, and also basically be able to use the AST for multiple tasks along a long pipeline.

    對於集成開發環境用例來說,這些方法有很多都很不錯,但如果你想完成其他任務,例如,獲得最快的轉換,以及在長管道中將 AST 用於多個任務,那麼這些方法就不一定是最好的了。

  • So when we, I think Boschian could probably share more insights on this front, but I think the difference between the AST and CST was also a major reason where Boschian was like, we don't really want to do that in OXC.

    是以,當我們,我想博世安也許可以分享更多這方面的見解,但我認為 AST 和 CST 之間的差異也是一個主要原因,博世安想,我們真的不想在 OXC 中這樣做。

  • But I think it's unfortunate that Roam didn't get to actually keep going beyond what it is now.

    但我認為,《漫遊》未能真正超越現在的水準,實在令人遺憾。

  • But I think it still showed people that it's possible to write high quality tooling for

    但我認為,它還是向人們展示了為以下設備編寫高質量工具的可能性

  • JavaScript in Rust, because a lot of people are happy with Biome as a flowmatter nowadays.

    JavaScript in Rust,因為現在很多人都喜歡將 Biome 作為流程物質。

  • And it's also part of the reason why we're not in a hurry to work on flowmatter, because it already kind of fills that gap.

    這也是我們不急於研究流動物質的部分原因,因為它已經填補了這一空白。

  • We will probably eventually have an OXC based flowmatter just for complete sake, but for us, that's just going to be down the road.

    我們最終可能會推出基於 OXC 的 flowmatter,但對我們來說,這只是以後的事。

  • Your first point reminds me of the saying, make it work, make it right, or make it, yeah, make it work, make it right, make it fast.

    你的第一點讓我想起了一句話:"讓它工作,讓它正確,或者讓它,是的,讓它工作,讓它正確,讓它快速。

  • Like you made it work, Vite, we already have like the grand vision and just all of this work now is like truly like making it right and being able to like make sure the pipes make it fast.

    維特,就像你做的那樣,我們已經有了宏大的願景,現在所有的工作就是要真正把它做好,並能確保管道快速鋪設。

  • Yeah.

    是啊

  • Yeah.

    是啊

  • In a lot of ways.

    在很多方面都是如此。

  • Yeah.

    是啊

  • I think the first stage of Vite really was like, let's just make things work and make it better than the status quo.

    我認為,Vite 的第一階段真的就像是:讓我們把事情做好,讓它比現狀更好。

  • But underneath, there might be a lot of, you know, hacks and things we want to improve in the future.

    但在這背後,可能有很多,你知道的,黑客和我們未來想要改進的東西。

  • And now it's the proper time to do it.

    現在正是時候。

  • So I've developed a little bit of a few Vite plugins as I've gone along.

    是以,我開發了一些 Vite 插件。

  • I've done a lot of static site generation and I've rebuilt Storybook a few different times.

    我做過很多靜態網站生成工作,也重建過幾次 Storybook。

  • And most of those things usually come down to like, I need to make a very intense plugin for the system.

    而這些事情中的大多數通常會歸結為,我需要為系統製作一個非常強大的插件。

  • And the one thing that kind of trips me up a lot of the time is the plugin API for Vite is the same as Rollup, but it only has like a select few hooks.

    Vite 的插件 API 與 Rollup 相同,但只有少數幾個鉤子。

  • And I feel like those hooks are probably excluded because like we have like speed concerns in the mix.

    我覺得這些鉤子可能會被排除在外,因為我們有速度方面的顧慮。

  • With the advent of like Rolldown, will we see the plugin API start to like open up a little bit?

    隨著 Rolldown 的出現,我們是否會看到插件 API 開始變得開放一些?

  • Will the speed unlock more power that we can give to plugin devs?

    速度是否會釋放出更多的能量,讓我們可以為插件開發人員提供更多的功能?

  • I'm curious, what are the hooks you were looking for, but doesn't work indeed?

    我很好奇,你在尋找什麼鉤子,但它確實不起作用?

  • There's just like a handful, like four or five of them that like I've always want to use, but they just don't run in dev mode because they're not there.

    我一直想用的東西屈指可數,大概有四五種,但它們無法在開發模式下運行,因為它們不存在。

  • So yeah, just wondering, will the new power expand to more stuff for us to do?

    所以,我只是想知道,新權力是否會擴展到我們可以做的更多事情?

  • So this is an interesting one because, so first of all, with Rolldown and in a future version of Vite, dev and prod will become more consistent.

    是以,這是一個有趣的問題,因為首先,有了 Rolldown 和未來版本的 Vite,開發和生產將變得更加一致。

  • They will be using the same plugin pipeline and so the plugins will work exactly the same between dev and prod.

    它們將使用相同的插件流水線,是以開發版和原版之間的插件工作方式將完全相同。

  • But the interesting part about having JavaScript plugins running in a Rust-based tool is there is the overhead of sending data back and forth between the two languages because they don't share memory by default.

    但是,在基於 Rust 的工具中運行 JavaScript 插件的有趣之處在於,兩種語言之間來回發送數據會產生開銷,因為它們默認情況下並不共享內存。

  • So in most cases, when you send things across the wire, you have to clone them in memory.

    是以,在大多數情況下,當你通過電線發送信息時,你必須在內存中克隆它們。

  • And that's probably one of the biggest bottlenecks for speed.

    這可能是速度的最大瓶頸之一。

  • So let's say if you use raw Rolldown without any JavaScript plugins to bundle 20,000 modules, you can do it in 600 milliseconds.

    是以,如果不使用任何 JavaScript 插件,使用原始 Rolldown 來捆綁 20,000 個模塊,則只需 600 毫秒即可完成。

  • But if you add a couple of JavaScript plugins, you can slow it down by maybe two to three times.

    但如果添加幾個 JavaScript 插件,速度可能會減慢兩到三倍。

  • And this is directly correlated to the number of modules because we have to, for every hook of every plugin, you have to call it once for every module.

    這與模塊數量直接相關,因為我們必須為每個插件的每個鉤子,為每個模塊調用一次。

  • So let's say you have a plugin with three hooks, then we're doing 60,000 Rust to JS calls.

    是以,假設您有一個帶有三個鉤子的插件,那麼我們將進行 60,000 次 Rust 到 JS 調用。

  • And that's not cheap.

    這可不便宜。

  • Even if you don't do anything in a hook, it's still quite a bit of a cost.

    即使你在鉤子裡什麼都不做,代價也是相當大的。

  • So we're looking for ways to optimize that.

    是以,我們正在尋找優化的方法。

  • So first of all, base layer compatibility is we want all the existing Vite plugins to be able to continue to work the same way.

    是以,首先,基礎層的兼容性是我們希望所有現有的 Vite 插件都能以同樣的方式繼續工作。

  • It might compromise the ideal performance to a certain extent, but let's make things work first.

    這可能會在一定程度上影響理想的性能,但我們還是先把事情做好吧。

  • And then the next step is for Vite itself internally, we've actually already ported some of the Vite internal logic over to Rust.

    下一步是 Vite 本身的內部工作,實際上我們已經將部分 Vite 內部邏輯移植到了 Rust。

  • So right now it's only for builds.

    是以,現在只能用於構建。

  • So when you do the production build, you can enable the native equivalent of some Vite internal plugins.

    是以,在進行生產構建時,可以啟用一些 Vite 內部插件的在地等效功能。

  • So that allows us to essentially get Vite build speed down to maybe two to 2.2 and a half times slower than raw Rodan without any JavaScript plugins, which I think is actually decent.

    這樣,我們就能將 Vite 的構建速度降低到原始 Rodan(不含任何 JavaScript 插件)的 2 到 2.2.5 倍,我認為這已經很不錯了。

  • And in fact, that's already kind of on par with other pure Rust sponsors.

    事實上,這已經與其他純粹的 Rust 贊助商不相上下了。

  • And then we are doing a few things to essentially, there are two different ways you can think about this.

    然後,我們正在做一些事情,從本質上講,你可以從兩種不同的角度來考慮這個問題。

  • One is reduce unnecessary Rust to JS calls.

    一是減少不必要的 Rust 到 JS 調用。

  • So in typical Rust rollup plugins, we do a lot of things like in the transformer hook, we look at the ID.

    是以,在典型的 Rust 卷積插件中,我們會做很多事情,比如在變壓器鉤子中,我們會查看 ID。

  • If the ID ends with a certain extension, we do this, otherwise we just return early.

    如果 ID 以某個擴展名結束,我們就這樣做,否則就提前返回。

  • This is actually wasteful if you're using the plugin in a Rust bundler, because the bundler essentially does a Rust to JS call, figure out it actually doesn't need to do anything, but it already paid the cost.

    如果你在 Rust 捆綁程序中使用該插件,這實際上是一種浪費,因為捆綁程序基本上會進行 Rust 到 JS 的調用,然後發現它實際上不需要做任何事情,但它已經支付了成本。

  • This is why ESBuilds plugin actually requires to have a filter outright before it is ever applied.

    這就是為什麼 ESBuilds 插件實際上要求在應用之前必須徹底過濾。

  • And we're going to essentially introduce something similar.

    我們基本上也要引入類似的內容。

  • So it's going to be an extension on top of the current rollup syntax.

    是以,它將是對當前卷積文法的擴展。

  • It's going to be compatible because when you use the object format for your hooks, so you specify a logic in the handler property, and then you can have a filter property to say, only apply this hook if the ID matches this regex or something like that.

    它將是兼容的,因為當你為鉤子使用對象格式時,你可以在處理程序屬性中指定一個邏輯,然後你可以有一個過濾器屬性來表示,只有在 ID 符合這個 regex 或類似條件時才應用這個鉤子。

  • So we can essentially determine whether this hook even needs to be called for a certain module before we even call it.

    是以,我們基本上可以在調用鉤子之前就確定是否需要為某個模塊調用該鉤子。

  • So we don't even need to cross the Rust to JS bridge.

    是以,我們甚至不需要跨過 Rust to JS 橋。

  • That's one thing.

    這是一方面。

  • The other thing is we're seeing a lot of plugins in the wild doing very similar things.

    另外,我們還看到很多插件都在做類似的事情。

  • For example, in the transform hook, a lot of plugins take the incoming source code, parse it using a JavaScript parser in the hook, and then do their own semantic analysis or AST traversal, and then use something like magic string to alter the code and generate a new code and also need to generate the source map and then pass it back to the bundler.

    例如,在轉換鉤子中,很多插件都會獲取輸入的源代碼,使用鉤子中的 JavaScript 解析器對其進行解析,然後進行自己的語義分析或 AST 遍歷,然後使用類似 magic string 的東西來更改代碼並生成新代碼,還需要生成源映射,然後將其傳回給捆綁程序。

  • So a lot of work done in JavaScript, not leveraging the Rust parts.

    是以,很多工作都是在 JavaScript 中完成的,並沒有利用 Rust 部分。

  • And then also the Rust needs to now need to take the source map and do the source imagine.

    然後,Rust 還需要獲取源地圖並進行源想象。

  • And source maps are also quite heavy to pass across the boundary because it's bigger objects than source code.

    由於源映射是比源代碼更大的對象,是以跨邊界傳遞時也相當沉重。

  • So we're trying to design APIs to essentially make this kind of standard AST-based simple transforms to be as efficient as possible.

    是以,我們正在嘗試設計 API,使這種基於 AST 的標準簡單轉換儘可能高效。

  • So imagine instead of getting the string of the code, you actually get the pre-parsed

    是以,想象一下,您實際上得到的不是代碼字符串,而是預先解析的

  • AST directly.

    AST directly.

  • And instead of manipulating the code and generating the source map in the JS side, you still do the same kind of magic string-like operations, say like append some code here, remove the code here.

    而不是在 JS 端操作代碼和生成源映射,你仍然可以進行類似神奇字符串的操作,比如在這裡添加一些代碼,在這裡刪除代碼。

  • But these operations are kind of buffered and send as very compact instructions back to Rust.

    但這些操作會被緩衝,並以非常緊湊的指令形式發送回 Rust。

  • And the heavy lifting of code manipulation, string manipulation, and source map generation is actually done by Rust on the Rust side.

    而代碼操作、字符串操作和源代碼映射生成等繁重的工作,實際上都是由 Rust 來完成的。

  • So the only work you're doing on the JS side really is looking at the AST and record the operations you want to do, and then tell the Rust side to do it.

    是以,你在 JS 端要做的唯一工作就是查看 AST 並記錄你要做的操作,然後告訴 Rust 端去做。

  • So I think this, in fact, can cover a very wide range of custom transform needs.

    是以,我認為這實際上可以滿足非常廣泛的定製改造需求。

  • Because we're actually able to build views, single file component transform entirely using this model in JavaScript.

    因為我們實際上可以完全使用 JavaScript 中的這個模型來構建視圖和單文件組件轉換。

  • And if we get this API natively from the bundler, then we can actually offload a lot of the heavy lifting to the Rust toolchain instead of doing it in JavaScript.

    如果我們能從捆綁程序中獲得原生的應用程序接口,那麼我們就能將大量繁重的工作卸載到 Rust 工具鏈中,而不是在 JavaScript 中完成。

  • I don't even need to install a parser dependency myself.

    我甚至不需要自己安裝解析器依賴項。

  • So this is the second part of it.

    所以這是第二部分。

  • And then if we go a bit deeper, this is further down the line, we're also investigating whether it's possible to send ASTs from Rust to JavaScript as little memory cost as possible.

    再深入一點,我們還在研究是否有可能以儘可能少的內存成本將 AST 從 Rust 發送到 JavaScript。

  • So this is something called like zero cost AST transfer.

    這就是所謂的 "零成本 AST 轉移"。

  • Theoretically, it's already possible using a shared array buffer.

    理論上,使用共享數組緩衝區已經可以做到這一點。

  • And then we need a custom deserializer on the JavaScript side that understands the memory layout and be able to lazily read the AST from the flat array buffer as you need.

    然後,我們需要在 JavaScript 端定製一個反序列化器,它能理解內存佈局,並能根據需要從平面數組緩衝區輕鬆讀取 AST。

  • One of our team members, Overlook Motel, actually has a proof of concept of this working already.

    我們的團隊成員之一,Overlook 汽車旅館,實際上已經有了這方面的概念驗證。

  • But getting this properly into XE is going to be quite challenging.

    但要將其正確導入 XE 將是一項相當具有挑戰性的工作。

  • So this is something we're eventually going to do down the road.

    是以,這是我們最終要做的事情。

  • But the proof of concept shows that this is possible, right?

    但概念驗證表明這是可能的,不是嗎?

  • And there are some exciting things in the JavaScript specs.

    JavaScript 規範中有一些令人興奮的內容。

  • For example, there's a share struct proposal.

    例如,有一項股權結構提案。

  • That's quite new.

    這倒是新鮮事。

  • That's still stage one.

    這還是第一階段。

  • It also is kind of exciting if you can use share structs to essentially properly share state across virtual threads and maybe Rust.

    如果能使用共享結構體來跨虛擬線程和 Rust 適當地共享狀態,也是一件令人興奮的事情。

  • So what this unlocks is proper parallelization of JavaScript plugins.

    是以,這將解鎖 JavaScript 插件的適當並行化。

  • Right now, when you use JavaScript plugins with a Rust bundler, because the JavaScript plugin still runs in Node.js process, it's still single threaded.

    目前,在使用 JavaScript 插件和 Rust 捆綁程序時,由於 JavaScript 插件仍在 Node.js 進程中運行,是以仍是單線程的。

  • One thing we've done is trying to use multiple worker threads to parallelize the workload.

    我們已經嘗試使用多個工作線程來並行處理工作負載。

  • But the downside of this is, for example, if the plugin uses a heavy dependency like

    但這樣做的缺點是,例如,如果插件使用的依賴性很強,如

  • Babel, each worker thread needs to initialize with Babel and allocate the memory for it.

    在 Babel 中,每個工作線程都需要使用 Babel 進行初始化,併為其分配內存。

  • And in a lot of cases, the gain is smaller than you might think.

    而且在很多情況下,收益比你想象的要小。

  • Because the initializing cost of each worker thread just offsets so much of the performance gains you get.

    因為每個工作線程的初始化成本抵消了性能提升的大部分。

  • It's challenging.

    這很有挑戰性。

  • There are some things we played around with.

    有些東西我們也玩過。

  • For example, instead of spawning the worker threads through a Node.js main process and then get the data back and send it back to Rust, we let the worker threads directly send the data back to Rust.

    例如,我們讓工作線程直接將數據發回 Rust,而不是通過 Node.js 主進程生成工作線程,然後再將數據發回 Rust。

  • I think some of this might be useful, but applying them blindly for every plugin may not end up being as beneficial as we think.

    我認為這其中有些可能是有用的,但盲目地將它們應用於每個插件,最終可能並不像我們想象的那樣有益。

  • So there's still a lot of work that we're exploring in this area.

    是以,我們在這方面還有很多工作要做。

  • But I'm kind of optimistic that for a long-term goal for us is to tackle this, still allow users to easily write JavaScript plugins, but without severely compromising the overall performance of the system.

    但我樂觀地認為,我們的長期目標是解決這個問題,仍然允許用戶輕鬆編寫 JavaScript 插件,但又不會嚴重影響系統的整體性能。

  • Yeah, I do think that this is one of the hardest areas for all the reasons you've outlined.

    是的,我確實認為這是最困難的領域之一,原因如你所述。

  • And the temptation is real to just say, sorry, no more plugins in JavaScript.

    如果只是說 "對不起,JavaScript 中不再有插件了",這種誘惑確實存在。

  • It's also, you know, there's a big ecosystem churn cost there, which is a pretty big downside.

    此外,生態系統的流失成本也很高,這是一個相當大的不利因素。

  • Yeah, I kind of want to mention there's also, we do want to start with getting the plugins work, right?

    是的,我還想提一下,我們確實想從讓插件正常工作開始,對嗎?

  • Then we start having a recommended subset or a recommended best practice for writing performant JavaScript plugins for Rust.

    然後,我們開始為 Rust 編寫高性能 JavaScript 插件推薦子集或推薦最佳實踐。

  • So maybe we'll have linked rules to help guide you writing these plugins, or we can have runtime warnings.

    是以,也許我們會有一些鏈接規則來幫助指導你編寫這些插件,或者我們可以有運行時警告。

  • Like, one thing we actually did is we use OXC to implement a small tool that can look at your plugin source code and, you know, look at, for example, look at your transform hook and notice that you're doing something like if id.test.regex.return, right?

    比如,我們實際上做了一件事,那就是使用 OXC 來實現一個小工具,它可以查看插件源代碼,比如,查看你的轉換鉤子,並注意到你正在做 if id.test.regex.return 這樣的事情,對嗎?

  • So this is a sign of early return, it shows that this transform hook is actually eligible for filter optimization.

    是以,這是一個提前返回的信號,它表明這個變換鉤子實際上有資格進行濾波優化。

  • So detect such cases and actually give you a soft recommendation, say like this plugin hook can be refactored to use the filter API to make it more performant.

    是以,我們可以檢測到這種情況,並給出軟性建議,比如可以重構這個插件鉤子,使其使用過濾器 API,從而提高性能。

  • So it kind of sounds like there's going to be kind of a divide here at some point where there's like, there's a bunch of legacy rollup plugins that still work in the new architecture.

    是以,這聽起來像是在某些時候會出現一種分歧,比如,有一些傳統的卷積插件在新架構中仍然可以使用。

  • But then as we go on, kind of like a recommended V2 of all of those that use these new APIs to make things really fast.

    不過,隨著我們的深入,我們會推薦 V2 版,讓所有使用這些新 API 的人都能快速完成工作。

  • Yeah, and in a lot of ways, we do also want to make most of the common things you need to do built in.

    是的,在很多方面,我們也確實想把你需要做的大部分常見事情內置進去。

  • For example, if you use rollup, rolldown today, you don't need common JS plugin because it just works out of the box.

    例如,如果您現在使用 rollup、rolldown,您就不需要普通的 JS 插件,因為它開箱即用。

  • You don't need the node resolve plugin because it just works out of the box.

    您不需要節點解析插件,因為它開箱即用。

  • You don't need TypeScript transforms, you don't need JSX transforms.

    你不需要 TypeScript 轉換,也不需要 JSX 轉換。

  • All of these things just work without plugins.

    所有這些都無需插件即可運行。

  • So in a lot of ways, it's similar to rollup's abstraction level is a bit, rolldown's abstraction model is a bit more like ES build slash leaps, right?

    是以,在很多方面,它與 rollup 的抽象層級有點類似,rolldown 的抽象模型更像 ES build slash leaps,對嗎?

  • It's a bit more battery included because that's also the most pragmatic way to get the best possible performance.

    它的電池容量更大一些,因為這也是獲得最佳性能的最實用方法。

  • Yeah, it makes a lot of sense.

    是的,這很有道理。

  • I'm really interested to see what y'all end up coming up with, with the AST transforms, because I feel like this is a pretty common problem is like, if you need to do very performant

    我真的很想知道你們最終會用 AST 轉換來解決什麼問題,因為我覺得這是一個很常見的問題。

  • AST transforms, I mean, you have the added problem of like going across language boundaries.

    AST 轉換,我的意思是,你還會遇到跨越語言界限的問題。

  • This just reminds me of a random project that I saw the other day called like render from this guy named Eric Mann.

    這讓我想起前幾天看到的一個隨機項目,名叫 "渲染",來自一個叫埃裡克-曼恩的人。

  • And it's like, it's a byte code that runs in JavaScript that like is a rendering engine or whatever.

    它就像是在 JavaScript 中運行的字節碼,就像是一個渲染引擎之類的東西。

  • And it's just like, I don't know, there's like a lot of interesting things in the space when you start thinking about like, how can we make like marshalling and serialization very, very, very fast.

    我也不知道,當你開始思考如何才能讓 marshalling 和序列化變得非常、非常、非常快時,這個領域就會出現很多有趣的東西。

  • So this will be really cool.

    是以,這將會非常酷。

  • I'm excited.

    我很興奮。

  • Well, maybe as we're getting close to wrapping up the episode, let's think about or talk a little bit about what the future looks like.

    好吧,也許在我們即將結束這一集的時候,讓我們想一想或談一談未來的樣子。

  • So you're saying earlier that Vite is already pretty prolific.

    所以你剛才說,維特已經非常多產了。

  • So it is your starting point, you have sort of this broad baseline that, you know, say

    是以,這是你的起點,你有這樣一個廣泛的基線,你知道,比如說

  • Rome when it was starting was missing.

    羅馬開始時就不見了。

  • But there's still a lot of work to do.

    但仍有許多工作要做。

  • So what do you like think the priorities going into the project will be?

    那麼,您認為項目的優先事項是什麼?

  • And you know, what is your like time horizon that you're sort of anticipating for, you know, say some of your first products when you release, like, what does that look like for you?

    你知道嗎,你對一些首批產品發佈的預期時間範圍是怎樣的?

  • Yeah.

    是啊

  • So this is obviously going to be a quite long process.

    是以,這顯然將是一個相當漫長的過程。

  • I think right now our priority is getting rolled down to sort of a beta status.

    我認為,目前我們的首要任務是將其升級到測試版狀態。

  • There's a lot of alignment work that we need to do right now, because with the goal of being able to swap out ESBuilder rollup, right, we need to make sure, like, because the sort of the mission of rolldown is to unify the two.

    我們現在需要做大量的調整工作,因為我們的目標是能夠交換 ESBuilder rollup,對吧,我們需要確保,就像,因為 rolldown 的任務是將兩者統一起來。

  • So in terms of how they handle, for example, CJS, ESM, Interop, how they handle a lot of the edge cases, they need to be as consistent as possible.

    是以,在如何處理 CJS、ESM、Interop 等方面,以及如何處理大量邊緣案例方面,都需要儘可能保持一致。

  • And we need to basically enable the test cases of both bundlers, run rolldown against those test cases and try to pass as many of them as possible.

    基本上,我們需要啟用兩個捆綁程序的測試用例,針對這些測試用例運行 rolldown,並儘可能多地通過測試用例。

  • And then for the ones that's not passing, we need to analyze them and see each whether this is just an output difference or is it more like a correctness issue, right?

    然後,對於未通過的數據,我們需要對其進行分析,看看這是否只是輸出差異,還是更像是正確性問題,對嗎?

  • So we kind of have to label them one by one.

    是以,我們必須一個一個地給它們貼標籤。

  • And if there are inconsistencies between the two, we need to make a call on which one do we go with.

    如果兩者有不一致的地方,我們就需要決定採用哪一個。

  • So this is just a lot of grunt work, but it's necessary before we can consider it, you know, production ready.

    是以,這只是大量的粗活,但在我們將其視為生產準備就緒之前,這是必要的。

  • Once that is completed, I think rolldown.

    一旦完成,我想就可以下線了。

  • In parallel, OXC is also trying to finish the syntax down leveling transforms.

    與此同時,OXC 還在努力完成文法降級轉換。

  • Like some of the hardest ones are like the async generators and stuff like that.

    其中最難的是異步生成器之類的東西。

  • But it's well underway.

    但目前進展順利。

  • So I think by end of this year, we're hoping to get rolldown to beta status and have the transforms also more or less completed.

    是以,我認為,到今年年底,我們希望能將翻滾功能提升到測試版狀態,並完成或多或少的轉換。

  • So that's a good milestone to hit.

    是以,這是一個很好的里程碑。

  • So that also primes the entire toolchain for general testing into Vite itself.

    是以,這也為整個工具鏈進入 Vite 本身的通用測試奠定了基礎。

  • So rolldown-based Vite already has a working progress branch where we pass over 90% of the tests.

    是以,基於下拉菜單的 Vite 已經有了一個工作進度分支,我們通過了 90% 以上的測試。

  • Some of the tests that's not passing are actually more or less blocked by tests like legacy mode, which we were kind of like intentionally pumping on because I'm not sure how many people will still be using legacy mode by the time we actually release the thing that's stable.

    實際上,一些未通過的測試或多或少受到了傳統模式等測試的阻撓,而我們之所以故意拖延,是因為我不確定到我們真正發佈穩定版時,還有多少人在使用傳統模式。

  • So in a way, rolldown-Vite is somewhat usable.

    是以,在某種程度上,rolldown-Vite 是可用的。

  • Like we are actually already able to use it to power Vite trust to build the Vite docs.

    就像我們實際上已經能夠用它來為 Vite 提供動力,信任它,以建立 Vite 文檔。

  • But we want to wait until rolldown is ready.

    但我們想等到 rolldown 準備就緒。

  • We have all the transforms ready.

    我們已經準備好了所有的變壓器。

  • Then we have an alpha or slash beta release for rolldown-based Vite and have people test it.

    然後,我們將發佈基於輪播的 Vite 的 alpha 版或測試版,並讓人們對其進行測試。

  • So this version of rolldown-based Vite is strictly just replacing esbuild and rollup with rolldown.

    是以,嚴格來說,這一版本基於 rolldown 的 Vite 只是用 rolldown 取代了 esbuild 和 rollup。

  • So feature equivalence, not really many new things.

    是以,功能等同,並無太多新意。

  • It's mostly like we want to make sure the transition is smooth, frameworks can move over to the new one.

    主要是我們想確保過渡順利,框架可以轉移到新的框架。

  • So that will probably also take some time.

    是以,這可能也需要一些時間。

  • So in that same process, we do eventually want to move Vite over to a full bundle mode that's entirely powered by rolldown.

    是以,在同樣的過程中,我們最終希望將 Vite 轉變為完全由滾動條驅動的完全捆綁模式。

  • As nice as unbundled ESM is for smaller projects, we've run into scaling issues in larger projects.

    對於小型項目來說,非捆綁式 ESM 固然很好,但我們在大型項目中遇到了擴展問題。

  • Especially when you have, say, more than 3,000 unbundled modules as a dev server.

    尤其是當你有 3000 多個未捆綁模塊作為開發服務器時。

  • So we believe a fully bundled mode is still necessary.

    是以,我們認為完全捆綁模式仍有必要。

  • And it also allows us to get rid of some of the issues, for example, optimized depths.

    它還能讓我們擺脫一些問題,例如優化深度。

  • It can be completely eliminated.

    它可以完全消除。

  • So all your dependencies in your source code will go through the exact same transform pipeline for dev and for production.

    是以,源代碼中的所有依賴項都將通過完全相同的轉換管道進行開發和生產。

  • So consistency will improve greatly.

    是以,一致性將大大提高。

  • And for the metaframeworks, the one important API for metaframeworks is SSRLoggedModule.

    對於元框架來說,一個重要的應用程序接口就是 SSRLoggedModule。

  • In the new environment API, it's called environment.runModule, something like that.

    在新的環境 API 中,它被稱為 environment.runModule,類似這樣的名字。

  • So internally, it's currently still using a JavaScript-based transform.

    是以,在內部,它目前仍在使用基於 JavaScript 的轉換。

  • That will also be replaced by a Rust-based implementation that's exported by rolldown.

    它也將被基於 Rust 的實現所取代,該實現由 rolldown 導出。

  • So that you'd use the same bundling mechanism for your code running in the browser and running other environments, for example, Node.js SSR.

    這樣,在瀏覽器中運行的代碼和在其他環境中運行的代碼(例如 Node.js SSR)就可以使用相同的捆綁機制。

  • That also gets rid of the configuration needs for SSR externals.

    這也擺脫了 SSR 外部配置的需要。

  • So removing optimized depths, removing SSR externals are the two major goals of the full bundle mode and also greatly improving page load performance in larger projects.

    是以,移除優化深度和移除 SSR 外部因素是全捆綁模式的兩大目標,同時也能大大提高大型項目的頁面加載性能。

  • So that's kind of down the road, probably Q2 next year.

    是以,這可能要到明年第二季度。

  • And we will likely kick off some product development in parallel once we get the rolldown-based Vite into beta status.

    一旦基於滾輪的 Vite 進入測試階段,我們很可能會同時啟動一些產品開發。

  • Well, that sounds like a whole mountain of work that you guys have to do.

    聽起來你們要做的工作還真不少。

  • So I wish you guys luck on that.

    所以,我祝你們好運。

  • That also wraps it up for our questions for this week's episode.

    本週節目的問題也到此結束。

  • Thanks for coming on, Evan.

    謝謝你的到來,埃文。

  • It was a pleasure to have you back on.

    很高興你能回來。

  • And it's exciting to see how much progress both the projects have had and what the new project holds.

    看到兩個項目都取得了如此大的進展,以及新項目的前景,我感到非常興奮。

  • Thank you.

    謝謝。

  • Over to Chad.

    交給查德

  • Yeah, super excited for what y'all do.

    是啊,對你們的工作超級期待。

  • We had a few other episodes where we talked to people building infrastructure tooling.

    在其他幾期節目中,我們還與構建基礎架構工具的人進行了交談。

  • We had the Biome team on a little while back.

    不久前,我們請來了生物群落團隊。

  • We had Charlie Marsh talking about RUF and UV in the Python ecosystem.

    Charlie Marsh 談到了 Python 生態系統中的 RUF 和 UV。

  • And this really seems like of the bets that we've taken in this space, this seems like the one that's most likely to succeed in my case.

    在我們所下的賭注中,這似乎是我認為最有可能成功的一個。

  • It's always a big bet.

    賭注總是很大。

  • But I have a lot of faith in y'all.

    但我對你們充滿信心。

  • So really excited to see what you do and wish you all the best.

    非常期待看到你們的作品,祝你們一切順利。

  • Thank you.

    謝謝。

The first stage of VEET really was like, let's just make things work and make it better than the status quo, but underneath there might be a lot of, you know, hacks and things we want to improve in the future.

VEET 的第一階段就像是,讓我們把事情做好,讓它比現狀更好,但在這背後可能有很多,你知道的,黑客和我們希望在未來改進的東西。

字幕與單字
由 AI 自動生成

單字即點即查 點擊單字可以查詢單字解釋