Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲精品一区二区三区婷婷 ,国产成人一区二区三区,欧美成人在线免费视频

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript 前端框架維護者對 2024 年的預測

          者 | Loraine Lawson

          譯者 | 張衛濱

          策劃 | Tina

          本文最初發表于The New Stack網站,由 InfoQ 中文站翻譯分享。


          在 2024 年,前端領域會有怎樣的發展呢?因為沒有人能夠預見未來,所以 The New Stack 與來自 Angular、Next.js、React 和 Solid 的創建者和維護者討論了他們 2024 年的計劃。以下是前端開發者對未來一年的展望。


          Angular:可選的 Zone.js


          來自谷歌的 Angular DevRel 技術主管和經理Minko Gechev說,在過去的一年里,Angular 的兩大成就是引入了基于Signals的細粒度反應性和可延遲視圖。他告訴 The NewStack,新的一年將會在此基礎上進一步關注細粒度的反應性,并使 Zone.js 成為可選的。


          在 Angular 中,Zone 是一個執行上下文,它能夠跨異步任務持續存在。在這個GitHub倉庫中詳細介紹了Zone,它有五個職責,包括攔截異步任務調度和包裝回調以便于進行錯誤處理,以及跨異步操作的 zone 跟蹤。Zone.js 可以創建跨異步操作而持久化存在的上下文,也可以為異步操作提供生命周期鉤子。


          Gechev 說,“我們正在探索為現有的項目實現可選的 Zone.js,開發人員可以通過重構現有的應用程序來利用這一特性”。“借助可選的 Zone.js,我們期待加載時間能夠得以改善,并實現更快的初始渲染。對細粒度反應式的處理將提升到一個新的層次,使我們能夠僅探測組件模板的部分變更。”


          他說,這些特性將會帶來更快的運行時。


          在關于性能的另一個方面,Angular 正在考慮是否默認啟用混合渲染。他補充說,選擇避免混合渲染是可能實現的,因為這會增加托管需求和成本。


          Gechev 說,“我們看到了 SSG(靜態站點生成,static site generation)和 SSR(服務器端渲染,server-side rendering)的很多價值,而且在 v17 中奠定了堅實的基礎,我們正在進行最后的潤色工作,以便從一開始就實現這種體驗。”


          他補充到,另一個優先事項是完成Signals請求的評論(Request for Comment)。


          開發人員還可以看到 Angular 文檔的改進。根據對開發人員的調查,他們希望能有一個升級的學習體驗,其中包括讓 Angular.dev 成為該框架新的托管地。他補充說,開發人員還優先考慮了初始加載時間(混合渲染、部分填充和可選的 Zone.js 應該可以部分解決該問題)和組件編寫,Angular 計劃會進一步簡化組件的編寫。


          Gechev 說,“我們致力于迭代式地交付特性,并隨著時間的推移逐步增強它們”。“開發人員將能夠從 2024 年的所有改進中受益,并在接下來的幾年里獲得更好的開發體驗和性能。”


          Next.js:新的編譯器


          Next.js 在 2023 年引入了一個新的應用服務器,旨在支持 React 服務器組件(React Server Component,RSC)和Server Action。Vercel(該框架的監管者)的產品負責人 Lee Robinson 說,該框架會繼續支持舊的服務器,并且其路由系統可以在兩者實現互操作性。這種互操作性意味著可以繼續花時間添加新的特性。


          Robinson 說,“有些客戶已經使用 Next.js 進行開發有五六年之久了,他們也會需要花費幾年的時間來采用這些新特性。在這個過程中,我們希望他們的工作能夠盡可能地順暢。”


          在新的一年中,Next.js 希望要解決很多問題,其中一個優先事項就是簡化緩存。他說,從開發人員的體驗來看,這可能會使其更加容易。


          Robinson 說到,“通常情況下,生態系統中的許多開發人員必須引入一堆額外的包,或者學習如何使用其他的工具來進行數據抓取、緩存和重現校驗”。“現在,Next.js 已經構建了很多這樣的特性,而且非常強大,但是這也意味著需要學習更多的東西,我們得到的初步反饋是,‘這非常棒,也很強大,但是我們希望它能更簡單一些’”。


          Next.js 團隊還將繼續關注性能的改進,他將其稱之為“我們的持續投資”。


          他補充到,在新的一年里,這很可能會以新編譯器的形式出現,它將加快在開發人員的機器上啟動 Next.js 的速度。該編譯器相關的工作已經進行了大約一年的時間,Vercel 一直在其內部產品和應用中使用它。他說,這個使用 Rust 編寫的編譯器即便在沒有使用的緩存的情況下也比之前啟用緩存的編譯器更快。


          Robinson 說,“距離推出這個功能已經近在咫尺了,甚至到了每個人都可以默認啟用它的程度,而且它比現有基于 Webpack 的編譯方案更快”。“開發人員總是希望他們的工具能夠更快。他們對工具運行速度的追求永無止境。因此,很有意思的一件事是,工具的制造商,而不是工具的使用者在開始轉向像 Rust 這樣的底層工具,從而幫他們實現性能方面的最終勝利。”


          他們的第三個目標是為未來十年的 Next.js 奠定基礎。


          他說,“我們對這個新的路由系統感到非常興奮。我們相信這是未來的基礎。但是,這也需要時間。人們會嘗試使用,從而有特性方面的需求,并且希望能夠看到實際的改變。我們將其視為未來五年至十年的長期投資。”


          他補充說,一個“某天”可能會實現的目標是在 Next.js 中找到更好方式來處理內容,不過這應該不會新的一年中實現。


          他補充說,“現在,它依然能夠正常運行,你依然可以連接到任何你想要的內容源,但是會有一些潛在的方式能夠簡化開發人員的體驗”。“這更像是一件錦上添花的事情,而不是必須要做的事情,這就是為什么我認為在 2024 年我們不會實現它,但我希望未來會為其做一些相關的工作。”


          React:2024 預覽

          Meta 的 React 工程主管 Eli White 說,React 團隊希望在新的一年里會有更多的框架采用 React 服務器組件(RSC,React Server Component)。


          White 說,“對大多數人來講,他們認為 RSC 是 React 領域的重要變化,從一個單純的 UI 層,變成對如何架構應用程序的方式都能產生更大的影響,以獲得最佳的用戶和開發人員體驗,特別是對于單頁應用程序(SPA,single page application)方式表現不夠好的應用程序。”


          雖然他沒有明確說明 2024 年的新動向,但是 White 表示他們將發布和分享 2023 年相關事項的更多進展。比如,在 React Advanced 會議上,團隊向與會者展示了 React Forget,這是 React 的自動記憶編譯器。White 說,有了React Forget之后,將意味著開發者不再需要使用useMemo和useCallback。


          White 補充說,“在 React Native EU 會議上,我們分享了從 0.73 版本開始將 web 開發人員熟悉的 Chrome 開發工具引入 React Native。我們還初步展示了對 Static Hermes 的研究成果,這是針對 JavaScript 的原生編譯器,它不僅有可能加快 React Native 應用程序的速度,而且會從根本上改變 JavaScript 的用途。”


          Solid:專注于基本元素(Primitive)

          Solid 創始人 Ryan Carniato 表示,在 2024 年,Solid 開發人員可以期待即將推出的SolidStart 1.0和 Solid.js 2.0。SolidStart 是一個元框架,這意味著它建立在框架 Solid.js 之上。他說,這類似于Svelte的SvelteKit。


          SolidStart的文檔是這樣描述的:

          “Web 應用程序通常包含很多組件,比如數據庫、服務器、前端、打包器、數據抓取/變更、緩存和基礎設施。編排這些組件很具挑戰性,并且通常需要跨應用程序技術棧共享大量的狀態和冗余邏輯。這就是 SolidStart 的用武之地,它是一個元框架,提供了一個將所有這些組件組合在一起的平臺。”


          由于 SolidStart 仍處于 beta 階段,Carniato 有機會利用生態系統中已有的東西將其變得更好。

          Carniato 說,“其中很重要的一點是,我們現在不再需要編寫自己的部署適配器,而是可以使用 Nitro,它也支撐了 Nuxt 框架,這使得我們可以將其部署到所有的不同平臺上。”


          另外一個樣例是任何 Solid 路由器都能在 SolidStart 中運行。


          他說,“這意味著對路由器的底層部分進行了大量更新,這樣它們才能一起運行,但最終結果令我非常高興,因為我們小團隊的志愿者需要維護的代碼量要少得多,這給了開發人員很大的靈活性。”“他們不必被迫采用單一的解決方案,這對我來說非常重要,因為每個人都有自己的需求。正如我所言,如果你構建了正確的組件并且能夠弄清楚構建基塊(building block),那么人們可以做更多的事情。”


          他說,最終的結果是由“可互換”的組件所組成的元框架,而不是具有很強的傾向性。Solid 團隊一直在思考,在由越來越多的元框架決定開發人員能夠使用什么的世界中,正確的基本元素所帶來的影響。


          他說,“對我來講,最重要的一直是基本元素形成的構建基塊,這是一個非常工程化的關注點,我認為這也是它與眾不同的原因之一。”“我一直喜歡給別人選擇的權力,并且我認為如果有正確的基本元素,正確的構建基塊,就可以構建出正確的解決方案。”


          他表示,Solid 2.0 應該會在 2024 年中后期發布。現在,他們正在實現如何處理異步系統的原型。


          Carniato 說,“Solid 2.0 也將是一個非常重要的版本,因為我們正在重新審視反應式系統,并思考如何解決異步信號或異步系統的問題。”


          他補充說,Solid 試圖在控制和性能之間取得平衡。


          他說,“在我們的社區里,有很多非常熱情的人,非常有技術頭腦的人,他們關注性能,關心控制。”“我們確實吸引了很多人,他們真的想控制自己建造的每一個組成部分。”

          原文鏈接:https://www.infoq.cn/article/7ciYZE56w7KENEGOjfQY

          者 | Adrien Joly

          譯者 | 張衛濱

          策劃 | 丁曉昀

          有時候,JavaScript(甚至帶有類型檢查的 TypeScript)會因為其不可預測的特性和缺乏約定而遭到批評。對于那些知道 JavaScript 是為 web 瀏覽器設計的腳本語言的人來說,這就不足為奇了。


          但是,現在它已經成為開發全棧 web 的首選語言,也是跨平臺移動應用的熱門方案。那么,當開發人員的 JavaScript/TypeScript 代碼庫開始老化,由此帶來的復雜性痛苦地增長時,他們該采取什么行動才能最大限度地減少資源浪費并保持工作滿意度呢?


          本文將基于我 10 多年來編寫 JavaScript 代碼的經驗和 5 年多拯救 JS/TS 項目的經歷,向讀者介紹如下內容:


          • 如何評估 JS/TS 代碼庫的質量和風險。
          • 對于需要修復的部分,該如何確定其優先級。
          • 有哪些非破壞性的方法可以讓 JS/TS 代碼庫逐漸變得更健康。


          清理工作臺

          在開發下一個特性時,每個警告、類型錯誤或非正常的測試都會讓開發人員浪費時間、精力和專注度。


          代碼警告尤其令人討厭,因為開發人員會習慣性地忽略它們,“只要一切按預期運行就好”。因此,它們會迅速累積,當我們遇到缺陷、事故或系統的意外行為時,就很難將其作為有用的線索。


          類型錯誤就是一個很好的樣例。當我們的用戶遵循“快樂路徑(happy path)”時,這些錯誤似乎無關緊要,因為軟件似乎能夠按照預期運行。所以,我們可能會使用@ts-ignoreany或類型斷言來暫時忽略它們。但是,這樣做的話,就意味著如果有一天用戶選擇不同的路徑,就會面臨運行時錯誤。


          這樣的話,開發人員就需要調查、重現和修復一個新的缺陷,而這個缺陷恰恰是他們幾個月前允許走捷徑所造成的。如果你的代碼被各種警告和/或暫時忽略這些警告削弱了質量,那么找到這個捷徑將耗費大量的時間。



          當生產環境的數據庫因“內存不足”錯誤而崩潰時,該警告可能會幫助開發人員找到崩潰的原因


          警告和類型錯誤是查找缺陷和事故的線索。我們累積(或忽略)的警告和錯誤越多,開發人員就會花費越多的時間去調查。如果代碼是他們很久以前編寫的,那情況就會更糟糕了。


          我們能做些什么呢?


          1. 確保開發人員在開發過程中能夠盡快看到警告和類型錯誤。這不應該花費額外的成本。如果可能的話,集成到他們的 IDE 中。
          2. 不要讓警告和類型錯誤累積。盡快修復它們。
          3. 提高信噪比。如果團隊一致認為某條引發警告和類型錯誤的規則沒有用處的話,就干脆禁用它。
          4. 如果你確信需要在代碼的特定部分忽略掉某條規則的話(也就是,使用 code>@ts-ignore、any或類型斷言),請添加注釋以記錄忽略該規則的原因。
          5. 不要在運行時添加 try-catch 代碼塊來捕獲編程錯誤(比如,業務邏輯中意料之外的未定義值)。而是要使用這種代碼塊來處理外部系統的預期錯誤(如輸入/輸出異常、校驗、環境問題等)。在開發過程中,應使用靜態代碼分析和單元測試來捕獲編程錯誤。
          6. 不要讓帶有警告和類型錯誤的代碼進入生產環境。使用持續集成流水線來強制要求這一規則。



          類型檢查器認為缺少一個預期的屬性。忽略這個錯誤將意味著要承擔持久化不一致數據的風險,在幾個月之后,你可能需要花費幾天的時間來調查和解決這個問題


          我們可以使用哪些工具來實現這一目標呢?


          有許多靜態代碼分析工具可供使用,最常用的包括:


          • ESLint,能夠用來探測代碼中的語法錯誤和反模式;
          • TypeScript(啟用嚴格的規則),借助.ts文件或JSDoc注解以探測類型錯誤;
          • 除此之外,SonarCloud、SourceGraph、Codacy或類似的在線工具服務也有助于跟蹤共享代碼庫中多個代碼質量度量指標的變化情況。


          警告也可能來自其他工具:依賴安裝器(如npmyarn)、打包器(如webpack)、代碼處理器(babelscss)和執行環境(CI 運行器)。不要忽視它們!


          如果遵循這些建議會讓你的代碼變得非常冗長和/或復雜(比如防御式代碼),你可以需要對其進行重新設計。


           "scripts": {
              "lint": "eslint .",
              "lint:fix": "eslint . --fix",
              "lint:errors": "eslint . --quiet",
              "lint:typescript": "tsc --noEmit --skipLibCheck",
              "lint:jsdoc-typing": "tsc --noEmit --allowJs `find ./ -name '*.js' -name '*.d.ts'`"
            },

          復制代碼


          借助靜態代碼分析器和 npm 腳本,能夠讓開發人員輕松快速地探測有問題的代碼


          后續該怎么辦?


          安裝和配置靜態代碼分析工具是一個良好的開端,但這還不夠。


          要想取得持續的成功,要確保開發團隊做到如下幾點:


          • 充分認識到部署不含編程錯誤的代碼的重要性,并相信靜態代碼分析可以幫助他們實現這一點;
          • 充分理解 TypeScript 的運行原理(參見TypeScript: Handbook)
          • 定期修復警告和類型錯誤,起碼要比引入它們的頻率更高;
          • 保持這些措施,永不間斷。


          如下幾種策略可能會提供幫助:


          • 獎勵提高代碼質量的代碼貢獻行為,從而激勵開發人員。其中,有種方法是使用可插入持續集成流水線的工具來跟蹤開發人員推送的每個變更的代碼質量變化,例如可以使用 SonarCloud 和/或 Codacy。
          • 讓一名開發人員負責確保代碼質量永不下降。
          • 讓另一名開發人員負責定期更新依賴,從而能夠讓團隊能夠從它們的邏輯和安全修復中受益。


          為何要把每個角色都交給一個專門的人?


          當某項職責沒有人負責時,集體責任往往會被其他“優先事項”所取代(比如,本周多交付一個特性,但是代價是忽略一個警告)。


          定期輪換角色,確保每個人都能參與其中并保持積極性。


          使用(恰當類型的)測試覆蓋關鍵的業務邏輯


          現在,我們有了一支致力于保持代碼庫整潔的團隊,我們相信用戶很少會遇到編程錯誤。


          但是,業務邏輯中的錯誤該怎么辦呢?


          例如,如果一個新添加的功能破壞了另一個功能該怎么辦?如果開發人員從一開始就誤解了該功能的預期行為,又該怎么辦?如果這樣的錯誤最終導致了嚴重的收入損失又該如何處理?


          與編程錯誤類似,業務邏輯問題可能會在生產環境由用戶發現,但我們更希望盡早發現它們。因此,定期測試軟件非常重要,這個過程可以使用自動化和/或手動測試。


          從業務角度看,測試有兩個作用:


          • 符合功能性需求:每個特性的實現都能滿足開發時的需求。
          • 檢測回歸:在對代碼進行任何修改后,所有現有的特性都能按照預期運行。


          確保功能性測試(也稱為“驗收測試”)涵蓋大多數關鍵業務特性,單元測試或集成測試涵蓋大多數關鍵技術組件。此外,確保持續集成在任何測試失敗時都能向開發人員提供可執行的反饋。


          對于有些開發人員來說,將測試工作委托給其他人(如產品負責人或 QA 團隊)是很有誘惑力的做法。在每個新特性完成后,進行一次這樣的委托測試,以確保特性實現符合功能性需求,并進行協作迭代,這樣做可能是合理的。


          但是,委托他人進行回歸檢測并不是一個好主意,原因包括:


          • 它增加了合并代碼和部署代碼之間的延遲。
          • 它增加了發現回歸問題和修正它們之間的延遲。
          • 隨著功能性范圍的不斷擴大,檢測回歸所需的時間也會隨之增長。如果負責這些測試的人沒有將其自動化,他們最終可能會跳過越來越多的測試。因此,一段時間之后,出現回歸測試未發現問題的風險就會越來越高。


          回歸測試是一項痛苦且可能代價高昂的負擔,尤其是需要不同角色(如產品負責人和開發人員)必須協作的情況下。從長遠來看,回歸測試自動化意味著可以節省大量的時間,而且開發人員具有編寫自動化測試的技能,所以,開發人員首先要承擔起檢測回歸的責任,而不必讓其他角色參與進來,這符合他們的利益。


          如果要涵蓋的功能范圍很大該怎么辦?


          從最關鍵的業務特性開始。要找出這些特性,你可以問自己:“就收益和/或減少成本而言,在生產環境中可能發生的最糟糕的事情是什么?”


          例如,電子商務網站的回答可能是如下的特性:


          • “信用卡購物”特性每分鐘可以帶來大約 1000 美元的收入。
          • 如果銷售人員必須要求首席技術官手動將產品添加到數據庫中,則“將產品添加到目錄中”特性每小時的成本約為 500 美元。
          • 如果客戶支持團隊需要手動處理訂單,那么“打印條形碼以退回訂單”將使我們每天損失 500 美元。


          基于這些業務關鍵的用例,從它們開始編寫端到端的自動化測試肯定就是非常有意義的。


          何時運行測試?


          在每次代碼更新或添加到代碼庫之時,在將其部署到生產環境之前。


          借助git hook,在每次提交時運行測試可能就足夠了,因為它能可靠地運行,而且其持續時間不會導致開發人員編寫更少的測試。


          不管是否使用git hook,都要確保每次推送可用于生產環境的代碼時,測試能在某處運行(例如,最好是在持續集成環境中)。



          在持續集成環境中,每次提交都會運行代碼檢查和自動化測試。


          我們應該編寫什么樣的測試?


          需要優化的變量包括:


          • 測試所覆蓋的功能性和技術性范圍的大小。
          • 從測試中獲得反饋的時間。
          • 修復失敗測試所報告的問題所需的時間。
          • 因為誤報而損失的時間(即由于隨機原因導致失敗的測試)。


          如果你的團隊在編寫自動化測試和/或可測試代碼方面經驗不足,那么可以從一些端到端測試開始。然后,逐步增加對范圍更小的代碼單元的測試。這樣做可以激勵開發人員編寫易于測試的代碼。例如,通過隔離責任、減少耦合和/或將業務邏輯寫成純函數。遵循依賴注入架構是實現這一目標的好方法。(參見六邊形架構或簡潔架構)


          我們是否應該 Mock 第三方 API?


          自動化測試(如本文所述)的目的是探測團隊的功能性范圍內的回歸,而不是第三方的功能。基于這一點,在測試中 Mock 第三方是合理的。


          也就是說:


          • Mock 應始終與當前 API 的行為相匹配。這意味著開發人員需要持續關注 API 的變化,并相應的更新它們的 Mock。
          • 當實際 API 的行為與預期不符時,你可能依然希望得到警告。


          探測自己的代碼中的問題和第三方 API 中的問題并不遵循相同的生命周期:


          • 每次代碼進行變更時,所涉及的范圍都應該進行測試。
          • 僅在第三方的代碼發生變更的時候,才應該對其進行測試。(也就是說,每次提交代碼變更都測試第三方依賴是沒有什么意義的)。


          你需要持續監控第三方提供商是否能夠正常運行并達到預期效果。但是,第三方錯誤不一定能夠在發生之時就探測到,因此最好是定期監控,而不是在開發人員每次推送代碼變更的時候進行監控。


          所以,需要搭建兩個專門的流水線:


          • 你自己的 CI 流水線會在你的代碼發生變更的時候測試自己的范圍。
          • 另外一個 CI 流水線定期檢查第三方所涉及的范圍是否按照預期運行。


          為了編寫長期最有用、最健壯的測試,我建議遵循F.I.R.S.T.原則。確保開發人員不會濫用mock。


          細致保護代碼庫中新的/現代化的部分


          假設你的代碼庫已經或者將要開發數年的時間,那么隨著時間的推移,它很可能會在代碼風格和質量方面失去內聚力。更糟糕的是,由于技術債務、缺乏測試或意外復雜性的積累,某些組成部分的維護可能會變得很復雜。


          在這種情況下,要像上文所建議的那樣,在整個代碼庫中對代碼實現一致的內聚預期可能會變得很復雜。不過,這也沒有關系。


          你不希望看到的是期望值降低到一個最低的平均水準。這樣的話,你可以把代碼劃分為不同的范圍,并為每個范圍設置不同的期望水平。


          例如,考慮一個即將為電子商務網站實現新特性的團隊。他們希望這個新特性能夠比代碼庫中的其他特性更健壯、更易于維護。為了實現這一點,他們在配置靜態代碼分析工具(如 ESLint 和 TypeScript)時采用比代碼庫的其他部分更嚴格的規則,并針對專門為該特性而創建的目錄使用覆蓋的方式啟用更多的規則。通過這種方式,團隊可以提高新代碼的質量,而不必急于對代碼庫中“遺留”的部分進行現代化處理。


          "rules": {
              "prettier/prettier": "error",
              "deprecation/deprecation": "warn"
            },
            "overrides": [
              {
                // Tolerate warnings on non critical issues from legacy JavaScript files
                "files": ["*.js"],
                "rules": {
                  "prefer-const": "warn",
                  "no-inner-declarations": ["warn", "functions"],
                  "@typescript-eslint/ban-ts-comment": "warn",
                  "@typescript-eslint/no-var-requires": "off"
                }
              },
              {
                // Enforce stricter rules on domain / business logic
                "files": ["app/domain/**/*.js", "app/domain/**/*.ts"],
                "extends": ["async", "async/node", "async/typescript"],
                "rules": {
                  "prefer-const": "error",
                  "no-async-promise-executor": "error",
                  "no-await-in-loop": "error",
                  "no-promise-executor-return": "error",
                  "max-nested-callbacks": "error",
                  "no-return-await": "error",
                  "prefer-promise-reject-errors": "error",
                  "node/handle-callback-err": "error",
                  "node/no-callback-literal": "error",
                  "node/no-sync": "error",
                  "@typescript-eslint/await-thenable": "error",
                  "@typescript-eslint/no-floating-promises": "error",
                  "@typescript-eslint/no-misused-promises": "error",
                  "@typescript-eslint/promise-function-async": "error"
                }
              }
            ]

          復制代碼


          通過配置覆蓋,我們可以為不同的部分設置不同的 ESLint 規則


          與之類似,如果要對整個代碼庫進行現代化改造,也要循序漸進。你可以創建一個具有更嚴格規則的專用目錄,并逐漸將遺留代碼遷移至該目錄,同時修復代碼的警告和類型錯誤。


          從何處開始?


          有種方式是逐步將功能范圍中陳舊的部分遷移到更好的設計中。例如,選擇一個難以編寫自動化測試的特性,并將它的實現遷移到六邊形架構中,將業務/領域邏輯根據輸入命令(即“API”)和副作用(即“SPI”)分離開來。通過編寫自動化測試來指導遷移,并將新的實現放在具有更嚴格靜態代碼分析規則的專用目錄中。


          import { makeFeatures } = from './domain/features';
          import { userCollection } from './infrastructure/mongodb/UserCollection';
          import { ImageStorage } from './infrastructure/ImageStorage.js';
          
          
          
          
          
          
          
          
          /** @type {import('./domain/api/Features').Features} Features*/
          const features = makeFeatures({
            userRepository: userCollection,
            imageRepository: new ImageStorage(),
          });
          
          
          
          
          
          
          
          
          routes.post('/avatar', (request, response) => {
            features
              .setAvatar(request.session.userId, request.files[0])
              .then(
                () => response.json({ ok: true },
                (error) => response.json({ ok: false })
              );
          });

          復制代碼

          setAvatar特性經過了重新設計,由于采用了依賴反轉,使其易于單獨進行測試。下面是我們遷移另一項特性的過程,即播放列表刪除


          如果你決定遵循這一路徑,如下是一些建議:


          • 如果你的團隊沒有重新設計遺留特性的經驗,那么就從簡單的小特性開始。否則的話,請選擇一個未來幾周或幾個月內要實現的特性最依賴的那個特性。
          • 在編碼之前,明確范圍、業務事件和路徑。例如,與你想重新設計的領域(或限界上下文)所涉及的專家一起組織一次事件風暴。
          • 可視化要遷移范圍的當前架構,例如使用像ARKit、Dependency-Cruiser或類似的依賴分析工具,并寫明不想在目標架構中重復出現的問題,以免重蹈覆轍。
          • 如果有疑問的話,請使用軟件設計工具(如時序圖、狀態機圖、ADR)協作完成恰當的設計。


          在遷移完每個限界上下文之后,你將會得到一個代碼庫,在代碼庫中 100%的代碼都應按照更嚴格的規則進行檢查。


          每日部署,但同樣的錯誤不要犯兩次


          盡管使用了靜態分析工具來檢測缺陷,使用了自動化測試來探測回歸,但用戶還是會在生產環境中發現問題。這是無法避免的。但是,有一種方法可以降低出現此類問題的概率,并縮短團隊修復問題的時間:


          • 每日部署(前提是你確信失敗的風險很低)。
          • 同樣的錯誤不要犯兩次。


          為何要每日部署?


          簡約版答案:因為DORA研究項目發現,大多數執行團隊每天都在進行部署,或者每天部署多次。


          詳盡版答案:

          • 因為這能夠讓開發人員更快地找到在生產環境中出現新缺陷的根本原因。也就是說,部署越頻繁,最新部署和上次部署之間的提交次數就越少。
          • 基于相同的原因,如果最新版本不能按照預期運行,回滾到上一個版本的成本會更低(就回滾代碼提交的次數而言)。
          • 因為這能鼓勵團隊將工作分成更小、更安全的增量。DORA 認為,這也是表現最好的團隊所遵循的做法。


          如何確保相同的錯誤不犯兩次?


          在生產環境中出現意料之外的行為是可以的。在有些情況下,這甚至是一件好事。


          當意料之外的行為給企業和/或開發團隊帶來巨大損失時(例如,網站中斷,導致幾個小時無法使用),開發人員應該采取措施防止類似的事件再次發生。


          如何探測生產環境中的問題?


          有多種方式可以探測生產環境中的問題:


          • 理想情況:開發人員發現問題并立即修復。
          • 常規情況:員工發現問題并向開發團隊報告。
          • 更糟糕的情況:用戶向開發團隊報告問題。
          • 最糟糕的情況:用戶發現了問題,但并沒有報告。


          無論是哪種情況,開發人員都需要以下信息:問題是什么、問題的具體表現(如錯誤信息)、如何重現問題(如環境+過程),以及用戶的初衷和期望是什么。


          但是,如何在最糟糕的情況下獲得這些數據呢?這就是錯誤監控工具(如Sentry)的用武之地了。通過將它們注入到生產環境中運行的產品中,它們就能像探針一樣檢測運行時錯誤,并將它們匯總到已知錯誤的列表中,直到每個錯誤都被開發人員修復為止。此外,它們還會獲取有關錯誤上下文的數據(如用戶代理、所使用軟件的版本、操作系統、確切的時間戳等),以幫助開發人員重現錯誤。


          但令人遺憾的是,與靜態代碼分析器類似,這些工具并不能解決問題。因此,與警告和類型錯誤一樣,要確保盡快處理每個錯誤。團隊讓錯誤累積得越多,使用這些工具的動力和效率就會越低。


          此外,在使用這類監控工具時,請確保個人和/或機密數據不會從系統中泄露出去。


          從戰術上講,有許多方法可供選擇。你可以讓一名開發人員負責修復生產環境的錯誤,并將其作為最優先的事項。這個角色可以定期輪換(比如每天),這樣可以激勵每個人都編寫更健壯的代碼。或者,也可以在每天的會議上將新錯誤單獨分派給志愿開發人員。


          如何降低復發風險?


          不必慌張!當生產環境中發生事故時,都要遵守如下程序:


          1. 保留事故發生前、發生時和發生后的痕跡,以幫助你進行事后分析(注意:在事故發生前做好充分的監控和日志收集工作)。
          2. 在內部和外部就事故進行溝通。
          3. 穩定生產環境,例如,回滾到之前能正常運行的版本。
          4. 編寫并部署修正版本,以修復問題。
          5. 查找并解決導致問題的根本原因,并采取預防措施。


          避免重蹈覆轍的關鍵在于上述程序的最后一步。


          這也是經常被忽視的過程。大多數情況下,是因為沒人覺得自己有責任這樣做。很多時候,是因為產品負責人(或產品團隊)向開發人員施壓,要求他們優先完成開發計劃中的特性,而不是保護現有代碼和/或調整開發流程。有時,開發人員自己也會決定開發更多的特性,而不是避免再次犯錯。



          調查事故根本原因時的注意事項


          如何查找事故的根本原因?


          在這個方面,“5 個為什么(5 WHY)”技巧是很有用的。例如:


          • 生產系統為什么會崩潰?——因為一個未登錄的用戶訪問了頁面 B。
          • 用戶為什么能夠訪問頁面 B?——因為主頁上有一個鏈接。
          • 用戶在訪問頁面 B 的時候為什么沒有看到登錄頁面?——因為在頁面渲染時,后端還不知道登錄狀態。
          • 為什么頁面渲染時還不知道登錄狀態?——因為我們的會話管理后臺很慢,等待這個狀態會大大降低我們的網絡性能指標。
          • 為什么會話管理后端很慢?——因為它使用的是未經優化的遺留數據庫。


          在本例中,根本原因是整個網站都依賴于遺留的會話管理后端,這使得導航難以預測,有時還會導致生產環境崩潰。因此,除非團隊修復傳統的會話管理后端,否則類似的崩潰很可能很快就會在生產環境中再次發生。團隊現在應該修復遺留的會話管理后端嗎?也許不用。但是他們應該努力制定一個能夠實現該目標的補救計劃。


          在實踐中,如何實現低故障率的日常部署呢?


          讓一位開發人員負責確保盡快發現生產中的意外行為(如運行時錯誤、缺陷、事故……),盡快修復,并采取措施防止今后再次發生各類問題。


          通過這種方式,開發人員能夠感受到有能力在良好的條件下開展工作。例如,在生產過程中設置恰當的監控和日志,確保撰寫有用的事后報告,并采取預防措施。


          當信心達到良好水平時,逐步增加部署頻率。


          以正確的激勵機制調整產品開發團隊


          此時,開發人員就具備了編寫高質量軟件,并盡快發現缺陷的能力。這些缺陷最好是在設計或實現時發現,而不是在生產環境中。他們能夠快速發現并修正生產環境的錯誤,不會重復犯同樣的錯誤。他們對自己的代碼和開發流程充滿信心,因此每天都能在生產中實現改善。而且,他們在對軟件功能化范圍進行預期改善的同時,也會逐步改善代碼庫中最古老部分的設計和質量,使其保持健康、穩健并易于長期維護。


          但是,令人遺憾的是,這種平衡很快就可能被瓦解。舉例來說:


          • 如果開發人員失去了長期保持高設計標準和/或代碼質量的動力。
          • 如果部分開發人員不遵循團隊的質量準則,造成系統性返工、挫折和延誤。
          • 如果開發人員誤解了功能性需求,而急于修復無法達到預期效果的特性,從而犧牲了長期的技術責任。
          • 如果有人(如經理、產品負責人或其他人)向開發人員施壓,要求他們每周發布更多的特性,或在緊急的期限內完成任務。
          • 如果激勵和/或獎勵開發人員的績效指標與其代碼庫的長期質量和健壯性不一致。例如,根據每周交付的特性數量確定晉升獎金。


          防止或解決這類情況可能會非常困難,因為這需要良好的領導力和/或軟技能。


          一個常見的錯誤是培養某種思維定式,即開發人員應該主要致力于實現優先的、計劃好的和設計好的特性。


          這樣做是有問題的,因為:


          • 它要求開發人員處于這樣一種狀態,即對軟件做的每一項變更都要有精確和明確的規范。這可能會導致開發人員無法與負責制定這些規范的人員進行健康的雙向合作。對于那些喜歡整天獨自工作的開發人員來說更是如此。
          • 它讓開發人員處于這樣一種境地,即難以衡量那些與功能性路線圖沒有直接貢獻的開發活動,如更新依賴、提高代碼質量、培訓更好的設計和編碼技術。
          • 這很容易讓人傾向于根據指標(如用戶故事的開發速度)來跟蹤開發人員的績效(或“生產力”),而忽略了對可持續開發實踐的投資,即代碼質量、阻礙回歸、錯誤管理等。


          下面是一些關于如何避免上述陷阱的建議:


          • 在詳細闡述業務問題的解決方案時,至少讓一名開發人員參與設計過程。這將提高開發人員的責任心,使他們能夠為一個充分理解的問題實現一個好的解決方案。有時,由于開發人員了解當前的建模和實現方式,他們會提出替代解決方案,從而在滿足需求的同時節省大量的開發時間。
          • 確保產品和技術代表能夠公開、友好地協商功能性和技術性項目的優先級和規劃。例如,如果開發人員需要重新設計代碼庫的某個部分,那么他們就應該說服其他人相信這一點的重要性,解釋這將為下一個特性的開發帶來哪些具體的改善,以及延遲該項目的風險和成本是什么。同樣的建議也適用于產品經理如何對即將開發的功能改善進行優先排序和規劃:通過解釋來說服開發團隊并讓他們參與進來。這樣做可以增強參與設計和實現特性的所有員工的信任、協作和參與度。
          • 在管理方面,確保開發人員不會得到這樣的激勵,即“每周盡可能多地發布特性”。找到使每個開發人員的職業目標與團隊的短期和長期期望相匹配的發展軌道。這樣做的目的是防止出現開發人員理直氣壯地只從事短期改善相關工作的情況。
          • 最后,確保為開發人員提供資源和指導,以不斷提高他們的軟硬技能。為他們提供培訓和/或指導資源。鼓勵他們通過結對和/或群體編程的方式共同完成任務。鼓勵他們與其他/非開發人員角色進行良好的協作,包括領域專家、產品負責人、產品設計師、客戶支持團隊、終端用戶等。


          結論


          JavaScript 語言及其不斷變化的軟件包和實踐組成的生態系統會使代碼庫迅速變得難以維護。正如我們在本文所討論的那樣,無需從頭重寫所有的內容,也無需暫停新特性的開發,就可以避免由此造成的開發速度和/或代碼質量的下降。


          關于如何在 TypeScript 和 JavaScript 項目中應用這些推薦做法的更多實用建議,我建議你參考Yoni Goldberg的最佳實踐列表。它們是為 Node.js(后端)項目編寫的,但其中很多也適用于前端代碼庫。

          原文鏈接:前端老手10年心得,JavaScript/TypeScript項目保養實用指南_架構/框架_InfoQ精選文章

          了在TypeScript中封裝一個獲取當前年前后十年的方法,您可以定義一個函數,接受一個參數表示偏移量(正數表示未來年份,負數表示過去年份),并返回相應年份的數組。以下是一個實現示例:

          function getYearsAroundCurrentDecade(offset: number): number[] {
          const currentYear = new Date().getFullYear();
          const startYear = Math.floor(currentYear / 10) * 10 + offset;
          // Ensure we don't go beyond the year range supported by JavaScript's `Date` object.
          const minYear = 0;
          const maxYear = 9999;
          if (startYear < minYear || startYear > maxYear) {
          throw new Error(`The specified offset ${offset} leads to an out-of-range year.`);
          }
          // Generate an array of years spanning the decade.
          const years = [];
          for (let year = startYear; year < startYear + 10 && year <= maxYear; year++) {
          years.push(year);
          }
          return years;
          }
          // Usage examples:
          console.log(getYearsAroundCurrentDecade(0)); // [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029]
          console.log(getYearsAroundCurrentDecade(-1)); // [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
          console.log(getYearsAroundCurrentDecade(1)); // [2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039]

          這個函數首先獲取當前年份,然后根據偏移量計算出目標十年的起始年份。它確保起始年份在JavaScript `Date`對象支持的合理范圍內(通常是從公元0年到公元9999年),超出范圍時拋出錯誤。接著,函數使用循環生成包含十年內所有年份的數組,并返回該數組。

          通過調用此函數并傳入不同的偏移量值(如`0`表示當前十年,`-1`表示前一個十年,`1`表示下一個十年),您可以輕松獲取所需年份范圍。


          主站蜘蛛池模板: 日本无码一区二区三区白峰美| 日韩美一区二区三区| 亚洲宅男精品一区在线观看| 亚洲欧洲专线一区| а天堂中文最新一区二区三区| 国产精品视频一区二区三区| 无码国产精品一区二区免费3p| 一区二区精品视频| 国产精品久久久久一区二区三区 | 99久久精品国产一区二区成人| 国产成人一区二区三区电影网站 | 国产乱码精品一区二区三区四川| 久久综合精品不卡一区二区| 无人码一区二区三区视频| 国产成人一区二区三区精品久久| 无码一区二区三区免费视频| 麻豆果冻传媒2021精品传媒一区下载| 蜜桃传媒视频麻豆第一区| 亚洲中文字幕无码一区| 日韩电影一区二区| 91在线一区二区| 在线播放一区二区| 亚洲欧美日韩一区二区三区| 亚无码乱人伦一区二区| 天天视频一区二区三区| 国产成人一区二区精品非洲| 无码日韩精品一区二区人妻| 久久婷婷色综合一区二区| 一区二区三区内射美女毛片 | 秋霞日韩一区二区三区在线观看| 伦精品一区二区三区视频| 国精产品一区一区三区有限在线| av一区二区三区人妻少妇| 变态调教一区二区三区| 国产在线观看一区二区三区精品 | 日本精品无码一区二区三区久久久| 国产日韩一区二区三区在线播放 | 夜夜嗨AV一区二区三区| 亚洲一区免费观看| 日本无码一区二区三区白峰美| 日韩免费视频一区|