一文帶你梳理清楚 Next-js 的功能
前面寫了好幾篇關於 Next.js 的文章,雖然都不長,但都是實際使用過程中的一些經驗分享,不過這些文章對於不瞭解 Next.js 的人來說,可能很不友好,我也一直想重新梳理一下 Next.js 使用的方案。因此打算好好寫一下 Next.js 相關運用,並整理到一個專欄,主要內容會從瞭解 Next.js 開始,然後逐漸搭建一個完整的項目模板,讓沒怎麼接觸過 Next.js 甚至 React 的小夥伴也能從中逐漸學習到一些東西,當然這個時間週期可能會比較長。感興趣的可以關注一下作者。
前言
如果你用過 React 或者想嘗試 React,那麼建議你使用 Next.js 來搭建 React 項目,本篇文章將帶你詳細瞭解 Next.JS 主要的一些功能,看它能給我們帶來什麼樣的能力,然後再談一下對 React 單頁應用的看法。
Next.js 可以帶給我們什麼?
Next.js 是一個 React web 應用框架,這是官方對自己的定義,然後它主要做的事情有以下幾點:
-
完善的工程化機制
-
良好的開發和構建性能
-
智能文件路由系統
-
多種渲染模式來保證頁面性能體驗
-
可擴展配置
-
提供其他多方面性能優化方案
-
提供性能數據,讓開發者更好的分析性能。
-
提供的其他常用功能或者擴展,比如使用 mdx 來編寫頁面的功能等等。
完善的工程化機制
你不需要自己去配置 webpack 方案,它已經內置了以下工程化基礎:
-
babel
內置,支持 JS 代碼向後兼容 -
postcss
內置,支持 CSS 代碼向後兼容 -
browserslist
支持配置兼容的瀏覽器信息,配合babel
和postcss
工作。 -
TypeScript
可選擇使用,保證代碼的質量,以及可閱讀性和可維護性。 -
eslint
可選擇使用,檢測代碼格式,可自定義規則。vscode 編寫代碼,或者 build 打包時都會有提示。 -
prettier
可通過擴展使用,格式化代碼,可自定義規則。 -
css modules
內置 -
css-in-js
可擴展使用 -
tailwind css
可擴展使用
也做了一些打包優化功能:
-
tree shaking
-
代碼壓縮
-
頁面自動靜態化
-
按需打包第三方 es 包(通過設置
transpilePackages
屬性,讓部分包可以被 next-babel 打包) -
異步動態加載組件,和
React.lazy
功能一樣,只不過實現得更早。
基本上使用了 Next.js 你不需要再去處理工程化相關事項。也可以通過很簡單的方式去優化打包性能,且每次構建都會輸出頁面資源大小信息,如下圖所示:
圖中是我寫的一個測試工程,會清楚的標註每個頁面首次加載的 JS 資源的大小,最下面是公共部分資源的大小。
如果你需要具體的分析 JS 資源的組成,那麼可以使用 @next/bundle-analyzer[1] 來分析,其可具體分析服務端代碼、edge 運行時代嗎、客戶端代碼
良好的開發和構建性能
去年 next.js 13 發佈會上,官方公佈了 next.js 使用 turbopack
進行編譯打包,稱其編譯速度極快,將是 webpack 的繼承者,感興趣的同學可以去看一看 [2],我記得有翻譯版本,我們就不去測試它到底有多快了,反正就是很快。我是從 next.js 10 直接切到的 13,那感覺真的不要太爽,啓動秒啓,首次打開頁面也秒開,因爲開發模式 next.js
都是動態編譯,啓動的時候並不會去編譯頁面,訪問纔去動態編譯,而且因爲是多頁應用,頁面非共用部分互不影響,不會因爲工程的業務模塊變多而導致頁面訪問變慢。
構建性能也很快,以我前面打包的工程爲例,我算了一下,十幾個頁面,全部打包只用了 10.52 秒,有兩個頁面還動態請求了接口,不然還會更短一些。
不過我聽說 windows 上開發性能或者打包性能可能有一點問題,可以注意一下。
智能文件路由系統
Next.js 的智能文件路由指的是,頁面寫在 pages
目錄或者 src/pages
下的 js 文件都會被認爲是頁面,也會當成頁面來打包,路由定義了一套動態路由 [3] 的規則,感興趣的可以去看一下。
上面說的只要是特定目錄下的 js 文件都會當成頁面,這樣會造成不經意把非頁面的 js 文件也打包成了頁面,這樣肯定是不太好的,因此 Next.js 13 纔會推廣出 app
目錄下的新模式,但還不太穩定,有些功能還沒實現,因此如果在老模式下還是需要注意,可以這樣來處理文件結構:
./src
├── common // 公共部分
├── views // 頁面內容,所有代碼都寫在這個文件
│ └── home // 首頁
│ ├── index.tsx
│ ├── List.tsx
│ ├── util.ts
│ └── style.module.css
├── pages
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── api
│ └── home.tsx // 只對 src/views/home 的導出進行轉發
└── styles
├── Home.module.css
└── globals.css
複製代碼
pages/**
目錄下只對 src/views/**
的導出進行轉發。
// src/pages/home.tsx
export * from "../views/home";
複製代碼
其實智能文件路由系統雖然有一點缺陷,但優點更多,它也是 Next.js 最重要的特性之一,因爲它在一定程度上規範了代碼組織結構,這也是比較重要的。
當然還是等 Next.js 新模式穩定下來後是最好的,感興趣的可以在掘金上搜索 Next.js 13
關鍵字,有其他掘友寫了相關文章。
多種渲染模式來保證頁面性能體驗
渲染模式是決定頁面性能很重要的因素,也是 Next.js 最核心的一部分,之前寫了幾篇相關的文章,這裏就不進行再次說明了,建議去看看:
-
理解前端基礎渲染模式|CSR、SSR、同構、靜態化 [4]
-
# 前端各種渲染模式性能對比分析 [5]
-
Next.js 性能優化之 ISR 渲染入門和原理探索 [6]
可擴展配置
Next.js 的可配置性真的是一個很強大的特色,它準備了一套默認就很好用的默認配置,但這些配置基本上用戶都可以 完全
控制它(完全做一個保留,但大型工程基本上都是可以支撐的)。
下面我們來分析一下它的可配置功能。
-
配置文件
next.config.js
中暴露了 webpack 實例,因此你可以完全控制 webpack -
配置文件
next.config.js
中支持配置自定義配置,你可以把一些公用的不變的配置寫在serverRuntimeConfig
或者publicRuntimeConfig
中,前者只會出現在服務端,後者會暴露到客戶端。 -
可 自定義 server[7] ,你可以在啓動服務的時候做一些自己想要做的處理,比如 node.js 性能監控等等。
-
不自定義 server ,也可以使用它提供的 middreware[8] 機制來攔截請求或者校驗權限等事項。
-
自定義 APP[9],也就是
_app.js
,它用於處理多個頁面公共部分。 -
自定義 Document[10],也就是
_document.js
,用於自定義配置 html 生成內容,比如插入 Google 分析腳本。 -
自定義錯誤界面 [11] 也就是 404 或者 500 錯誤狀態的頁面。
-
可自定義
babel
[12] 和postcss
[13] 等工程化規則配置。
可以看出基本上各個方面都可以自定義配置,擴展性還是很強的。
提供其他多方面性能優化方案
Next.js 除了頁面默認靜態化(不使用 getServerSideProps/getStaticPath/getInitialProps),還提供了其他方面的優化方案:
-
圖片優化 [14]:大部分頁面基本上都會有或多或少的圖片,圖片往往是影響頁面性能體驗的重要因素之一,因爲現在一張圖片的體積很可能比頁面的所有代碼體積還打,因此關注性能就一定要關注圖片。
-
字體優化 [15]:字體文件一般也比較大,這一塊還不是很瞭解,因爲時間問題,後續瞭解完再更新一下。
提供性能數據
Next.js 提供了獲取應用性能數據的方法 reportWebVitals[16], 只能在 App
組件中使用。
// _app.tsx
export function reportWebVitals(metric: NextWebVitalsMetric) {
console.log(metric)
}
複製代碼
提供的其他常用功能或擴展
其他功能:
-
API Routes
[17] ,Next.js 支持在pages/api
目錄下編寫接口,可通過接口去實現ISR
增量靜態化功能,前端用於編寫 BFF 接口應該也是一個不錯的方案,但注意不能在getStaticProps/getStaticPaths
中去請求,打包的時候請求不了。 -
next/amp
[18]: 用於支持開發 AMP 應用。
擴展:
@next/mdx
[19]: 用於支持使用 mdx 來編寫頁面,也就是如果要開發一個 md 的文檔工程,直接接入它即可。
談談 React 單頁應用
用過 React 的應該都知道官方提供了一個 Create React App
腳手架,可以很方便的搭建一個單頁應用,但是其實真的不太好用(我不知道大家有沒有這種感覺),因此我們可能還要去社區找一些完整的模板,或者新建以後,我們還要去新增各種配置和規劃頁面結構規範,比如路由、redux、請求封裝,不能做到真正的開箱即用。而且兩年前就已經傳出不怎麼維護的消息,將近一年沒有新版本了。
上一次版本還是在去年 4 月份,然後在官方 github 論壇上,很多都在說 CRA 已經被放棄了。
再加上 React 官方文檔現在其實也在推薦其他的搭建方案,比如 Next.js 和 Gatsby:
其實 CRA 放棄沒放棄,關係也不是特別大,反正也可以暴露了 webpack 配置,但需要自己定製的內容太多,而且並沒不能完全的去體現出 React 的能力,比如不支持服務端渲染,也不支持 React 18 中的 Serevr Component/Client Component/Shared Component 等等新概念,因此 CAR
還是會逐漸被 Next.js
或者 Gatsby.js
給逐漸取代。
CAR
的結果如此,後續的前端開發的方向應該會更偏向 Next.js
或者 Gatsby.js
,不過這些主要是在 C 端或者 B 工程的市場會表現更好,在不那麼重視首屏性能的管理端應用來說,影響不會那麼大。
最後
Next.js 已經很全面了,但還是有一些需要開發者自己去處理,比如請求方法(感覺後面有可能官方會提供統一方案)、redux、多語言等等,這些我之前寫了一些相關的文章,感興趣的可以去看看,沒寫的後面也會補上。
關於本文
作者:𝑯𝒖𝒕𝒂𝒐
https://juejin.cn/post/7206261082452639802
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/xeRYh1sbt3iW0uF84qDgpw