欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    本文預計閱讀 25 min,建議先收藏后觀看~

    一、刀光劍影的 2022

    時光荏苒,這絕不平淡的 2022 年已經(jīng)走上歷史的黃頁,新的一年也逐漸看不到故人回首的光影。感謝你對前端技術領域持續(xù)關注,我們一直在這里等你。

    ① 2022 年前端人偏愛什么?

    數(shù)據(jù)來源 bestofjs (https://risingstars.js.org/2022/en)

    • 可愛的小包子 Bun 奪得頭籌!Bun 是類似 Node 、Deno 的 JavaScript 運行時。僅一個月內(nèi),就在 GitHub 上獲得了超過兩萬顆 Star。Bun 試圖讓解釋器本身更快。它是用 Zig 編寫的,并且使用 Apple 的 JavaScriptCore,類似于 Node 使用 V8 的方式。Zig 是一種新興的低級語言,出現(xiàn)在 C++ 占主導地位的領域。Bun 雖然現(xiàn)在還不能接入生產(chǎn)(缺乏 Windows 支持),但是無限的潛力讓人不禁感嘆一句未來可期。
    • 如果你要試試跨端技術, Tauri 是個不錯的選擇, 這是一個由 Rust 編寫的項目,利用 Web 技術創(chuàng)建跨平臺的桌面應用程序。在 2021 年的榜單中它還排在第五位,一顆冉冉上升的新星即將被越來越多的開發(fā)者所熟知,期待跨端技術為我們帶來更多的效率提升。
    • React 前端從業(yè)者繞不過去的高峰, 2022 年前端生態(tài)圈的豐富度依舊保持 React > Vue > Angular
    • 10月發(fā)布的 Next.js 13, 利用了 2020 年 React 17 推出的 React Server Components。這是一個非常富有魅力的方案設計,不僅如此 ,你還可以使用比現(xiàn)有打包工具快數(shù)倍的 Turbopack。
    • Vite “快”是它的核心, 它主要解決的核心痛點就是項目啟動緩慢, 作為下一代前端開發(fā)與構建工具,極速的服務啟動將帶來最佳的開發(fā)體驗。

    ② 你也許會有同樣的疑問?

    團隊的新項目要不要試試用 Svelte 來構建但不清楚好用嗎?性能怎么樣?

    RSC(React Server Components)SSR 傻傻分不清楚?

    項目正在用的測試庫(Jest、Cypress)要不要升級到最新版本?

    聽說了 Turborepo 的強大打包實力,但是我當前在哪里可以體驗到,現(xiàn)有項目可以接入嗎?

    老項目想從 Babel 切換到 SWC ,有沒有什么限制?收益大嗎?

    到底用 Tailwind 還是 styled-components ?團隊內(nèi)部已經(jīng)吵起來啦!

    手上有個業(yè)務復雜的大項目,有沒有必要遷移成微前端架構?

    Github Actions 是什么?我們可以跨團隊共建可復用的 CI 節(jié)點嗎?

    ChatGPT 可以幫我寫代碼嗎?什么是 web3.0?跨端方案選什么?

    如何搞點炫酷的Web 3D?聽說 Serverless 是前端開發(fā)的福音?

    等等等等......問題太多啦,什么時候才能全部搞明白?

    ③ 往下看,馬上給你解答

    如果你對上面所敘述問題有同樣疑惑的話,請一定要讀完本文!相信我們的精心制作一定會給你帶來豐富的收獲,一起走入跌宕起伏風云變幻的前端世界吧!

    “天道酬勤,我們與夢想總是雙向奔赴”

    二、Web 框架

    數(shù)據(jù)來源 star-history (https://star-history.com/#sveltejs/svelte&facebook/react&vuejs/vue&lit/lit&solidjs/solid&Date)

    從近年來的數(shù)據(jù)來看,React 和 Vue 是現(xiàn)如今前端入門必學的兩大框架,各大技術論壇上也常常有人為兩者孰優(yōu)孰劣吵得不可開交,從此便可顯現(xiàn)出兩大框架的布道范圍之廣泛,但如果僅僅局限于讓兩個框架一較高下,那格局便小了。Vue 和 React 兩者的差別說大也不算大,它們的主體思想都是數(shù)據(jù)驅(qū)動視圖,直觀表現(xiàn)都是響應式更新,實現(xiàn)載體都是 Virtual DOM(除了 Vue1 )。由于采用了 Virtual DOM ,React 和 Vue 在前端都天生攜帶一個體積不小的“運行時”,它將根據(jù)輸入的數(shù)據(jù)生成 Virtual DOM,并執(zhí)行調(diào)度和渲染流程。

    根據(jù) HTTP Archive 報告 (https://httparchive.org/reports/state-of-the-web#bytesTotal) 顯示,2015 年網(wǎng)頁的中位數(shù)大小為 1280 KB ,到 2022 年已增長到了2000+ KB ,龐大的網(wǎng)頁會占用大量網(wǎng)絡帶寬,使頁面加載時長更長,一些網(wǎng)絡資源不發(fā)達的地區(qū)更能體會到這種影響。為了改善這種趨勢,Svelte 出現(xiàn)了。Svelte 旨在讓開發(fā)者以最少量的代碼,產(chǎn)生最輕量的響應式應用,并且在運行期間產(chǎn)生最小的性能開銷。從原理上講,Svelte 便與 React 和 Vue 兩者有一點不同:它不依托 Virtual DOM 技術來實現(xiàn)響應式更新,取而代之的是直接利用自定義的語法規(guī)則來實現(xiàn)響應式數(shù)據(jù)的分析、綁定以及響應式過程代碼的實現(xiàn),大部分場景下最終編譯生成的產(chǎn)物大小可以做到和原生實現(xiàn)媲美,且性能不遜色于 Vue 和 React。

    Svelte 在 2021 年度 stackoverflow 網(wǎng)站上關于“最受歡迎的 Web 框架” (https://insights.stackoverflow.com/survey/2021#most-loved-dreaded-and-wanted-webframe-love-dread) 調(diào)研中位列第一,在 2022 年度的此項調(diào)研 (https://survey.stackoverflow.co/2022/#most-loved-dreaded-and-wanted-webframe-love-dread) 也位列第二,從好評比例來看使用者們對這個框架很滿意。github stars 的增長速度也說明了 Svelte 是一個在開發(fā)者社區(qū)中十分有發(fā)展?jié)摿Φ?Web 框架,在生態(tài)日趨完善之后,Svelte 很可能是一個比肩 React 和 Vue 的存在。

    下面我們將從各方面來看看這個新星框架與 Vue 和 React 相比都有哪些區(qū)別,從而讓大家對這個框架的潛力和局限性有更多的認識。

    ① 狀態(tài)管理和更新機制

    Svelte 是一個模版編譯器,一個模版文件分為 Script 、CSS 、HTML 三個部分用以描述一個組件:demo (https://codesandbox.io/s/frosty-worker-o66p2f?file=/App.svelte), HTML 部分采用 Mustache 模版引擎的語法動態(tài)地描述 DOM 樹。Script 分為 Module Script 和 Instance Script ,分別用于外部庫的引入組件狀態(tài)的維護。編譯器工作流程大概分為四個步驟:生成 AST 、封裝 Component(收集上下文數(shù)據(jù))、渲染 Component(拼裝代碼)、生成最終代碼(鏈接 runtime 庫)。Svelte 通過 AST 的方式對代碼進行靜態(tài)分析,可以實現(xiàn)數(shù)據(jù)和視圖的綁定,還可以根據(jù)上下文和配置文件,實現(xiàn)剪枝和依賴的按需引入,盡最大的努力優(yōu)化產(chǎn)物大小和性能。Svelte 為了避免不必要的 DOM 操作,為產(chǎn)物實現(xiàn)了一套原理十分簡單的基于 Dirty Mask 以及守衛(wèi)判斷的 DOM 更新機制,實現(xiàn)了細粒度的更新。

    Virtual DOM 類的技術,則是在運行期間實現(xiàn)數(shù)據(jù)和視圖的綁定,當組件遞歸式地執(zhí)行渲染時,組件內(nèi)部的狀態(tài)便被動態(tài)地注冊,當組件更新狀態(tài)時,運行時將調(diào)用用戶定義的渲染函數(shù),重新計算 Virtual DOM ,并利用 DOM Diff 算法來決定哪些 DOM 需要更新,用戶如果想優(yōu)化 Virtual DOM 的計算流程,避免不必要的計算,則需要自行調(diào)用運行時提供的函數(shù)來實現(xiàn)剪枝操作。

    ② SSR渲染

    Svelte 天生自帶了 SSR 渲染的能力,用戶如果有相關需求,便可通過簡單的配置實現(xiàn) SSR 產(chǎn)物的生成;Vue 如果要生成 SSR 產(chǎn)物則需要借助 Nuxt 、Quasar 等專門的呈現(xiàn)框架庫的支持,React 與之對應的庫則是 Next 、Remix 等。

    ③ 跨平臺

    React 、 Vue Svelte 都具有良好的跨平臺能力。由于 Virtual DOM 把渲染過程高度抽象化,Virtual DOM 不單單可以描述瀏覽器的 DOM 結構,還可以適配其他如 Android Layout 等渲染目標,抹平了瀏覽器應用和客戶端應用的差異。

    ④ 產(chǎn)物大小

    Svelte 最大的賣點之一便是其小而精的產(chǎn)物體積。Svelte 由于可以根據(jù)源代碼上下文只編譯出對功能實現(xiàn)有用的代碼,并且對 Runtime 包的依賴做按需引入,另外其 Runtime 包的實現(xiàn)十分原子化和扁平化,編譯器很容易對產(chǎn)物做剪枝處理,在這些機制的共同作用下保證了 Svelte 以最低的空間成本實現(xiàn)最終產(chǎn)物。不過由于需要實現(xiàn)組件的狀態(tài)和生命周期管理等功能,單個組件的源碼-產(chǎn)物大小轉(zhuǎn)換放大倍數(shù)可不小,和 React 這種可以以一個函數(shù)直接描述一個組件的形式相比,Svelte 產(chǎn)物體積隨源碼體積增長的斜率要比 React 大。有人創(chuàng)建了一個項目嘗試以圖表的形式直觀地表現(xiàn)出了這個效應。

    數(shù)據(jù)來源 github (https://github.com/halfnelson/svelte-it-will-scale)

    將兩條體積增長線放一起可以直觀地看出,當源碼大概達到120 KB 規(guī)模時, Svelte 相較于 React 將不存在產(chǎn)物體積優(yōu)勢。 不過這種規(guī)模的項目在現(xiàn)實世界中很難達到,對于使用者來說,完全可以認為 Svelte 是一個輕量級的框架。

    ⑤ 性能

    Svelte 的響應式更新機制較為簡單,它會使用狀態(tài)更新的 update 函數(shù),這個函數(shù)內(nèi)部只做了兩件事:比較并更新 component 上下文信息、標記臟數(shù)據(jù)掩碼(make_dirty) 。Svelte 的這套響應式更新機制遠沒有 React 和 Vue 的調(diào)度更新復雜,實現(xiàn)的更新粒度也十分細,不過在某些場景下這種機制存在弊端。

    由于是基于靜態(tài)代碼分析, Svelte 難以從視圖中收集到十分詳細的訂閱信息,這導致了 Svelte 對于對象引用的賦值操作可能會存在無用更新

    在這個 demo (https://codesandbox.io/s/lingering-resonance-rjz5gh?file=/App.svelte) 中,雖然對于 person 狀態(tài)視圖中只訂閱了其 name 引用,但是對于另一個引用 age 的修改操作,仍然會觸發(fā)更新操作的執(zhí)行。

    這種情況在 Vue 的實現(xiàn)中并不會發(fā)生,Vue 狀態(tài)的依賴是在運行時收集,因此可以實現(xiàn)在狀態(tài)修改時更精準地判斷視圖是否需要執(zhí)行更新操作,從這個 demo (https://codesandbox.io/s/musing-dhawan-k8n2wn?file=/src/App.vue) 中我們可以得到驗證。

    Svelte 的性能表現(xiàn)和 Vue 、React 等框架相比究竟如何,我們可以通過一個項目來有更直觀的認知(https://github.com/krausest/js-framework-benchmark)

    這個項目對大量的前端框架實現(xiàn)了表格數(shù)據(jù)的增加、刪除、換位等操作,并通過無頭瀏覽器測試各種操作的性能,我們可以通過跑分結果大概了解各種框架數(shù)據(jù)更新操作的性能,這里篩選了原生、Vue 、Svelte 、React 的結果。

    從結果來看,Svelte 的性能與 Vue 不相上下,它們都比較接近原生實現(xiàn)的性能,并且大部分操作性能都優(yōu)于 React 。不過,實際上在很多情況下,一個系統(tǒng)整體的性能并不取決于選擇的框架,而是取決于開發(fā)者功能實現(xiàn)是否合理,Svelte 在很大程度上已經(jīng)幫助其使用者完成一部分優(yōu)化工作,這可以說是它的魅力所在。

    三、呈現(xiàn)框架(Rendering Frameworks)

    作為一名優(yōu)秀的前端工程師,當你做好了技術選型并確定了某個 Web 框架準備施展拳腳時,會發(fā)現(xiàn)要從頭構建一個完整的 Web 應用程序還需要考慮許多重要的細節(jié)。

    • 使用打包構建工具(例如 Webpack、Rollup)打包代碼。配置 css 預處理器、并使用 Babel 等編譯器進行代碼轉(zhuǎn)換
    • 應用的路由設計
    • 針對生產(chǎn)環(huán)境進行優(yōu)化,例如代碼拆分
    • 提高頁面性能和 SEO,考慮服務端渲染 (SSR)

    Web 框架如 React、Vue 為開發(fā)者提供了官方的腳手架,讓我們無需深入學習配置構建工具的情況下就可以快速創(chuàng)建一個 Web 應用,使我們專注于編碼,不用操心構建工具。

    通過腳手架創(chuàng)建的項目可以解決部分工程化的問題,然而腳手架不是萬能的。當我們想搭建一個 SSR Web 站點就需要用到更高階的框架能力、更高級的構建配置、更復雜的項目部署。

    呈現(xiàn)框架為開發(fā)者提供了更多便利,下圖是近年來相關框架的使用度排名:

    數(shù)據(jù)來源 stateofjs

    (https://2022.stateofjs.com/zh-Hans/libraries/rendering-frameworks/)

    ① Next.js

    Next.js 是一個靈活的 React 框架。 它每周有超過 300 多萬次 npm 下載和 9 萬多個 GitHub Star,足以說明了它是構建 Web 最流行的框架之一。2022 年10月 發(fā)布了 Next.js 13 ,帶來了一個全新的版本:

    • 引入了全新的構建工具
    • 改進路由和布局體驗:更簡單、更快、更少的客戶端 JS

    Webpack 已被下載超過 30 億次,它已然成為構建 Web 不可或缺的一部分。然而它也已經(jīng)達到了使用基于 JavaScript 的工具可能達到的最大性能的極限。 所以 Next.js 另辟蹊徑,選擇了 Turbopack,它的架構吸取了 Turborepo 和 Google 的 Bazel 等工具的經(jīng)驗教訓,這兩個工具都專注于使用緩存來避免重復執(zhí)行相同的工作

    • 函數(shù)級緩存: 通過緩存函數(shù)調(diào)用的結果而不是重做以前完成的工作將節(jié)省大量時間。
    • 按需編譯: 如果瀏覽器請求 HTML,將只編譯 HTML——而不是 HTML 引用的任何內(nèi)容。

    Next.js 13 也引入了一個新的基于文件系統(tǒng)的路由器,該路由器構建在 React Server Components 之上,支持布局、嵌套路由、加載狀態(tài)、錯誤處理等。

    React Server Components

    RSC 出現(xiàn)的背景

    主要原因是因為大量的 React 組件依賴數(shù)據(jù)請求之后才能做渲染。如果是這樣,那么每個組件自己去請求數(shù)據(jù)的話會出現(xiàn)子組件要等父組件數(shù)據(jù)請求完成,到渲染子組件的時候才會開始去請求子組件的數(shù)據(jù),也就是官方所謂的 WaterFall 數(shù)據(jù)請求隊列的問題。而將數(shù)據(jù)請求放在一起又非常不便于維護,出現(xiàn)了一個兩難的問題。

    RSC 是如何解決組件依賴數(shù)據(jù)渲染的問題?

    既然組件是依賴數(shù)據(jù)做渲染的,那為什么接口不直接返回渲染后的組件呢?所以他們提出了 Server Components 的解決方案。方案的大體是將 React 組件拆分成 Server 組件(.server.tsx)和 Client 組件(.client.tsx)兩種類型。 其中 Server 組件會在服務端直接渲染并返回。

    與SSR的區(qū)別是什么?

    • SSR 是在服務端拼接好 HTML,返回給客戶端;而 RSC 是在客戶端渲染的,服務端輸出的是 chunks
    • SSR 的請求響應是 HTML,是無狀態(tài)的;而 RSC 在渲染的時候,不影響 Client Components 的狀態(tài)

    SSR 和 RSC 可以結合使用,SSR 目前大部分被用在首屏加載的場景,之后的頁面交互可以選擇用 RSC

    RSC 有哪些優(yōu)勢?

    • 在服務端獲取數(shù)據(jù)通常更緊密,比在瀏覽器中請求速度更快
    • Zero-Bundle-Size:RSC 不會打包到端的 bundle 中,依賴的 npm 包也不會,減少了發(fā)送到 客戶端 JavaScript 數(shù)量
    • 使用大型庫時 RSC 開銷更小,舉例:項目中使用 Markdown 轉(zhuǎn)換 HTML 的 npm 包,在服務端不需要反復下載安裝,而在瀏覽器中的每次請求都需要獲取。

    大家可以通過 React 官方的演講和實例 (https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html) 來了解 RSC 的更多內(nèi)容。React Server Components 仍在研發(fā)中, 如果自己在項目使用 RSC 的成本還是很大的,所以推薦在 Next.js 中使用 RSC ,這樣會輕松很多。

    同時,如果使用 Next.js 中的 RSC 和 嵌套布局 (https://beta.nextjs.org/docs/routing/pages-and-layouts) 可以立即呈現(xiàn)頁面中不需要特定數(shù)據(jù)的部分,并顯示正在獲取數(shù)據(jù)的頁面部分的加載狀態(tài) (https://beta.nextjs.org/docs/routing/loading-ui) 使用這種方法,用戶不必等待整個頁面加載完畢就可以開始與之交互。

    也可以與 React Suspense (https://beta.reactjs.org/apis/react/Suspense) 結合使用,可以獲得以下優(yōu)勢:

    • Streaming Server Rendering - 從服務器到客戶端逐步渲染 HTML。
    • Selective Hydration - React 根據(jù)用戶交互優(yōu)先考慮哪些組件首先進行交互。

    ② Nuxt.js

    Nuxt.js (https://nuxt.com/) 是一個構建于 Vue 生態(tài)系統(tǒng)之上的呈現(xiàn)框架,它為編寫 Vue SSR 應用提供了絲滑的開發(fā)體驗。

    2022年11月,官方發(fā)布了 Nuxt 3.0 穩(wěn)定版,Nuxt 3 是基于Vite (https://vitejs.dev/) Vue3 (https://vuejs.org/) 和 Nitro (https://nitro.unjs.io/) 的重寫版本,具有一流的 Typescript 支持。

    開發(fā)者可以基于它初始化新項目的基礎結構代碼,或者在已有 Node.js 項目中使用 Nuxt.js。

    ③ 對比

    Next.js、Nuxt.js 這兩個框架的重心都在 Web 部分,對 UI 呈現(xiàn)部分的代碼組織方式、服務器端渲染功能等提供了完善的支持,讓開發(fā)者開箱即用。

    • 在路由結構設計上,兩者都采用了文件結構即路由的設計方式。
      • 默認以 pages 文件夾為入口,生成對應的路由結構,文件夾內(nèi)的所有文件都會被當做路由入口文件,支持多層級,會根據(jù)層級生成路由地址。
    • 兩者都支持動態(tài)路由訪問,命名規(guī)則不同:
      • Next.js 中括號命名 /pages/foo/[id].js -> /pages/foo/123
      • Nuxt.js 下劃線命名 /pages/foo/_id.js -> /pages/foo/123
    • 兩者都內(nèi)建提供了 link 類型組件(LinkNuxtLink)當路由跳轉(zhuǎn)時,組件會檢測鏈接是否命中路由,命中組件出現(xiàn)后會觸發(fā)對應路由的 js 資源的加載。(前端路由跳轉(zhuǎn),不會重新加載頁面)
    • 兩者都提供了數(shù)據(jù)預取的方法
      • asyncData:組件可導出 asyncData 方法,返回值會和頁面路由組件的 data 合并,用于后續(xù)渲染,只在頁面路由組件可用。
      • fetch:在 2.12.x 中增加,利用了 Vue SSR 的 serverPrefetch,在每個組件都可用,且會在服務器端和客戶端同時被調(diào)用。
      • 渲染過程的最后,頁面數(shù)據(jù)與頁面信息寫在 window.NUXT 中,同樣會在客戶端被讀取。
      • 渲染過程的最后,會生成頁面數(shù)據(jù)與頁面構建信息,這些內(nèi)容會寫在 <script id="__NEXT_DATA__"/> 中渲染到客戶端,并被在客戶端讀取
      • Next.js 可以在頁面路由文件中導出 getServerSideProps 方法,會使用此函數(shù)返回的值來渲染頁面,返回值會作為 props 傳給頁面路由組件;
      • Nuxt.js 數(shù)據(jù)預取方法有兩個,分別是 asyncData、fetch
    • 兩者都支持靜態(tài)頁面生成 SSG,生成靜態(tài)的 HTML 文件對于訪問速度提升和做 CDN 優(yōu)化很有幫助

    沒有最好的框架,只有最合適的框架。 本質(zhì)上 Next.js 是一個 React 框架,另一方面 Nuxt.js 是一個 Vue 框架,兩者的目標都是來簡化開發(fā)成本和提高開發(fā)體驗的。

    四、測試工具

    數(shù)據(jù)來源 bestofjs(https://risingstars.js.org/2022/en#section-test-framework)

    Jest 和 Cypress 都是使用 Javascript 進行編寫測試用例的老牌工具,也都有完整的文檔和生態(tài)對各種測試情景進行支持,對于前端同學來說學習成本較低。同時,這兩個工具也都支持 CI/CD 集成,在提交代碼合并請求的時候可以自動運行測試用例,簡化回歸測試流程。

    相較于2022年,Cypress 和 Jest 新增 Star 數(shù)較 2021年都有所下降,尤其是 Jest,從21年的第5名下降到了第7名。而微軟團隊開發(fā)維護的 Playwright 的新增 Star 數(shù)連續(xù)三年遙遙領先,總 Star 數(shù)也在22年首次超過了 Jest 和 Cypress,達到了46.3k。其優(yōu)勢在于多瀏覽器和多語言的支持。不過因為 Playwright 相較于其他測試框架還比較新,生態(tài)支持還不如其他的老牌測試框架。

    當然測試是確保程序正確運行的保障,不是為了單純提高測試覆蓋率而寫的,畢竟寫測試也是要占用開發(fā)人力的。至于在工作當中如何設計實用的測試用例,把握好測試覆蓋的粒度,就是一門更加深入的學問了。

    ① 單元測試:Jest

    Jest 是基于 React 的應用程序的首選測試框架。 由 Meta 定期維護。除了 React,它還支持 Angular,VueJS,NodeJS 和其他基于 Babel 的項目。

    在 2022 年4月發(fā)布的 Jest 28中,增加了 --shard 命令條選項,可以把測試分片,并在不同的機器上運行。在測試條目很多的情況下,大大降低了跑測試所需要的時間。與此同時,這次更新還解決了 Jest 最大的一個兼容性問題,完全支持了 package.json exports 。這次更新還完成了對 Node.js globals 的支持,以后就不需要手動復制全局變量到測試中了。

    ② E2E測試:Cypress

    Cypress 是一個使用 Javascript 編寫,可在瀏覽器或 CI / CD 集成中進行運行的工具。 有豐富靈活的 API 和插件對各種場景的測試用例進行支持。Cypress 在進行 E2E 測試時,會打開 Chrome 瀏覽器,然后根據(jù)測試代碼對頁面進行操作,就像一個正常的用戶在操作頁面一樣。

    Cypress 12 于 2022 年 12 月發(fā)布,其中最重量級的新功能就是對跨源的支持。 現(xiàn)如今,大部分網(wǎng)頁都是用第三方授權系統(tǒng)的方式進行登錄驗證。之前,Cypress 只能對使用程序化授權驗證的方式進行登錄測試,卻不能完全模擬用戶使用時的操作。現(xiàn)在,我們可以通過 cy.session() 存儲用戶授權后的 session 信息 (如 cookies,storage 等),并在之后的測試中隨時調(diào)取。這也降低了測試用例運行的時間,因為不需要每個測試單獨運行一次授權登錄流程。

    五、打包工具

    數(shù)據(jù)來源 npmtrends

    (https://npmtrends.com/esbuild-vs-grunt-vs-gulp-vs-parcel-vs-rollup-vs-turbo-vs-vite-vs-webpack)

    從上圖可以看出,目前前端世界主流的前 3 名模塊打包器仍然是 Webpack Rollup Esbuild

    ① Webpack

    本質(zhì)上,Webpack 是一個用于現(xiàn)代 JavaScript 應用程序的靜態(tài)模塊打包工具。當 Webpack 處理應用程序時,它會在內(nèi)部從一個或多個入口點構建一個 依賴圖(dependency graph) ,然后將你項目中所需的每一個模塊組合成一個或多個 bundles,它們均為靜態(tài)資源,用于展示你的內(nèi)容。

    ② Esbuild

    Esbuild 是一個用 Go 編寫的模塊打包工具。因為它大量利用了 Go 中并行的特性,所以 Esbuild 非常快。

    • Esbuild 內(nèi)部的算法經(jīng)過精心設計,在可能的情況下它將飽和使用所有可用的 CPU 內(nèi)核
    • Esbuild 中的所有功能在開始編寫時就充分考慮了性能

    ③ Rollup

    Rollup 是一個 JavaScript 模塊打包工具,可以將多個小的代碼片段編譯為完整的庫和應用。與傳統(tǒng)的 CommonJS 和 AMD 這一類非標準化的解決方案不同,Rollup 使用的是 ES6 版本 Javascript 中的模塊標準。

    • 與 Webpack 相比快速且輕量級
    • 支持 Tree Shaking

    ④ Parcel

    Parcel 是一個眾所周知的零配置 Web 應用程序打包器。

    • 默認啟用 Tree Shaking
    • 使用 Rust 編寫的 Javascript 編譯器,以利用并行性并提高性能
    • 支持原生 ES Moduls 和 CommonJS 兩種模塊標準
    • 自動代碼拆分

    ⑤ Turbopack

    Turbopack 建立在 Turbo 之上:Turbo 是一種用于 Rust 的開源增量記憶框架。 Turbo 可以緩存程序中任何函數(shù)的結果。當程序被執(zhí)行多次時,函數(shù)不會重新運行,除非它們的輸入發(fā)生變化。

    這種方法使 Turbopack 在計算增量更新方面非常快。這也優(yōu)化了 Turbopack 使得開發(fā)過程中增量更新非常快,確保 dev server 能夠快速響應代碼變更。

    Turbopack 還使用請求級編譯方法來只編譯請求的代碼。如果瀏覽器請求某些 CSS,則只會編譯該 CSS,而不編譯引用的 images。采用請求級編譯有助于減少請求數(shù)量并能夠快速編譯它們。

    目前,Turbopack 比現(xiàn)有打包工具快 10 倍~700 倍。但它目前只可以在 Next.js v13 中使用。未來計劃發(fā)布獨立的 CLI、插件 API,并支持 Svelte 和 Vue 等其他框架。

    ⑥ Nobundle:Vitejs

    Vite 通過在一開始將應用中的模塊區(qū)分為依賴源碼兩類,改進了開發(fā)服務的啟動時間。

    • 依賴大多為在開發(fā)時不會變動的純 JavaScript。一些較大的依賴(例如有上百個模塊的組件庫)處理的代價也很高。依賴也通常會存在多種模塊化格式(例如 ESM 或者 CommonJS)。Vite 將會使用 esbuild (https://esbuild.github.io/) 預構建依賴(https://cn.vitejs.dev/guide/dep-pre-bundling.html)
    • 源碼通常包含一些并非直接是 JavaScript 的文件,需要轉(zhuǎn)換(例如 JSX,CSS 或者 Vue/Svelte 組件),時常會被編輯。同時并不是所有的源碼都需要同時被加載(例如基于路由拆分的代碼模塊)。Vite 以 原生 ESM (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) 方式提供源碼。這實際上是讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請求源碼時進行轉(zhuǎn)換并按需提供源碼。根據(jù)情景動態(tài)導入代碼,即只在當前屏幕上實際使用時才會被處理。

    對于生產(chǎn)環(huán)境,Vitejs 使用 Rollup 進行打包。

    六、編譯工具

    編譯工具(Compiler)可以理解為將一種語言編寫的源代碼轉(zhuǎn)換為另一種語言的過程。在前端開發(fā)過程中,我們經(jīng)常遇到如下兩類編譯場景:

    1. 將 TS 轉(zhuǎn)換為 JS;
    2. 將新版本 JS 語法轉(zhuǎn)換為低版本瀏覽器支持的語法;

    盤點當前前端界的編譯工具,如下四個占據(jù)了大部分市場:

    名稱描述Star底層語言Babel (https://babeljs.io/)JS 編譯器,用于將新版本 JS 語法轉(zhuǎn)換為向后兼容的 JS 語法。也可以通過插件(https://babeljs.io/docs/en/babel-plugin-transform-typescript)支持 TS 語法編譯,但不支持類型檢查。41.8KJSTSC (https://www.typescriptlang.org/)TS 官方編譯器,用于將 TS 編譯成 JS。同時也支持舊版本語法轉(zhuǎn)換,但不能自動 polyfill。87.5KTSSWC (https://swc.rs/)新一代 JS 編譯器,特點是速度非常快,宣稱單核下比 Bable 快 20 倍。支持 TS 編譯,但不會做類型檢查。25.5KRustesbuild (https://esbuild.github.io/)一款超級快且融合編譯&打包的工具,宣稱比現(xiàn)在生態(tài)(說的就是你:webpack + babel)快10-100倍。支持 JS/TS,編譯 TS 不會做類型檢查。34.3KGo

    可以看出,由于 SWC 和 esbuild 的出現(xiàn),編譯工具生態(tài)正在進行巨大的轉(zhuǎn)變過程中,底層引入 Rust、Go 等更高效的語言,讓編譯速度有了幾十倍乃至上百倍的提升。SWC 和 esbuild 雖然能高效的編譯 TS,但是都不支持類型檢查,TS 項目中還需要配置 TSC 來進行額外的類型檢查支持,不過 SWC 已經(jīng)有計劃做些事情了。

    從下面 Github 的點贊量趨勢圖中可以看出,新一代的編譯工具正在猛追老牌工具,esbuild 和 SWC 在 2020 年之后都獲得了大量的關注。

    數(shù)據(jù)來源 star-history (http://star-history.com)

    不過,關注歸關注,從使用量來看,卻是另一番景色,根據(jù) NPM 包下載量趨勢分析來看:

    • Babel 和 TSC 依然占據(jù)統(tǒng)治地位;
    • esbuild 逐漸獲得了更多的使用,猜測和 2022 年 Vite 的大火有一定關系,Vite 的內(nèi)置編譯工具即為 esbuild;
    • SWC 還是不慍不火,不過最新的 Next.js 的官方內(nèi)置編譯工具已經(jīng)替換成了 SWC,且背靠 Vercel 這顆大樹,相信 SWC 未來會有更好的發(fā)展;

    數(shù)據(jù)來源 npmtrends (https://npmtrends.com/)

    如果你準備開發(fā)新項目或者升級工程框架,不妨嘗試一下 esbuild 和 SWC,畢竟,誰不想要更快一些呢!

    ① Babel

    最早開始出現(xiàn) JS 編譯工具之一,也是目前使用最多的 JS 編譯工具。隨著 Babel 的出現(xiàn),前端開發(fā)者可以直接編寫現(xiàn)代 JS 代碼,同時又不失去對舊瀏覽器的支持。

    簡單來說,Babel 是一個工具鏈,主要用于將 ECMAScript 2015+ 版本的代碼轉(zhuǎn)換為向后兼容的 JavaScript 語法,以便能夠運行在當前和舊版本的瀏覽器或其他環(huán)境中。Babel 可以做如下事情:

    • 語法轉(zhuǎn)換,比如 constlet?. 、箭頭函數(shù)等
    • 最新 ES API 和 ES 實例/靜態(tài)方法的 Polyfill,如 PromiseArray.prototype.includes 等。這部分主要通過第三方庫來 polyfill,如 core-js (https://github.com/zloirock/core-js)
    • 源碼轉(zhuǎn)換(codemods)

    Babel 官方提供一個 在線編譯網(wǎng)站(https://babeljs.io/repl),大家可以使用它便捷的體驗 Babel 的編譯效果。

    Babel 構建在插件之上,默認情況下,Babel 不做任何處理,需要借助插件來完成語法的解析、轉(zhuǎn)換、輸出。

    ② TSC

    TSC(TypeScript Compiler) 是 TS 語言官方的編譯器,最初 TS 語言只能使用 TSC 進行編譯,隨著 Babel 等工具也相繼支持編譯 TS,你可能有疑問,他們之間有什么區(qū)別嗎?答案是有的, 相對于 Babel,TSC 有如下 優(yōu)勢

    • 可以進行類型檢查;
    • 可以識別所有的類型并生成 .d.ts 類型文件;

    原因在于 Babel 是單個文件編譯的,不會解析其他文件的信息,而 TSC 的類型檢查需要拿到整個工程的類型信息,需要做類型的引入、多文件 namespace 的合并等。而 Babel 編譯 TS 只是去掉類型聲明,保留原有 JS 功能。

    通過配置 target 也可以讓 TSC 編譯出低版本瀏覽器支持的代碼,但存在一些 缺點:

    • 對一些新語法缺乏支持,如提案階段的語法;
    • 對于 ES API 和 ES 實例/靜態(tài)方法無法解析,需要單獨添加 polyfill

    綜上,現(xiàn)在的前端 TS 項目一般還是會使用 Babel 做編譯,使用 TSC 做類型檢查。

    Babel for transpiling, TSC for types :

    (https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html#handbook-content)

    ③ SWC

    一款基于 Rust 語言開發(fā)的編譯工具,它相對于 Babel 的優(yōu)勢就是編譯速度非常快,在它的官網(wǎng)上,寫著如下一句話。

    SWC is 20x faster than Babel on a single thread and 70x faster on four cores.

    SWC 的成功得益于 Rust 語言,這是一門高效、性能更好且內(nèi)存安全的語言。隨著 SWC 的崛起,很快它就被 Next.js 采用,進而取代 Babel 作為 JS 編譯工具。

    優(yōu)缺點:

    SWC 最大的優(yōu)勢就是編譯速度快,另外在可擴展性、WASM 支持、社區(qū)和生態(tài)系統(tǒng)方面也是做的非常不錯的。

    但是,如果從 Babel 切換到 SWC,也有一些問題需要考量:

    • 相對于 Babel SWC 的編譯支持上有一些區(qū)別,參考 官方列表 (https://swc.rs/docs/migrating-from-babel) 可能會導致代碼的瀏覽器支持度降低
    • SWC 也有插件系統(tǒng),但仍是實驗性的,且開發(fā)插件要學習 Rust 和 WebAssembly,上手門檻明顯很高

    SWC 并不滿足只是一個編譯工具,未來或?qū)⒅С秩缦履芰?/span>

    • 編譯工具,替代 Babel
    • 打包器,替代 Webpack,目前正在建設中:swcpack (https://swc.rs/docs/usage/bundling)
    • 類型檢查器,替代 TSC
    • 壓縮器,替代 Terser

    ④ esbuild

    esbuild 更多是作為打包工具被大眾熟知,我們在打包工具章節(jié)也做了介紹。

    其實 esbuild 也是支持編譯能力的,且速度要比 Babel 快很多,但是它不兼容低版本瀏覽器,產(chǎn)物無法降級到 ES6 以下。esbuild 也原生支持編譯 TS 語言,同樣不支持類型檢查,遺憾的是官方也沒有計劃去做這件事。

    七、樣式工具

    數(shù)據(jù)來源 star-history (https://star-history.com/#sass/sass&postcss/postcss&tailwindcss/tailwindcss&styled-components/styled-components&webpack-contrib/css-loader&Date)

    如何更優(yōu)雅、更舒適的書寫樣式是前端領域永遠繞不開的話題,為了解決原生 CSS 存在的一些問題,社區(qū)中出現(xiàn)了各式各樣的樣式工具。有覆蓋范圍比較小,但是解決了最關鍵問題的 CSS module;也有以 Sass 為代表的,中規(guī)中矩的 CSS 預處理器;還有通過插件化形式,具備非常強大的可拓展性的 PostCSS;以及劍走偏鋒的 tailwind 和 styled-components。他們各有自己的優(yōu)勢劣勢,也不存在一個最好的工具,作為前端工程師,只能根據(jù)具體場景,選擇最適合的工具。

    ① 原生 CSS

    從前,車馬很慢,書信很遠,樣式開發(fā)也很簡單。我們只需要將樣式放在 CSS 文件中,并直接引入即可。然而簡單也是需要代價的:

    1. 缺少局部作用域:所有組件使用的所有 CSS 代碼,都會全局生效。
    2. 不支持條件邏輯:比如,我們無法非常方便的實現(xiàn)“第一個元素是紅色,其余元素為綠色”,而是需要使用較復雜的偽類選擇器。這也是 CSS 被人詬病“不是一種編程語言”的原因之一。

    ② CSS module

    CSS Modules 是這樣一種效果:CSS 文件中的所有類名都默認具有局部作用域。即使是一個普通的 CSS 文件,只要開發(fā)者通過某種方式實現(xiàn)了這種效果。也可以稱之為“使用了 CSS module”。

    顯著的不同是:CSS 文件居然導出了一個變量(style)。并且,html標簽上的類名,并不是普通的字符串,而是從style變量導出的同名屬性。

    最主流、應用最廣也是最早產(chǎn)生的實現(xiàn)方式,就是通過構建工具來實現(xiàn)。比如 webpack 生態(tài)下的 css-loader。這些工具會為 CSS 文件中的每個類名,生成一個哈希值。并在打包產(chǎn)物中,將哈希值作為類名使用。并且打包工具會保證 ,即使是不同的 CSS 文件中,存在同名的類,生成的哈希值也是不同的。從而保證了局部作用域。

    ③ CSS 預處理器

    CSS 預處理器可以說是眾多樣式工具中比較主流的一類,有很多廣受歡迎的工具:Less、Sass 以及 Stylus。

    CSS 預處理器是一種獨有的語法來生成 CSS 代碼的程序。也就是說,每種 CSS 預處理器,都會引入一種新的語言,開發(fā)者需要使用這種新的語言來編寫源碼。而預處理器會負責將源碼編譯成 CSS 代碼。并且,雖然說會引入一種新的語言,但為了方便開發(fā)者使用,這種新的語言一般不會和 CSS 相差太多,基本上是 CSS 的一個超集。 從這個意義上來說,CSS 預處理器其實和 Typescript 有些相似之處。

    這些超集內(nèi)容提供了很多的語法,比如支持定義變量和嵌套寫法等, 為我們的開發(fā)帶來了很大的助力。

    ④ PostCSS

    PostCSS 的名稱可能會讓人誤解,認為這個工具是進行 CSS 后處理(對用戶編寫的標準 CSS 代碼進行處理)的。從而與一些 CSS 預處理工具(比如上面提到的 Sass)區(qū)分開。實際上,PostCSS 依靠其簡單的核心功能以及豐富的插件體系,能夠同時完成 CSS 后處理,以及 CSS 預處理的工作

    PostCSS 的插件體系是極其豐富的,對于常見的需求,我們都能找到對應的插件。比如 Autoprefixer 是一個十分常用的 PostCSS 插件。它能夠在輸出的 CSS 中,對于兼容性有問題的 CSS 規(guī)則,自動加上不同瀏覽器的前綴。免去了開發(fā)人員手動為每一個規(guī)則加上不同前綴的繁瑣而無趣的工作。

    ⑤ Tailwind

    Tailwind和上面提到的工具,采取了完全不同的思路。因此也有了完全不同的架構。具體來說,tailwind 的思路是:它提供非常多的原子化 CSS 。用戶可以通過組合這些類來實現(xiàn)想要的樣式。

    總的來說 tailwind 的優(yōu)點和缺點都十分突出。其缺點顯而易見:大多數(shù)人都不熟悉這種方式,并且學習起來比較困難。要想熟練地使用 tailwind,需要對其提供的大多數(shù)常用的類都比較熟悉,看到某個組件的設計圖,就能大概知道需要使用哪些原子化 CSS 類。而在達到這個程度之前,使用 tailwind 編寫樣式是一個比較痛苦的過程(寫兩行代碼需要看十次文檔)。

    而優(yōu)點可能不太容易察覺:

    1.在大多數(shù)情況下,幾乎不用自己編寫一行 CSS 代碼

    如果開發(fā)者能夠?qū)?tailwind 比較熟悉,就能夠使用它提供的原子化 CSS 類完成全部樣式。

    當我們需要對第三方組件庫(比如 antD)的類添加一些樣式時,我們就必須自己編寫 CSS 代碼了

    2.極大的提高開發(fā)效率

    之前需要編寫多行 CSS 規(guī)則,現(xiàn)在只需要組合幾個原子化 CSS 類

    3.幾乎不需要考慮原子化 CSS 類之間的沖突

    原子化這個稱呼就表明了,每個類只完成一個孤立的功能。所以不同類的 CSS 規(guī)則之間,不會有覆蓋或重疊

    4.以一種非常獨特的方式,解決了全局作用域問題

    如果我們完全使用 tailwind 來編程,我們會發(fā)現(xiàn),我們幾乎不需要定義 CSS 類。如此,既然不存在自定義的CSS 類,就根本不會存在 CSS 類污染了全局作用域的問題。

    但也有例外,比如上文提到的“為第三方組件庫的類添加一些樣式”時,還是會產(chǎn)生 CSS 類名,從而產(chǎn)生了污染全局作用域的風險

    ⑥ Styled-components

    Jeff Atwood 在2007年提出 Atwood 定律:任何能夠用 JavaScript 實現(xiàn)的應用系統(tǒng),最終都必將用 JavaScript 實現(xiàn)。大家或許能想到 JS 在服務器、客戶端領域的大放異彩。但大家想不到的是,JS 竟然也想要將樣式也納入統(tǒng)治范圍之內(nèi)。而這個趨勢的產(chǎn)物,就是 styled-components。

    使用者完全不需要引入 CSS 文件或者類 CSS 文件,也完全不需要定義和使用CSS類名。而是需要將樣式代碼,放在一個個樣式組件中。而樣式組件如何定義呢?需要使用暴露出來的styled api,并且將樣式代碼放在模板字符串中。

    值得一提的是 antd v5 開始使用了 css in js 方案,不過部分開發(fā)者認為 styled-components 這種“依賴模板字符串構建樣式組件”的方式并沒有給他們帶來多大收益,但是它讓樣式組件, 以及樣式組件和邏輯組件分離的概念普及給了更多人,這本身就是一件很好的事情。

    八、微前端方案

    微前端是一種類似于微服務的架構,是一種由獨立交付的多個前端應用組成整體的架構風格,將前端應用分解成一些更小、更簡單的能夠獨立開發(fā)、測試、部署的應用,而在用戶看來仍然是內(nèi)聚的單個產(chǎn)品。

    通俗來說,就是在一個 web 應用中可以獨立地運行另一個 web 應用,這樣的使用場景其實不少:

    • 比如制作一個統(tǒng)一運營平臺,把已有的評論系統(tǒng)和申訴系統(tǒng)等一眾運營平臺統(tǒng)一接入到這個平臺;
    • 比如有一個巨大的應用,為了降低開發(fā)和維護成本,分拆成多個小應用進行開發(fā)和部署,然后用一個平臺將這些小應用集成起來;
    • 又比如一個應用使用 vue 框架開發(fā),其中有一個比較獨立的模塊,開發(fā)者想嘗試使用 react 框架來開發(fā),等模塊單獨開發(fā)部署完,再把這個模塊應用接回去

    一個完整的微前端框架應該具備哪些能力呢?

    • 子應用的加載和卸載能力

    頁面需要從一個子應用切換到另一個子應用,框架必須具備加載、渲染、切換的能力

    • 子應用獨立運行的能力

    子應用運行會污染全局的 window 對象,樣式會污染其他應用,必須有效的隔離起來

    • 子應用路由狀態(tài)保持能力

    激活子應用后,瀏覽器刷新、前進、后退子應用的路由都應該可以正常工作

    • 應用間通信的能力

    應用間可以方便、快捷的通信

    數(shù)據(jù)來源 star-history(http://star-history.com)

    可以看出 single-spa 和 qiankun 是微前端方案的不二之選,無論是從其業(yè)界認可程度還是生態(tài)的活躍程度,都屬于第一梯隊。下面我們來介紹這些業(yè)界流行的方案:

    ① Single-spa

    從名字上就可以推斷出,Single-spa (https://single-spa.js.org/docs/getting-started-overview/) 是一個將多個單頁面應用聚合為一個整體應用的 JavaScript 微前端框架,其主要實現(xiàn)思路:

    • 預先注冊子應用,包含激活路由、子應用資源、生命周期函數(shù)等;
    • 監(jiān)聽路由的變化,匹配到了激活的路由則加載子應用資源,順序調(diào)用生命周期函數(shù)并最終渲染到容器。

    Single-spa 是微前端領域的先行者,下面介紹的幾個框架也是借鑒了它不少設計思路,但由于它本身沒有處理 CSS 樣式隔離或是 JS 運行時隔離,因此只適合單應用的場景。

    ② Qiankun

    Qiankun (https://qiankun.umijs.org/zh) 是一個基于 single-spa 的微前端實現(xiàn)庫,但對 single-spa 方案中的痛點進行了完善,主要的完善點:

    • 子應用資源由 JS 列表修改為一個 URL,大大減輕了注冊子應用的復雜度
    • 實現(xiàn)應用隔離,完成 JS 隔離方案(window 工廠)和 CSS 隔離方案(類 vue 的 scoped)
    • 增加資源預加載能力,預先將子應用 HTML、JS、CSS 資源緩存下來,加快子應用的打開速度

    優(yōu)點:

    • 監(jiān)聽路由自動的加載、卸載當前路由對應的子應用
    • 完備的沙箱方案,js沙箱做了SnapshotSandboxLegacySandboxProxySandbox三套漸進增強方案,css沙箱做了兩套strictStyleIsolationexperimentalStyleIsolation兩套適用不同場景的方案
    • 路由保持,瀏覽器刷新、前進、后退,都可以作用到子應用
    • 應用間通信簡單,全局注入

    缺點:

    • 基于路由匹配,無法同時激活多個子應用,也不支持子應用保活
    • 改造成本較大,從 webpack、代碼、路由等等都要做一系列的適配
    • css 沙箱無法絕對的隔離,js 沙箱在某些場景下執(zhí)行性能下降嚴重
    • 支持 viteESM 腳本運行的能力較差

    ③ Garfish

    Garfish (https://www.garfishjs.org/) 是字節(jié)跳動團隊提出的一種微前端解決方案,其原理跟 qiankun 比較近似。

    ④ MicroApp

    MicroApp (https://zeroing.jd.com/) 是京東開發(fā)的一種基于 WebComponent 進行渲染的微前端架構,它沒有沿襲 single-spa 的思路,而是通過 CustomElement 結合自定義的 ShadowDom,將微前端封裝成一個類 WebComponent 組件,從而實現(xiàn)微前端的組件化渲染。

    優(yōu)點:

    • 使用簡單,MicroApp 提供了 JS 沙箱、樣式隔離、元素隔離、預加載、數(shù)據(jù)通信、靜態(tài)資源補齊等一系列完整的功能
    • MicroApp 沒有任何依賴,這賦予了它小巧的體積和更高的擴展性

    MicroApp 的實現(xiàn)方式其實就是2個概念:HTML Entry 和類 webComponent

    • HTML Entry 其實就是 qiankun 的實現(xiàn)方式,通過加載遠程 HTML,去解析其 DOM 結構從而獲取 JS、CSS 等靜態(tài)資源來實現(xiàn)渲染
    • 類 webComponent 其實是將 CustomElement 結合自定義的 ShadowDom 實現(xiàn) WebComponent 基本一致的功能。

    ⑤ 無界

    無界 (https://wujie-micro.github.io/doc/) 則是騰訊推出的一款微前端解決方案。與眾不同的是,它是一種基于 iframe 的全新微前端方案,無界團隊希望借助 iframe 的優(yōu)點,努力補足 iframe 的缺點,讓 iframe 煥發(fā)新生。

    優(yōu)點:

    • 使用簡單,使用沒有任何心智負擔;
    • 基于 iframe 的天然沙盒,物理隔離,無論是 js、css、dom 都可以完全隔離開來;
    • 支持多應用同時激活,頁面上可以擺放多個 iframe 來組合業(yè)務

    缺點:

    • 路由狀態(tài)丟失,刷新一下,iframe 的 url 狀態(tài)就丟失了;
    • dom 割裂嚴重,彈窗只能在 iframe ,內(nèi)部展示,無法覆蓋到全局
    • 通信困難,只能通過 postmessage 傳遞序列化的消息

    以上這些缺陷歸根結底都是使用 iframe 帶來的限制,無界團隊逐一提出了解決方案:

    針對彈窗適配問題,無界采用 webcomponent 來實現(xiàn)頁面的樣式隔離,子應用的實例在 iframe 中運行,DOM 在主應用容器下的 webcomponent 內(nèi),通過代理 iframe 的 document 到 webcomponent,可以實現(xiàn)兩者的互聯(lián),從而使得iframe無法全局展示的問題。

    針對路由狀態(tài)丟失問題,無界提出了子應用“保活”模式。具體來說,當子應用發(fā)生切換,子應用的容器可以銷毀,但 webcomponent 和 iframe 依然可以選擇保留,這樣等應用切換回來將 webcomponent 再掛載回容器上,使得其獲得類似 vue 的 keep-alive 能力。

    而針對通信難問題,無界提供了三種通信方式:props 注入機制、window.parent 通信機制和去中心化的 EventBus 通信機制。

    ⑥ 用或不用?

    微前端的適用場景

    • 中大型項目
    • 建設微前端項目的初衷就是為未來可能的擴展開發(fā)提供可能,因此微前端非常適合具有多個團隊維護的大型項目。
    • Web 項目
    • 雖然說微前端這個概念不僅限于某種類型的平臺,但是他在 Web 領域能夠發(fā)揮出它的最大優(yōu)勢。諸如同屬于大前端領域的 Native 應用,在這個領域的局限性就比較大,在開發(fā)過程中不能像 Web 項目靈活。
    • 適用于垂類業(yè)務復雜的團隊
    • 綜合來說,提高垂類業(yè)務的復雜度會增加應用的整體產(chǎn)品能力,但它卻帶來了額外的成本和維護挑戰(zhàn)。如果你把生產(chǎn)力放在首位,可以考慮 微前端 架構

    微前端的勸退場景

    • 業(yè)務邊界不清晰的項目
    • 在發(fā)起一個微前端項目前,你需要對該項目的業(yè)務領域及分工有著全面的了解。 如果你不知道某個特定的功能是由哪個團隊負責開發(fā)及維護的,最終這個微前端項目將會變得一團亂,開發(fā)及維護成本極高,而由此帶來的人效提升卻很少,背離的微前端的初衷。
    • 小型項目
    • 在評估是否需要采用微前端架構前,你需要對平臺的規(guī)模有大概的認知,不要為了紙面上的優(yōu)勢而強行采用微前端方案,業(yè)界還有很多其他小而美的框架可以嘗試。

    微前端是前端發(fā)展的必然階段。目前微前端框架也是屬于百花齊放的階段,基本上每一個大廠都有結合自己業(yè)務推出的方案,每個框架都有自己的優(yōu)缺點,大家可以根據(jù)自己的項目去選擇合適好用的即可。

    但需要注意的是,微前端并非是最好的。他只是解決項目復雜性、代碼檢查及管控等問題的一種方式,對于架構設計的合理性提出了更高的挑戰(zhàn)。

    九、CI & CD

    數(shù)據(jù)來源 katalon (https://katalon.com/resources-center/blog/ci-cd-tools)

    Quality at Speed” is the new norm in software development.

    CI 持續(xù)集成(Continuous Integration) ,是我們的開發(fā)工程流里非常重要的一環(huán)。

    在進行多人協(xié)作的日常工作中,為了保證整個團隊的代碼質(zhì)量維持一個比較高的水平,我們往往會在 pre-commit 鉤子里配置 lint 校驗或者在 CI 中執(zhí)行校驗,兩者的最大不同就是本地運行的 git hooks 可以被手動跳過(--no-verify 大法),且校驗未通過內(nèi)容只有當前分支的開發(fā)者本人可見,并伴隨著較長的校驗運行等待時間,無法在根本上保障代碼質(zhì)量。

    同時我們也希望在合碼到 master 之前執(zhí)行一些單元測試和 E2E 測試,這種時候 CI 就成為了最佳選擇。

    CD 持續(xù)交付(Continuous Delivery), 為我們帶來流暢的部署體驗和更好的產(chǎn)品更新速度。

    我們的代碼在通過 CI 校驗流程后,還需要一些相對重復和繁瑣的環(huán)節(jié)來進行部署才能真正被用戶訪問到最新的內(nèi)容,把這些重復的的工作用類似流水線的形式一鍵完成便是 CD 流程的 使命

    ① 歷史

    如果我們把 CI & CD工具分為兩代來對比,可以劃分為:

    第一代工具:Jenkins、TeamCity、Bamboo 等

    第二代工具:CircleCI、GitLab CI 等

    在早期,第一代工具的底層思路大多是使用一條流水線將編譯、測試、部署等重要環(huán)節(jié)鏈接起來,并且這些環(huán)節(jié)的配置基本是通過 UI 交互來實現(xiàn)的。Jenkins 的靈活性和可擴展性使其一直享有著最流行和使用最廣泛的 CI & CD 工具的地位,后續(xù)慢慢發(fā)展出來具有類似思路的 TeamCity、Bamboo 等工具。

    而隨著互聯(lián)網(wǎng)技術的逐漸發(fā)展,開發(fā)者們慢慢注意到之前靈活的 Jenkins 在面對復雜,重復的多個項目時,相關配置的工作量非常大。由于 Jenkins 的相關配置文件 Jenkins file 需要開發(fā)者在Jenkins server 中進行配置,這往往帶來較多的重復操作,所以我們需要一種更簡單的、可復用的 CI & CD 工具來幫我們維護項目。

    CircleCI、 GitLab CI 可以代表第二代工具的出現(xiàn),它們可以將 CI 流程部署在云服務器上,其中 CI 相關運行的配置都基于特定格式的 YAML 文件。由于我們的 YAML 文件和主代碼倉庫存儲在一起,我們不需要手動配置云服務器,CI 云服務器可以根據(jù)不同倉庫的不同配置文件來做特定的處理動作。

    ② Jenkins

    Jenkins (https://www.jenkins.io/) 是一個開源的免費 CI & CD 工具,它支持的平臺非常多,可以在安裝了Java Runtime Environment(JRE)的任何機器上獨立安裝,同時有非常豐富的插件生態(tài)可供開發(fā)者使用,具有自動化構建、測試和部署等功能。

    ③ GitLab CI

    GitLab CI (https://docs.gitlab.com/ee/ci/) 對于在 GitLab 代碼托管平臺上的倉庫來說是最容易實現(xiàn) CI 的方式,如果你想使用其他軟件提供的 CI 能力,就必須注冊對應平臺的賬號和下載相關應用。而 GitLab CI 內(nèi)部集成好了這一切,如果你用 GitLab 的公用 CI 集群部署 CI 腳本,那基本算是開箱即用,使用成本很低。

    ④ Github Actions

    Github Actions 誕生于 2018 年,與誕生于 2004 年的行業(yè)大前輩 Jenkins 相差 14 年。

    其中 Actions 可以算是 Github Actions 最有特色的功能,Github 所有的 Actions 都可以在 (https://github.com/actions) 找到。

    Actions 可以被理解為 CI 流程中可復用的 原子化 step 結點。 試想,如果我們想做實現(xiàn)一個代碼行數(shù)檢查的 CI 節(jié)點,整個腳本的設計大抵會很順利,但是這種基礎的功能可能有很多場景需要,其他業(yè)務線也有類似的能力想要實現(xiàn),沒有 Actions 的話只能做機械的腳本代碼拷貝工作。

    在使用 Github 的 CI 能力后,我們就可以把想要封裝的能力設計為一個 Actions,發(fā)布后其他人也可以使用同一個 Actions 而避免重復開發(fā)。

    我們可以把 Actions 抽象理解為一個活躍在 CI 流水線上的云函數(shù),我們設定好固定的輸入輸出和執(zhí)行環(huán)境后,用戶只需要把云函數(shù)需要的參數(shù)傳遞過去,在腳本正常執(zhí)行的情況下,云函數(shù)就能生成預期的計算結果。

    ⑤ 選型的考慮點

    在 CI 工具選型時,云服務 VS 自建服務是一個永遠也逃不過的話題,云服務的簡單便捷有目共睹,自建服務往往對開發(fā)者的 docker 使用能力也有一定的要求,但是云服務就一定好于自建服務嗎?答案也不是如此,當我們的的 CI 節(jié)點運行出現(xiàn)預期之外的故障時,自建服務可以很方便的通過 SSH 進入內(nèi)部進行調(diào)試和檢查,而云服務就很難進行問題定位。

    但是不論是 Jenkins 豐富的插件生態(tài)還是 Github Actions 多樣的 Actions 能力,功能 原子化 ,細粒度化和能力集成的復用性都是非常有意義的探索命題,它們?yōu)槊恳粋€開發(fā)者都帶來很大的便利,也是跳脫出 CI & CD 領域也值得其他方向共同研究的軟件工程演進方向。

    十、其他

    除了主流的前端研發(fā)領域相關知識,還有一些衍生領域的前沿概念是我們不得不去探索學習的,下面就帶大家深入淺出的了解一下這些能拓寬我們技術知識面的內(nèi)容吧!

    ① Web 3.0

    區(qū)塊鏈

    區(qū)塊鏈是在計算機網(wǎng)絡的節(jié)點之間共享的分布式數(shù)據(jù)庫或分類帳。區(qū)塊鏈以組(稱為塊 [https://www.investopedia.com/terms/b/block-bitcoin-block.asp] ) 的形式收集信息,這些組包含信息集。塊具有一定的存儲容量,并且在填充時關閉并鏈接到先前填充的塊,形成稱為區(qū)塊鏈的數(shù)據(jù)鏈。新添加的塊之后的所有新信息都被編譯成一個新形成的塊,一旦填充,該塊也將被添加到鏈中。區(qū)塊鏈的創(chuàng)新之處在于它實現(xiàn)了數(shù)據(jù)記錄的保真度和安全性,并在不需要接受第三方管理。

    DeFi: Decentralized Finance - 去中心化金融

    DeFi 旨在徹底改變金融部門,消除對銀行、支付處理商和其他中介機構等中央機構的需求。取而代之的是一個基于區(qū)塊鏈的點對點金融系統(tǒng)。

    NFTs: Non-Fungible Tokens - 非同質(zhì)化代幣

    NFT 是一類存在于 區(qū)塊鏈 上的數(shù)字資產(chǎn)。

    每個 NFT 都是唯一的(不可替代的),并且沒有兩個 NFT 是相同的。這與可替代的美元形成對比:一美元與任何其他一美元是完全相同的。

    DAOs: Decentralized Autonomous Organization - 去中心化自治組織

    DAO 是一個為了共同目的而形成的團體,其規(guī)則、計劃和目標都編碼在區(qū)塊鏈上。在 DAO 中,每個人都可以發(fā)布提議并進行投票來做決策。

    加密貨幣

    通過 Web 3.0 應用程序(如比特幣、以太坊等加密貨幣)正在創(chuàng)建一個新的貨幣世界,力求與傳統(tǒng)的法定現(xiàn)金世界區(qū)分開來。

    ② 跨端

    眾所周知,很多平臺都采用了跨端開發(fā)(跨平臺開發(fā))的方式。相對于原生開發(fā),跨端開發(fā)有開發(fā)成本低、開發(fā)周期短、開發(fā)難度小等諸多優(yōu)點。

    那么,如何進行是跨端開發(fā)?

    H5 Hybrid 方案

    簡單來說就是用網(wǎng)頁來跨端。從開發(fā)成本低、標準統(tǒng)一、生態(tài)繁榮上來說,H5 Hybrid 方案優(yōu)秀。但這種方案的劣勢也非常明顯,就是性能和體驗存在顯著的差距,同時 Web 的生態(tài)繁榮來自于其良好的歷史兼容性,也意味著沉重的歷史包袱

    React-Native/Weex 類方案

    React-Native/Weex 這類方案通過盡可能的取長補短,綜合了 Web 生態(tài)和 Native 組件,讓 JS 執(zhí)行代碼后用 Native 的組件進行渲染,以解決拋棄 Web 歷史包袱的問題。

    方案同樣存在一些缺陷:iOS/Android 雙端本身不一致的組件和布局機制,讓雙端一致性難以得到保障。另外,這套方案也需要非常高的維護支持成本。

    Flutter 方案

    Flutter 不繼續(xù)在 Web 生態(tài)上借力,從設計之初也并沒有把 Web 生態(tài)考慮進去。相比于 RN 依賴 Native View 渲染,F(xiàn)lutter則是自繪組件,通過 Skia 繪制到屏幕上。

    由于可以完全發(fā)揮 GPU 的能力,也不需要去 Native 繞一圈。Flutter 理論上能做到更好的性能和兩端一致性,這一意味著理論上未來可能基于 Flutter 的 JS 動態(tài)化方案能夠在樣式上支持的比 Weex 更好。

    目前最主要的問題是 Flutter for Web 從技術原理上來說離生產(chǎn)可用可能還非常遙遠,動態(tài)化能力的確實也會讓部分場景不適用

    小程序運行時方案

    這個方案可以說是目前性價比最高的方案。

    應用體驗方面,小程序技術是前端容器技術的一種應用,其組件及UI都有明確的規(guī)范,開發(fā)者不用考慮兼容性及類似 H5 開發(fā)時復雜工具及框架的選擇。同時,由于組件及 UI 都是預設的,展示體驗也會更佳。

    應用框架支持方面,某些運行時方案不僅支持純 wxml 微信小程序運行,還支持包括 uniapp、 Taro、kbone 等第三方框架集成的小程序。

    宿主環(huán)境結合方面,小程序是基于 App 端實現(xiàn)的應用,其獲取系統(tǒng)(App)的權限也會多于 H5;隨著微信小程序的潮流引領,各大主流互聯(lián)網(wǎng)平臺的追隨,小程序技術的發(fā)展已經(jīng)趨于成熟,市面上小程序運行時已經(jīng)開始出現(xiàn)多智能終端設備的適配(基于 Andriod 系統(tǒng)的多終端屏幕適配)。

    ③ WebAssembly

    優(yōu)勢

    • 解釋、編譯和優(yōu)化:另一方面,WebAssembly 更緊湊,并且由于其簡潔的設計,二進制格式允許更快的解析和快速優(yōu)化。
    • 便攜安全:它獨立于平臺、獨立于硬件和獨立于語言,它不對設備或瀏覽器沒有任何特殊要求,這增強了其便攜性,代碼在內(nèi)存安全的沙盒環(huán)境中進行驗證和執(zhí)行,可以防止安全漏洞和數(shù)據(jù)損壞。

    Javascript 的運行步驟

    WebAssembly 的運行步驟

    劣勢

    • 沒有垃圾收集:WebAssembly 使用平面/線性內(nèi)存模型,在實例化時分配大量內(nèi)存并且不會自動回收內(nèi)存。
    • 不能直接訪問 DOM:WebAssembly 無法訪問文檔對象模型 (DOM),任何 DOM 操作都需要使用 JavaScript 間接完成。在通過 JavaScript 膠水代碼完成 DOM 操作的情況下,它也可以使用工具鏈,例如 Emscripten。其部分性能取決于所使用的庫和膠水代碼的運行效率。
    • 舊瀏覽器不支持:通常較舊的瀏覽器,比如 ie,沒有可用于實例化和加載 WebAssembly 模塊的所需對象。

    ④ Web 3D

    數(shù)據(jù)來源 star-history (http://star-history.com)

    Web3D 是在Web瀏覽器實現(xiàn) 3D 模型繪制的一系列技術的統(tǒng)稱,用來豐富網(wǎng)頁用戶的使用體驗。目前 Web3D 技術已經(jīng)在許多場景起著無可替代的作用,利用 3D 模型實現(xiàn)商品、房間的展示,既可以給客戶帶來身臨其境的參觀體驗,還可以提供他們豐富的交互效果;將 3D 游戲、虛擬社交軟件移植到網(wǎng)頁上,由于無需本地安裝客戶端,有助于吸納大量的用戶;在地圖和導航中引入實物模型,可以使用戶直觀地識別地理信息;在醫(yī)療和教育培訓中引入網(wǎng)頁 3D 教具,可以用于科普和仿真實驗。未來隨著 XR 設備的推廣,Web3D 技術也將有更豐富的使用體驗,產(chǎn)生更多元的交互場景。

    OpenGL

    是計算機圖形編程的接口標準,為了將圖形編程引入瀏覽器,OpenGL 分化出了一個特殊版本 OpenGL ES ,WebGL則是將 OpenGL ES 以 JavaScript 接口的形式暴露給用戶使用。圖形編程有一個重要的概念叫做“著色器”,在 OpenGL 里由 GLSL 實現(xiàn),它是一種編譯成 GPU 匯編程序以提供圖形硬件運行的高級語言,在 WebGL 中,我們同樣可以編寫 GLSL 來實現(xiàn)著色器,最終將通過對應的 JavaScript 接口將其編譯成二進制從而運行在瀏覽器上。

    X3D

    是一種聲明式編程范式的用于表示 3D 模型的 ISO 標準,其前身是 VRML ,它可以提供用戶以 xml 或 json 的形式渲染出 3D 圖形,從而避免圖形渲染中復雜的計算和實現(xiàn)。目前 HTML 標準暫時不直接支持此類技術,不過已經(jīng)有一些 JavaScript 庫實現(xiàn)了這個標準,例如 X3DOM 和 X_ite 。以 X3DOM 為例,由于瀏覽器不直接原生支持 X3D 特殊標簽的渲染,X3DOM 底層便使用 JavaScript 通過 DOM 操作識別用戶聲明的 X3D 標簽,并利用 WebGL 進行圖形渲染。

    ThreeJS

    也是一套基于 WebGL 的技術封裝,整合了 Audio 等 API ,并且抽象出場景、材質(zhì)、動畫、攝像機等應用層概念的 Web3D 引擎,與其類似的引擎工具有 BabylonJS 、SceneJS 等,它們在各類場景下各有千秋,需要使用者根據(jù)自己的需求選擇合適的引擎進行開發(fā)。

    ⑤ Serverless

    Serverless 這個詞可以分為 server 和 less 兩部分。server自然就是服務器,less 則是使減少的意思。但組合起來,Serverless 并不是指不需要服務器,而是開發(fā)者不需要關心服務器的運維的一種架構

    與之相對的,是 serverful 架構(這并不是一個被廣泛使用的術語)。與 Serverless 架構相反,serverful 架構要求開發(fā)者細致地關心服務的運維。

    Serverless 只是一種具有以上特點的架構,但是開發(fā)者實際使用的 Serverless 平臺可能有很多種。其中具有代表性的兩種是:BaaS 以及 FaaS:

    BaaS

    Backend as a Service, 后端即服務指的是開發(fā)者不再編寫所有的后端邏輯,而是完全使用服務商提供的。這部分邏輯通常包含:數(shù)據(jù)庫服務、登錄注冊服務、消息推送服務等。所以如果用一個詞來代表 BaaS,可以使用“外包”。它代表了,軟件開發(fā)團隊將一些后端邏輯完全外包給 BaaS 平臺,而不需要自己編寫。

    FaaS

    Function as a Service,函數(shù)即服務指的是開發(fā)者以函數(shù)的形式編寫、組織后端邏輯,并將其上傳到 FaaS 平臺上。而這些函數(shù)會在什么情況下被觸發(fā),則是開發(fā)者需要關心的另一件事情。所以,我們可以用“函數(shù)”這個詞來代表 FaaS。開發(fā)者只需要將邏輯封裝在一個個函數(shù)中,而不需要關心如何管理擴縮容以及可用性。

    ⑥ ChatGPT

    ChatGPT 是 OpenAI 12 月 1 日官宣推出的一款對話式大規(guī)模語言模型,以對話的方式進行交互,采用基于 GPT-3.5 架構。

    數(shù)據(jù)來源 ChatGPT-真格基金分享 (https://daimajia.com/2022/12/05/chatgpt-zhenfund)

    如果你嘗試一下與它對話,你會發(fā)現(xiàn)它什么都能回答,而且能連續(xù)有理有據(jù)的回答,很難相信他是一個AI,反而更像是一個人工助理。

    我們或許能用它?

    • 通過自然語言翻譯為代碼,如通過注釋生成代碼,本質(zhì)即 GitHub Copilot 在做的事
    • 代碼 Debugger / CodeReview,幫我們做一些測試工作
    • 代碼重構,比如講 Python 代碼重構成 Golang,如 Twitter
    • 查詢技術知識,如 Bash 命令

    看看大家怎么說


    技術的進步往往會帶來生產(chǎn)力的進一步解放。對于每一個人來說 ,如何用好更新穎的工具,都是眼下需要思考的重點。

    十一、最后的最后

    小小預言一下,在 2023 這些方向可能會給人帶來不小的驚喜,同時存在很大的探索價值:

    • Web 框架:上文提到的 Svelte 需要逐漸完善的生態(tài)才能促進正向循環(huán),這塊對于開發(fā)者來說還有很大可以發(fā)揮的空間。老朋友 React 推出的 React Server Components 也更加體現(xiàn)了自己的方向性,相信寶刀未老的 React 會在未來提出更多突破性的概念。
    • 呈現(xiàn)框架(Rendering Frameworks):Next.js 在官網(wǎng)說它可以帶給開發(fā)者最棒的 React 開發(fā)體驗。每個 React 開發(fā)者都應該試試它的 V13 版本,相信會給你帶來煥然一新的體驗。
    • 測試工具:今年最受關注的新星 E2E 測試工具—— Playwright,支持多種語言,如果你已經(jīng)厭倦了使用傳統(tǒng)測試工具,那一定不能錯過它。
    • 打包工具:快的厲害的 Turbopack,并且未來計劃支持更多的使用途徑,用 Rust 語言編寫的前端工程化生態(tài)鏈的成員們逐漸超越了之前具有霸主地位的前輩工具們。
    • 編譯工具:持續(xù)完善的插件系統(tǒng)將為 SWC 打造多面能力,雖然目前進行插件開發(fā)要學習 Rust 和 WebAssembly,但這依然值得我們?nèi)L試。
    • 樣式工具:CSS 預處理器 & PostCSS 依舊會是主流選項,但原子化 CSS 會越來越受到重視。
    • 微前端方案:模塊聯(lián)邦與現(xiàn)有容器化微前端方案的靈活結合,或許將解決部分開發(fā)痛點。
    • CI & CD:Github Actions 的節(jié)點化云服務助力全流程提升開發(fā)效率。
    • 值得單獨一提的是:
      • ChatGPT 和前端生態(tài)的結合:OpenAI 和工程研發(fā)的組合將更有想象力,未來一些簡單且具有部分重復節(jié)點的任務完全可以交給 AI 來幫忙完成。
      • tRPC :提供端到端的類型安全能力,體驗 TS 與 BFF 的化學反應。
      • Bun 相關生態(tài):拋開 V8 ,找到另一片天。或許未來能在全棧開發(fā)領域中為前端開發(fā)者開辟新的成長空間。

    看到這里,你一定收獲了不少新知識吧,但這仍然是前端領域大潮中的冰山一角。不過也不必“哀吾生之須臾,羨長江之無窮”,作為一名信息行業(yè)的一朵小浪花,我們永遠在路上,永遠有無限的角度值得我們?nèi)ネ诰驅(qū)W習。與其感嘆知海浩瀚無從下手,不如爭取每天都進步一點點,多了解一個新概念,在 2023 成為更好的自己!

    參考

    RSC:

    • https://developer.aliyun.com/article/913326
    • https://zhuanlan.zhihu.com/p/340816128

    編譯工具:

    • https://juejin.cn/post/7136404050995576863
    • https://juejin.cn/post/6968636129239105549

    測試工具:

    • https://www.freecodecamp.org/chinese/news/front-end-engineering-test/
    • https://jestjs.io/docs/tutorial-react

    WebAssembly:

    • https://juejin.cn/post/7110955912730738695
    • https://medium.com/dscvitpune/introduction-to-webassembly-wasm-54d505d6d569

    Video dialogue:

    Faiure is not afraid.

    短片中的對話:

    “I,Lei Wujie, get here all the way by treading on failure. But, I can afford to lose. I believe, as long as I'm breathing, one day, I will win.”

    “我,雷無桀,就是一敗著來到這里的。但是,我輸得起。我相信,只要我還活著,總有一天,我會贏回來的。”


    Good evening!Some friends watched my yesterday's video, and encouraged me not to be frustrated.

    晚上好!一些朋友看了我昨天的視頻,并鼓勵我不要氣餒

    If you feel my frustration from the last video, I have to say I am not.

    如果你從上一個視頻中看到我的氣餒,我必須說沒有。

    Just like the beginning of this vedio, all my way to XIAKELU, I have tasted too much failure.

    就像這個視頻開頭的短片,一路來到俠客廬,我已經(jīng)到了太多的失敗。

    I still believe, as long as I'm alive, one day, I will break the chains

    我依然相信,只要我還活著,有一天,我終會掙脫枷鎖

    and hug the things which you would like to spend all your life to pursue it.

    并會擁抱那些愿意讓你耗費一生去追求的東西。


    Every day is a new day, and always believe beautiful things will happen.

    每一天都是新的一天,永遠相信美好的事情終將發(fā)生。


    單詞解析:

    1. tread [tred] v.踩;踏
    2. afford [??f??rd] v.負擔得起;提供
    3. encourage [?n?k??r?d?] vt.支持;鼓勵
    4. frustrated [?fr?stre?t?d] adj.沮喪的
    5. frustration [fr??stre??n] n.挫敗;沮喪
    6. taste [te?st] v.嘗出
    7. break [bre?k] v.打破
    8. hug [h?ɡ] v.擁抱;摟抱
    9. pursue [p?r?su?] v.追求;致力于

    「晨起練口語」用英語分享日常,通過日常練習口語,同時提升詞匯量。

    同款視頻,會在西瓜號“廢柴自九”、抖Y號“廢柴自九”、VX號“廢柴自九”同步更新。

    純手工制作,如發(fā)現(xiàn)錯誤,歡迎在評論區(qū)留言、更正、討論。

    感謝您的關注和支持。

網(wǎng)站首頁   |    關于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有