close
點擊下方「前端技術優選」,選擇「設為星標」
第一時間關注技術乾貨!

icejs 是什麼?

icejs 是一個基於 React 的漸進式研發框架,由淘系前端飛冰(ICE)團隊於 2020.02 發布 1.0 版本,icejs 目前廣泛服務於阿里內部以及社區用戶,如下圖所示,在阿里內部每天至少有 400 多個倉庫基於 icejs 構建並發布,目前已經服務了內部 3K 多的開發者以及 5K 多項目。

很多人可能會問,為什麼需要或者什麼場景下需要使用 icejs?這裡把其中的 icejs 換成 Next.js、UmiJS 或者 Nuxt.js 問題依然成立,核心的問題都是此類研發框架的價值是什麼?我嘗試講一下飛冰團隊對於這個問題的思考:

通過內置功能+插件化能力保證跨項目的一致性:對於稍具規模的前端團隊往往會涉及很多個前端項目以及跨團隊的協同,一致性的開發&使用方式能夠更好的保證協同效率

通過開箱即用的框架能力降低重複勞作:小到 TypeScript、CSS Modules 之類的構建配置,大到 MPA/SPA/微前端等不同模式的能力提供

某些原本很複雜的功能可以讓業務低成本接入:諸如 SSR/SSG、一體化這些能力,基於 Webpack/Vite 需要做非常多的事情,框架可以讓這個成本大幅度降低

同時也必須承認的是相比於直接基於 Webpack/Vite 這樣的構建工具,研發框架會帶來黑盒、帶來約束、不夠靈活……而這也是對框架開發團隊最大的挑戰:在提供各種能力的基礎上如何還能保證良好的研發體驗。

全新的 2.0 版本

自 2020.02 發布 1.0 版本至今一年半的時間裡,icejs 結合社區的反饋迭代了 70 多個正式版本(平均每周一個版本),這也使得框架的功能豐富度&穩定性不斷提升。而在 2021 年前端社區非常重要的兩個趨勢:

基於 ES modules 的 Bundleless 模式: 隨着瀏覽器對於 ES modules 的原生支持,社區也出現配套的構建工具 Snowpack 以及後續的 Vite,Bundleless 模式正在撼動着以 Webpack 為主流的 Bundle everything 模式

基於 Rust/Go 重寫前端工具鏈:替代 babel 的 swc,替代 Webpack 的 esbuild,Rome 用 rust 重寫,Next.js 引入 Rust 後構建速度提升 5x

這兩個趨勢也讓大家更清晰的認識到傳統 Webpack 工程體系構建速度太慢了,前端的調試構建體驗有很大的提升空間,因此飛冰團隊圍繞「開發者體驗」開始探索 icejs 2.0 版本,經過 3 個月的研發周期,總共 100+ Pull Requests,我們在 2021.09.28 正式發布了 2.0 版本,目前阿里內部 200+ 的項目已經基於 2.0 版本,我們也在今天向社區正式輸出 icejs 2.0 的介紹文章。2.0 的一些重要特性:

Vite 模式:在原先 Webpack 基礎上,同步支持了 Vite 模式,同時在工程配置和框架能力上儘量保持一致性

Webpack 5:將 Webpack 從 V4 版本升級到 V5 版本,引入新版本的 Module Federation、Cache 等相關能力

swc&esbuild:試驗性的在 Webpack 模式下引入 swc 替換 babel,嘗試提升 Webpack 模式下最耗時的代碼編譯階段,同時壓縮鏈路也支持使用 esbuild 替代 terser

更加完善的業務解決方案:提供狀態管理、請求庫、環境配置、微前端、SSR、SSG(新增)、PWA(新增)、keep-alive(新增)等完備的解決方案

全新的文檔:通過Docusaurus 構建全新的文檔站點,得益於 Docusaurus 豐富的能力,文檔在 SEO、加載體驗、Dark Mode、搜索、手機端體驗等能力上有了大幅度的提升

對於 2.0 版本,可以通過命令行快速創建,支持 antd/fusion/... 等多種模板:

$ npm init ice icejs-example# 同時支持 yarn$ yarn init ice icejs-example

為了保證基礎的開發體驗,建議使用 cnpm 或者國內的 npm registry 安裝依賴。

除了 CLI 以外,我們同時提供了研發工具 AppWorks 用於可視化創建項目,只需要在 VS Code 插件市場中搜索並安裝 AppWorks 即可:

Vite 模式:突破

隨着社區不斷湧現的基於 ES modules 的構建工具,以及逐步完善的生態支持度,ES modules 的開發方式被越來越多的開發者所接受和嘗試。得益於 Vite 本身的成熟度,icejs 也是能夠快速的支持 ES modules 開發模式,同時我們的官方腳手架也已經默認開啟了 Vite 模式。

// build.json{ "vite": true}

快速適配 Vite 模式

對於完全基於 Webpack 建設的框架體系,引入 Vite 最大的問題就是兩種模式在使用上如何儘量保持一致、框架代碼如何更好的維護。針對這個問題,首先在配置上統一沿用原先的build.json配置文件,支持publicPath、alias等工程配置,對於框架中所有的工程配置操作都基於原先的webpack-chain進行,

一般情況下不需要面對 Vite/Webpack 的配置差異,通過抽象的 webpack-service 以及 vite-service 兩個適配層,在 service 這一層實現對應的 start/devServer/build 能力,同時藉助 wp2vite 將 Webpack 的配置一次性轉換為 Vite 配置。如下為大體的架構設計,後續我們也會有專門的文章來介紹這部分的設計和實現。

啟動與熱更新

在引入 Vite 之後,我們針對 fusion-design-pro 這個較為複雜的項目做了一些測試,首先是項目啟動時間,首次啟動時間上,Vite 本身有按需構建的機制,加上藉助 esbuild 的加持比 Webpack 快了 50%,但是二次啟動時間上,得益於 Webpack 5 Cache 機制的加持下反而是 Webpack 要稍快於 Vite。

由於 Vite 的 devServer 啟動不依賴源碼編譯,因此 Vite 的 啟動編譯結束時間基於源碼開始執行時間計算

其次是熱更新時間,與啟動時間相比熱更新時間 Vite 是完全碾壓 Webpack 模式的,Vite 模式下熱更新時間提升了 10 倍以上,只需要 100ms,並且不會隨着項目變複雜而劣化。這也是我們覺得 ES modules 模式帶來的最大收益點。

框架能力適配

除了上述基礎的配置以外,框架還提供了更上層的能力,對於這些能力我們也做了同步的支持:

MPA/SPA/微前端/一體化等不同應用模式的工程能力適配

本地調試實時的 TypeScript/ESlint 檢測能力:實現 vite-plugin-ts-checker 以及 vite-plugin-eslint-report 插件

JSX+ 語法支持:結合 Babel 實現對應的 vite-plugin-jsx-plus 插件

SSR/SSG:支持中

通過上述工作,我們保證了 icejs Webpack 模式下 80% 的能力在 Vite 模式下一致性的使用方式,其他能力我們也在結合業務訴求同步支持中。

Webpack 模式:穩中求進

icejs 1.0 有大量存量的 Webpack 模式項目需要持續支持,同時在某些場景也無法切換到 ES modules 模式,因此在 2.0 中我們對於 Webpack 模式依然跟隨社區的腳步在做持續的優化。

Webpack 5

從 ice.js 2.0 版本開始,底層工程依賴的 Webpack 版本將默認採用 v5 版本,工程上對 Webpack 相關的生態進行適配升級,確保開發者能夠順利過渡到 Webpack 5。藉助 Webpack 5 的 Cache 能力,在 2.0 中熱啟動時間提升了近5 倍,同時將 React Fast Refresh 做了內置將熱更新的時間減少了30%。另一方面我們也將諸如 postcss, less-loader, sass-loader 等依賴升級到了最新版本,確保開發者可以享受到新的功能。

基於 Module Federation 的預編譯方案

藉助 Webpack 5 的 Module Federation 特性,icejs 2.0 支持將應用的依賴預構建為一個 Module Federation 的 remote 應用,供當前應用進行消費,應用依賴不再編譯到一個文件中,以減少 Webpack 對於依賴打包所需的時間。

{ "remoteRuntime": true}

通過 Module Federation 預編譯的開啟,熱啟動相比 1.x 版本提升明顯,並且讓熱更新時間縮短近60%。

使用 SWC 替代 Babel(試驗)

swc利用 rust 大大提升 JavaScript 源碼的編譯效率,目前已支持大部分 babel 編譯的場景。因此 icejs 提供一鍵開啟 swc 編譯能力:

{ "swc": true}

開啟 swc 編譯後,除了 babel 被替換以外,默認的壓縮器也從 terser 切換至 swc,進一步縮短時間:

開啟 swc 編譯後,編譯速度平均提升50%,壓縮速度提升近35%。不過 swc 目前對於自定義插件支持還不友好,因此如果強依賴了一些其他 babel 插件,那麼 swc 下目前是很難對齊,因此我們也將該項能力標識為「試驗性」。目前前端社區對於 swc 越加重視, 飛冰團隊也在積極參與 swc 相關方案的討論,相信在不遠的未來我們可以使用 swc 完全替代掉 babel。

更多新特性
微前端 x ESM

在 icejs 支持 Vite 模式之後,同為飛冰團隊開源的微前端框架 icestark 也同步支持了 ESM 規範的微應用,只需要在微應用上配置loadScriptMode: import參數即可開啟:

<AppRouter> <AppRoute title="商家平台"+ loadScriptMode="import" url={[ '//unpkg.com/icestark-child-seller/build/js/index.js', '//unpkg.com/icestark-child-seller/build/css/index.css', ]} /></AppRouter>

在開啟該選項之後,icestark 會通過 dynamic import API 加載微應用資源。由於 ES modules 腳本只執行一次的策略,微應用二次加載渲染的速度提升非常明顯。

跟 SSR 一致的 SSG 方案

SSG(Static Site Generation) 即靜態站點生成,對於一些官網或者文檔的場景,SSG 能夠提供更好的 SEO 以及首屏渲染能力。icejs 1.0 中 SSG 方案基於 puppeteer 實現,開發者經常會遇到環境依賴的問題,在 2.0 中我們將 SSG 和 SSR 的方案做了更好的對齊,使用起來更加簡單,僅需在工程配置中開啟即可:

// build.json{ "ssr": "static"}

僅需上述配置,在 build 之後就會生成每個路由的靜態 HTML 文件,並且也同時支持 SSR 下的Page.getInitialProps在構建時獲取初始數據能力:

├── build| ├── dashboard| | └── index.html # 預渲染 Dashboard 頁面組件得到的 HTML| ├── index.html # 預渲染 Home 頁面組件得到的 HTML| └── js| └── index.js

針對動態路由的場景,也支持在頁面路由組件上設置getStaticPaths屬性:

// src/pages/Project/index.tsx: /project/:idconst Project = (props) => { return <>Hello</>;}+Project.getStaticPaths = async () => {+ return Promise.resolve(['/project/1', '/project/100', '/project/1001']);+}export default Project;

SSG 的構建產物支持直接使用 nginx、oss 以及後端服務等多種部署方式,而應用的渲染模式上也支持按頁面維度分別以 SSR 或者 SSG 方式渲染。

更穩定的依賴管理方案

研發框架往往會包含非常多的工程相關依賴,而我們也時不時會遇到社區依賴發包導致框架不可用的問題,因此在 2.0 中我們將依賴的 70+ 社區 NPM 包進行了預打包,只要 icejs 不主動升級,這些包以及其依賴的包版本就不會變化,以此來保證框架不會受這些依賴包發版影響,同時預打包也能間接提升框架安裝的速度。

未來

Vite模式下的能力完善

目前我們核心的工程能力已支持 Webpack/Vite 兩種模式一鍵切換,包括 SPA/MPA/微前端等場景,但是 Vite 模式下依然有很多需要突破的地方:

SSR/SSG 能力支持

進一步對齊 Vite/Webpack 的工程能力,比如 Vite 中更為簡潔直觀的 Static Assets 使用方式

統一 Vite 模式下 AST 轉換的能力,受限於 Vite 內置編譯工具 esbuild 的開放 API 能力,強依賴 Babel 的場景(react-rerefsh、jsx、jsx+)都是插件各自調用 Babel,我們會在框架層面對這一層進行統一,同時會嘗試直接引入 swc

更輕量的一體化研發模式

在很多中小型中後台系統的業務場景下,往往都是一個開發者從前到後負責整體的研發,在這種場景下以往的前後端分離反而會增加代碼管理、接口聯調、發布部署流程等成本。得益於前後端都使用 JavaScript 帶來的語言一致性,以及 Serverless 基建保障低運維成本,過去一年裡,我們基於 icejs + midway-hooks 的一體化研發模式在阿里內部落地了眾多中小型中後台系統,同時也為 C 端業務低成本的實現 SSR 方案提供了巨大支持。

在 2.0 版本里,我們希望進一步完善一體化方案,一方面會讓服務端框架更加輕量以提升 API 的開發調試體驗,另一方面也會在 FaaS 基礎上支持 Node.js 部署,保障即便在沒有 Serverless 基建的公司中也能夠使用一體化能力。

關於我們

飛冰(ICE)團隊隸屬於淘系前端架構團隊,希望能通過研發框架和研發工具改善前端開發者的體驗。如果對 icejs、Vite、Webpack、VS Code 插件、Electron 等領域比較感興趣,歡迎關注我們的 GitHub 倉庫:

https://github.com/alibaba/ice

如果在使用飛冰相關產品中遇到問題,歡迎加入飛冰社區釘釘群反饋&交流:

相關鏈接

飛冰(ICE)站點:https://ice.work/

icejs GitHub 倉庫:https://github.com/alibaba/ice

icejs 2.0.0 Release Pull Request https://github.com/alibaba/ice/pull/4334

VS Code 插件 AppWorks:https://appworks.site/

飛冰釘釘群二維碼:https://ice.alicdn.com/assets/images/ice-group.png

微前端方案 icestark:https://github.com/ice-lab/icestark

Vite: https://vitejs.dev/

swc:https://swc.rs/

esbuild: https://esbuild.github.io/

icejs NPM 依賴預打包:https://github.com/ice-lab/builder-deps


在看點這裡
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()