[譯] 設計大型 JavaScript 應用程式

shery發表於2019-02-06

這是我在 JavaScript 澳大利亞開發者大會(JSConf AU)上演講內容的文字編輯記錄。在 YouTube 上觀看整個演講視訊

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:你好,我曾經構建過非常大型的 JavaScript 應用。

你好,我曾經構建過非常大型的 JavaScript 應用。我不再那麼做了,所以我認為現在是個好時機來回顧並分享我學到的東西。昨天我在會議聚會上喝啤酒時,有人問我:“嘿,馬爾特,究竟是什麼賦予了你權利和權威,來講這個話題?”我想這個問題的答案實際上就是這個演講的主題,儘管我通常覺得談論自己有點奇怪。大概是因為,我在谷歌構建了這樣一個 JavaScript 框架。它被 Google 照片,Google 協作平臺,Google+,Google 雲端硬碟,Google Play,搜尋引擎,所有這些網站使用。其中一些專案非常大,你可能已經使用了其中的一些。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:我認為 React 很好。

這個 Javascript 框架不是開源的。它不是開源的原因是它與 React 同時出現,我想“世界是否真的需要另一個 JS 框架來做選擇?”。谷歌已經擁有了一些 JS 框架,Angular 和 Polymer,並且我覺得再有一個會讓人們感到困惑,所以我只是認為我們應該把它留給我們自己。但除了不是開源的,我認為還是有很多東西可以從中學習,值得分享我們一路上學到的東西。

[譯] 設計大型 JavaScript 應用程式

一張人山人海的圖片.

所以,我們來談談非常大型的應用,以及他們之間的共同點。當然可能會有很多開發者參與其中。可能有幾十人甚至更多,他們都有自己的情感和人際問題,你必須要考慮到這一點。

[譯] 設計大型 JavaScript 應用程式
一張非常古老建築的圖片.

即使你的規模不大,也許你已經在這個領域工作了一段時間,也許你甚至不是第一個維護它的人,你可能不瞭解專案的所有結構或者內容,可能有些東西是你不太明白的,你的團隊中可能還有其他人不瞭解應用程式的所有資訊。這些都是我們在構建非常大型的應用程式時,必須考慮的事情。

[譯] 設計大型 JavaScript 應用程式

推特: 一個沒有初級工程師的高階工程師團隊是一個工程師團隊。

我想在這裡做的另一件事是以我們的職業生涯說明下背景。我想我們很多人會認為自己是高階工程師。或者是還差一點點,但我們想成為一個高階工程師。我認為高階的意思是我幾乎可以解決其他人可能丟擲的任何問題。我熟悉我的工具,我熟悉我的領域。而這項工作的另一個重要部分是我讓初級工程師最終成為高階工程師。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:初級 -> 高階 -> ?

但是會發生什麼呢?在某種程度上,我們可能會懷疑“下一步可能是什麼?”。當我們達到這個高階階段時,我們接下來要做什麼?對於我們中的一些人來說,答案可能是做管理,但我認為這不應該成為每個人的答案,因為不是每個人都應該成為管理者,對嗎?我們中有些人是非常優秀的工程師,為什麼我們不應該在我們的餘生中也這樣做?

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:“我知道我會如何解決問題”

我想提出一種方法來升級到高階水平。我把自己當作高階工程師的方式是,我會說:“我知道如何解決這個問題”,並且因為我知道如何解決這個問題,所以我也可以教別人去解決它。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:“我知道別人怎麼解決這個問題”

我的理論是,下一個層次是我可以對自己說:“我知道別人會如何解決這個問題”。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:“我可以預測 API 選擇和抽象如何影響其他人解決問題的方式。”

讓我們更具體一點。你說了這樣一句話:“我可以預見我做出 API 選擇時,或者我往專案中引入抽象時,它們如何影響其他人解決問題。”我認為這是一個強大的概念,可以讓我思考我所做的選擇對應用程式的影響。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:同理心的應用。

我會稱之為同理心的應用。你在和其他軟體工程師一起思考,你在思考你所做的事情以及你給他們的 API 是怎麼樣的,以及它們如何影響其他工程師編寫軟體。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:對簡易模式感同身受。

幸運的是,這是對簡易模式感同身受。同理心通常很難,而且這仍然非常困難。但至少與你有同感的人,他們也是軟體工程師。儘管他們可能與你截然不同,但他們至少同你一樣也在開發軟體。當你獲得更多的經驗時,你可以很擅長的運用這種型別的同理心。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:程式設計模型。

考慮到這些話題,我想談談一個非常重要的術語,那就是程式設計模型,這個詞我會用很多次。它代表“給定一套 API,庫,框架或工具,人們如何在這種背景下編寫軟體”。我演講的真正內容是關於 API 等細微變化對程式設計模型的影響。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:影響程式設計模型的示例:React,Preact,Redux,Date picker,npm。

我想舉幾個影響程式設計模型的例子:假設你有一個 Angular 專案,並且你說:“我將把它移植到 React 中”,這顯然會改變人們編寫軟體的方式,對吧?但是接下來你想:“啊哈,60 KB 就為了使用一點虛擬 DOM 操作,讓我們切換到 Preact”,這是一個 與 React API 相容的庫,即使你做出了這個選擇,它也不會改變人們編寫軟體的方式。或許隨著專案的進展,你會覺得“單單 React 自有的狀態管理還不夠,應用會變得很複雜,我應該有一些東西來管理應用狀態,我會引入 Redux”,這將改變人們編寫軟體的方式。然後又來了個新需求“我們需要一個日期選擇器”,你到 npm 上進行搜尋,有 500 個結果,你選了一個日期元件。你挑選哪一個真的很重要嗎?它絕對不會改變你編寫軟體的方式。但是,npm 以及它的龐大生態集合,絕對會改變你編寫軟體的方式。當然,這些只是可能影響人們如何編寫軟體的幾個例子。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:程式碼分割.

現在我想談談所有大型 JavaScript 應用在將它們交付給使用者時的一個共同點:它們最終變得非常大,以至於你不希望一開始就把整個應用一次性傳輸給使用者。為此,我們引入了這種稱為程式碼分割的技術。程式碼分割意味著你為應用程式定義了一組打包。所以,你會說“有些使用者只使用我的應用程式的這一部分,有些使用者使用另一部分”,因此,當使用者實際使用應用程式時,只有使用到的部分才被下載執行。這是我們所有人都可以做到的。像許多事情一樣,它是由閉包編譯器實現的 —— 至少在 JavaScript 世界中。但我認為使用 webpack 進行程式碼分割是最流行的方式。如果你使用的是 RollupJS,這是超棒的,他們最近也增加了對程式碼分割的支援。程式碼分割絕對是你們應該做的事情,但是當你將它引入到應用程式中時有一些事情需要考慮,因為它確實對程式設計模型有影響。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:同步 -> 非同步。

你有過去是同步現在成為非同步的東西。你的應用程式在沒有程式碼分割時,簡單美好。整個專案只有一件大事。它啟動,然後它很穩定,你瞭解它的前世今生,你不必等待資源載入。有了程式碼分割後,有時候你可能會說“哦,我需要那個打包檔案”,所以你現在需要利用網路來獲取所需的檔案,這也使得你必須考慮網路可能出現異常情況,所以應用程式也變得更加複雜。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:人性化。

此外,我們需要有人介入,因為程式碼拆分需要你定義如何打包,需要你考慮何時載入它們,所以,那些在你們團隊的工程師們現在必須決定哪些檔案打包到一起,什麼時候載入那些打包檔案。每次有人介入時,都會明顯影響程式設計模型,因為他們必須考慮這些問題。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:基於路由的程式碼分割。

有一種非常成熟的方法可以解決這個問題,它可以將我們從進行程式碼分割的混亂中解脫出來,它被稱作基於路由的程式碼分割。如果你還沒有使用程式碼分割,那它可能是你初次進行程式碼分割的方式。路由將應用程式以 URL 粒度進行分割。例如,你的產品頁面可能在 /product/ 上,並且你的分類頁面可能在其他地方。你只需將每個路由用的檔案打包到一起,然後你的應用程式將根據路由自動進行程式碼分割。無論何時使用者訪問路由,路由都會載入相關的打包檔案,有了路由之後,你可以忘記程式碼分割的存在。再從程式設計模型上來看,這幾乎與將所有東西都打包到一起一樣。這是一種非常好的程式碼分割方法,絕對是個好的開始。

但是這個演講的主題是設計非常大型的 JavaScript 應用程式,並且這類應用程式很快會變得巨大無比,路由本身也會隨之變大,以至於基於路由的程式碼分割不再適用。實際上我有一個關於這類應用程式的好例子。

[譯] 設計大型 JavaScript 應用程式

“public speaking 101”的谷歌搜尋查詢截圖。

我正在弄清楚如何成為這場演講的公眾演講者,並且我得到了一個很好的藍色連結列表。你完全可以設想這個頁面非常適合將所有檔案打包到一個路由裡。

[譯] 設計大型 JavaScript 應用程式

“weath”的谷歌搜尋查詢截圖。

但後來我對天氣感到疑惑,因為加州有一個嚴峻的冬天,突然間有了這個完全不同的模組。所以,這個看似簡單的路由比我們想象的更為複雜。

[譯] 設計大型 JavaScript 應用程式

“20 usd to aud”的谷歌搜尋查詢截圖。

後來我被邀請參加這次會議,我檢視了 1 美元是多少澳元,那時出現了這個複雜的貨幣轉換器。很顯然,這些專用模組大約有 1000 多個,將它們放在同一個打包檔案中是不可行的,因為打包檔案的大小會有幾兆位元組,使用者將會真的變得不高興。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:元件級別的懶載入?

所以,我們不能只使用基於路由的程式碼分割,我們必須想出一個不同的方式來做程式碼分割。基於路由的程式碼拆分很不錯,因為你將應用程式進行了最粗略級別的拆分,而當應用程式進一步增長時,它能起到的作用就微乎其微了。因為我喜歡直截了當,那麼做超級細粒度而不是超級粗粒度拆分怎麼樣。讓我們想象如果我們網站的每一個元件都懶載入,會發生什麼。當你只考慮頻寬時,從效率的角度來看,這似乎非常好。從延遲等其他觀點來看,這可能是非常糟糕的,但它肯定是值得考慮。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:React 元件同他們的子元件是靜態依賴關係。

但讓我們想象一下,例如,你的應用程式使用 React。並且在 React 中,元件們同他們的子元件是靜態依賴關係。這意味著如果你懶載入你的子元件,就會改變你的程式設計模型,並且事情會變得不那麼美好,這讓你只好叫停這種策略。

[譯] 設計大型 JavaScript 應用程式

ES6 匯入示例。

假設你有一個貨幣轉換器元件,你想把它放在你的搜尋頁面上,你可以匯入它,是這樣的吧?這是在 ES6 模組中使用的普通方式。

[譯] 設計大型 JavaScript 應用程式

Loadable 元件示例。

但是如果你想延遲載入它,你會得到這樣的程式碼,你把它包裝在 Loadable 元件中,你還使用一種懶載入 ES6 模組的新方式動態匯入。當然有成千上萬種方法可以做到這一點,我不是 React 專家,但所有這些方式都會改變你編寫應用程式的方式。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:靜態 -> 動態。

事情不再那麼美好了 —— 一些靜態的東西現在變成了動態的,這是程式設計模型改變的另一個警示。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:誰來決定何時對什麼東西進行懶載入?

你不得已突然想知道:“誰來決定何時對什麼東西進行懶載入”,因為這會影響到應用程式的等待時間。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:靜態還是動態?

人類再次出現,他們必須思考“有靜態匯入,有動態匯入,什麼時候該用哪一個?”。弄錯就非常糟糕了,當一個靜態匯入的檔案突然變成動態匯入的時候,可能會把某些東西錯誤的打包進檔案。隨著時間的推移,同時你又有很多工程師在這個專案上開發,恐怕就會出錯。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:分割邏輯和渲染。

接下來我會分享 Google 如何做到保證良好程式設計模型的前提下,又有不錯的效能的。我們通過渲染邏輯和應用邏輯來分割元件,比如當你按下貨幣轉換器上的按鈕時發生的情況。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:僅在渲染時載入是唯一的載入邏輯。

所以,現在我們有兩件獨立的事情,並且我們只在渲染時才載入元件的應用程式邏輯。事實證明,這是一個非常簡單的模型,因為你可以簡單地在服務端渲染頁面,然後由實際呈現的內容,觸發下載關聯的應用程式打包檔案。因為載入是通過渲染自動觸發的,這使得人得以脫離系統。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:搜尋結果頁面上的貨幣轉換器。

這個模型看起來不錯,但它確實有一些折中。如果你知道通常服務端渲染在 React 或 Vue.js 等框架中如何工作,這個過程被稱為 hydration。hydration 是這樣的,你服務端渲染的一些東西,然後在客戶端再次渲染它,這意味著你必須載入程式碼來渲染一些已經在頁面上的東西,這在載入程式碼和執行程式碼方面都是巨大的浪費。這麼做既浪費頻寬,又浪費 CPU —— 但它確實很好,因為你在客戶端忽略了服務端渲染的東西。我們在 Google 使用的方法不是那樣的。所以,如果你設計這個非常大型的應用程式,你就會想:我是採用那種更復雜的超快速方法,還是採用效率較低的 hydration 方式,但這樣能有個良好的程式設計模型?你將不得不做出這個決定。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:2017 新年快樂。

我的下一個話題是我最喜歡的電腦科學問題 —— 它不是命名問題,儘管我很可能給它起了個糟糕的名字。這是“2017 年假期特別問題”。過去有人寫過一些程式碼,現在不再需要它們了,但它仍然在你的程式碼庫中?...這種情況時常發生,我認為 CSS 的問題尤為突出。你有一個大型 CSS 檔案。裡面有很多樣式選擇器。誰真的知道哪些樣式選擇器是否仍然對應著你應用中的內容?所以,你最終只能把那些程式碼留在那裡。我認為 CSS 社群處於變革的最前沿,因為他們意識到這個問題,並且他們建立了諸如 CSS-in-JS 之類的解決方案。因為你的元件可以放到一個單獨的檔案裡,2017 年假期特別問題元件,你可以說“它不再是 2017 問題”,你可以刪除整個元件,並且所有相關檔案一併消失。這使得刪除程式碼非常容易。我認為這是一個非常好的想法,它不僅僅適用於 CSS。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:不惜一切代價避免中央配置。

我想舉幾個例子,說明為什麼你想不惜一切代價避免在你的應用程式中採用中央配置,因為中央配置(比如大型 CSS 檔案)使得程式碼難以刪除。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:routes.js。

我之前在你的應用程式中談論過路由。許多應用程式都會有一個類似“routes.js”的檔案,其中包含所有路由資訊,這些路由將自己對映到某個根元件。這是一箇中央配置的例子,你不會希望在大型應用程式中這麼做。因為有了這種中央配置,工程師會說:“我還需要那個根元件嗎?我需要更新其他檔案,那是其他團隊負責的檔案。我不確定是否被允許修改它。也許我該明天再做“。之後,這些檔案只會越來越大。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:webpack.config.js。

這種反模式的另一個例子是 webpack.config.js 檔案,在這裡你可以假設你通過它構建了整個應用程式。剛開始可能沒什麼問題,但隨著時間的推移,這份配置不再適用,你需要知道其他團隊在應用程式中做了什麼,這樣才能對配置檔案做出相容性的調整。再一次,我們需要一個模式來展現如何分散我們構建過程的配置。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:package.json。

這有一個很好的例子:npm 使用的 package.json。每個軟體包都會說“我有這些依賴關係,這就是你如何執行我,如何構建我的方式”。顯然,對於所有的 npm,都不能有一個巨大的配置檔案。這對於成千上萬的檔案來說不起作用。這肯定會讓你在 git 操作中遇到很多合併衝突。當然,npm 非常大,但我認為我們的許多應用程式已經變得足夠大,讓我們不得不擔心同樣的問題,並且必須採用相同的模式。我沒有所有的解決方案,但我認為 CSS-in-JS 的想法將會涉及我們應用程式的其他方面。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:依賴關係樹。

更抽象地說,我會描述這個想法,即我們負責如何抽象地設計我們的應用程式,如何組織它,作為承擔塑造我們的應用程式的依賴樹的責任。當我說“依賴”時,我的意思是非常抽象的。它可能是模組依賴關係,可能是資料依賴關係,服務依賴關係,還有很多不同的型別。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:由路由和 3 個根元件構成的依賴關係樹示例。

顯然,我們都有超複雜的應用程式,但我會用一個非常簡單的例子。它只有 4 個組成部分。它有一個路由,知道如何從應用程式的一個路由到下一個路由,它有幾個根元件:A、B 和 C。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:中心匯入問題。

正如我之前提到的那樣,這具有中心匯入問題。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:由路由和3個根元件構成的依賴關係樹示例。路由匯入根元件。

因為路由現在必須匯入所有的根元件,如果你想刪除其中的一個,你不得不進入路由檔案,刪除引用,刪除路由,並最終你有了 2017 假期特別問題。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:匯入 -> 增強。

我們在谷歌已經為此提出了一個解決方案,我想向你們介紹一下,我想我們從來沒有談過這件事。我們提出了一個新概念。它被稱為增強。這是你用來代替匯入的東西。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:匯入 -> 增強。

實際上,這與匯入是相反的。這是一個逆向依賴。如果你增強一個模組,你會讓這個模組對你有依賴性。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:由路由和3個根元件構成的依賴關係樹示例。根元件增強了路由。

看看依賴關係圖,它發生了什麼,仍然是相同的元件,但箭頭指向相反的方向。因此,不是路由匯入根元件,根元件宣佈自己增強了路由的功能。這意味著我可以通過刪除檔案來刪除根元件。因為它不再增強路由,所以這是刪除元件的唯一操作。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:誰來決定何時使用增強?

這真的很棒,如果它不是再次涉及人性化。他們現在必須考慮“我是該匯入它,還是使用增強?我在哪種情況下使用哪一種方式?”。

[譯] 設計大型 JavaScript 應用程式

圖片:危險。危險化學品。

這是這個問題的特別糟糕的情況,因為增強模組的能力,能夠使系統中的所有其他東西都依賴於你是非常強大的,如果出錯的話,就會非常危險。很容易想象這可能會導致非常糟糕的情況。所以,在谷歌我們認為這是一個好主意,但我們也認為它是非法的,沒有人可以使用它 —— 有一個例外:生成的程式碼。它實際上非常適合於生成的程式碼,它解決了生成程式碼的一些固有問題。有了生成的程式碼,你有時必須匯入你甚至看不到的檔案,必須猜測他們的名字。但是,如果生成的檔案恰好不可見,並增強了它所需的任何內容,那麼你就沒有這些問題。你根本不需要知道這些檔案。他們只是神奇地增強了中央登錄檔。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:單檔案元件指向其增強路由的元件。

我們來看一個具體的例子。我們這裡有個單檔案元件。我們在其上執行程式碼生成器,並從中提取這個小的路由定義檔案。那個路由檔案只是說“嘿,路由,我在這裡,請匯入我”。顯然,你可以將這種模式用於各種其他事情。也許你正在使用 GraphQL,你的路由應該知道你的資料依賴關係,那麼你可以使用相同的模式。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:基本打包檔案。

不幸的是,這不僅僅是我們所需要知道的。第二個我最喜歡的電腦科學問題,我稱之為“基礎垃圾打包檔案”。在應用程式的打包邏輯中的基本打包檔案總是會被載入,而與使用者與應用程式的互動方式無關。所以,這一點尤其重要,因為如果它很大,那麼所有進一步深入的東西都會很大。如果它很小,那麼依賴檔案也有可能變小。一個小故事:在某個時候,我加入了 Google Plus JavaScript 基礎架構團隊,並且我發現他們的基礎打包檔案包含 800 KB 的 JavaScript。所以,我對你的警告是:如果你想比 Google Plus 更成功,就不要讓你的 JS 基礎打包檔案超過 800 KB,但不幸的是你的檔案體積很難維持在理想狀態。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:指向 3 個不同依賴關係的基礎打包檔案。

這有一個例子。你的基礎打包檔案需要依賴於路由,因為當你從 A 到 B 時,你需要知道 B 的路由,所以它總是在周圍。但是你真正不想要的是將任何形式的 UI 程式碼打包進基礎打包檔案,是因為取決於使用者如何進入你的應用程式,可能會有不同的使用者介面。所以,例如日期選擇器絕對不應該放在你的基礎打包檔案中,結賬流程也不應該。但我們如何防止這種情況?不幸的是匯入非常脆弱。你可能在無意中匯入那個很酷的工具包,因為它有一個函式來生成隨機數。現在有人說“我需要一種自動駕駛汽車的實用工具”,並且突然將自動駕駛汽車的機器學習演算法匯入到你的基礎打包檔案中。類似這樣的事情很容易發生,因為匯入是傳遞性的,所以問題往往會隨著時間的推移而累積起來。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:禁止依賴測試。

我們找到的解決方案是禁止依賴測試。禁止依賴測試是一種斷言,例如你的基礎打包檔案不依賴於任何 UI。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:斷言基本打包檔案不依賴於 React.Component。

我們來看一個具體的例子。在 React 中,每個元件都需要繼承自 React.Component。因此,如果你的目標是基本打包檔案中沒有 UI,只需新增一個測試來確定 React.Component 不是你基本打包檔案的傳遞依賴。

[譯] 設計大型 JavaScript 應用程式

禁止的依賴關係被刪除。

再看一下前面的例子,當有人想新增日期選擇器時,只會出現測試失敗。而這些測試失敗通常很容易就能很好地解決,因為通常這個人並不是真的想要新增依賴關係 —— 它只是通過一些傳遞路徑進入。比較這一點,當這種依賴關係已經存在了 2 年,因為你沒有測試。在這些情況下,通常很難通過重構程式碼來擺脫依賴關係。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:最自然的路徑。

理想情況下,你會發現最自然的路徑。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:最直接的方式必須是正確的。

你想要達到這樣一個狀態,無論你的團隊中的工程師做什麼,最直接的方式也是正確的方式 —— 這樣他們就不會離開這條道路,所以他們自然而然地做了正確的事情。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:否則新增一個確保正確的測試。

這可能不總是可行的。在那種情況下,只需新增一個測試。但這不是很多人認為有權做的事情。但是,為確保你的基礎架構保持不變,請為你的測試程式新增測試的授權。測試不僅僅是為了測試你的數學函式是否正確。它們也用於基礎架構和應用程式的主要設計特性。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:避免在應用領域之外進行人為判斷。

儘可能避免在應用領域之外進行人為判斷。在開發應用程式時,我們必須瞭解業務,但是並非團隊中的每位工程師都能理解程式碼拆分的原理。而且他們不需要那樣做。在不是每個人都能理解它們的時候,試著將這些東西以一種友好的方式引入到你的應用程式中,並保持其複雜性。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:可以輕鬆刪除程式碼。

真的,讓刪除程式碼簡單點。我的演講題為“構建非常大型的 JavaScript 應用程式”。我可以給出的最佳建議:不要讓你的應用程式變得非常大。最好的辦法是在還來得及的時候開始刪除東西。

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:沒有抽象比錯誤的抽象更好。

我想再談一點,那就是人們有時會說,沒有抽象比錯誤的抽象要好。這實際上意味著錯誤的抽象代價非常高,所以要小心。我認為這有時會被誤解。這並不意味著你不應該有抽象。這只是意味著你必須非常小心。

我們必須善於找到正確的抽象

[譯] 設計大型 JavaScript 應用程式

幻燈片文字:同理心和經驗 -> 正確的抽象。

正如我在演講開始時所說的:實現目標的方式是使用同理心,並與團隊中的工程師一起思考他們將如何使用你的 API​​ 以及他們將如何使用抽象。你如何隨著時間的推移充實這種同理心會成為經驗。綜上所述,同理心和經驗使你能夠為你的應用程式選擇正確的抽象


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章