偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

偷師 Next.js:我學(xué)到的 6 個(gè)設(shè)計(jì)技巧

開發(fā) 前端
從 React 誕生之初一直到React Hooks推出并進(jìn)化成完全形態(tài)。目前(2021/1/2)React Hooks 仍然不是完全形態(tài),componentDidCatch、getSnapshotBeforeUpdate、getDerivedStateFromError等特性還不健全,具體見Do Hooks cover all use cases for classes?

[[373397]]

本文轉(zhuǎn)載自微信公眾號「前端向后」,作者黯羽輕揚(yáng) 。轉(zhuǎn)載本文請聯(lián)系前端向后公眾號。    

本文記錄了我從中發(fā)現(xiàn)的設(shè)計(jì)技巧,包括 API 設(shè)計(jì)、文檔設(shè)計(jì)、框架設(shè)計(jì)等,也分享給你

定義基類,可能不如定義模塊

首先,類(Class)和模塊(Module)都是組織代碼的可選方式,放到 API 設(shè)計(jì)的場景,都能用來約束寫法,暴露框架能力。而在模塊概念成為正統(tǒng)之前,前端框架大多提供基類來滿足這種需要,因?yàn)闆]得選

典型的,React 通過React.Component基類暴露出各種生命周期 Hook,同時(shí)定義了組件寫法:

  1. // Components 
  2. class Clock extends React.Component { 
  3.   // Props 
  4.   constructor(props) { 
  5.     super(props); 
  6.     // State 
  7.     this.state = {date: new Date()}; 
  8.   } 
  9.  
  10.   // Lifecycle 
  11.   componentDidMount() { } 
  12.   componentWillUnmount() { } 
  13.  
  14.   render() { 
  15.     // Template 
  16.     return ( 
  17.       <div> 
  18.         <h1>Hello, world!</h1> 
  19.         <h2>It is {this.state.date.toLocaleTimeString()}.</h2> 
  20.       </div> 
  21.     ); 
  22.   } 

將 Props、State、Lifecycle、Template 等框架能力整合成一個(gè) Class,稱之為組件。并且,在很長的一段時(shí)間里,React 中能稱為組件的只有 Class

這段很長的時(shí)間有多長?

從 React 誕生之初一直到React Hooks推出并進(jìn)化成完全形態(tài)。目前(2021/1/2)React Hooks 仍然不是完全形態(tài),componentDidCatch、getSnapshotBeforeUpdate、getDerivedStateFromError等特性還不健全,具體見Do Hooks cover all use cases for classes?

也就是說,時(shí)至今日,React Components 仍等價(jià)于 Class Components,早期的函數(shù)式組件只能叫 Stateless Components,獲得 Hooks 加持之后的函數(shù)式組件雖然擺脫了 Stateless,但與完全形態(tài)的 Class Components 還有一點(diǎn)點(diǎn)差距

將 Components 概念與 Class 強(qiáng)綁定在一起真是個(gè)糟糕的選擇,被寄予厚望的 Hooks 充分說明了這一點(diǎn)。但 Props、State、Lifecycle、Template 這些框架能力又總要有東西來承載,那么,更好的選擇是什么呢?

可能是 Module。強(qiáng)調(diào)可能,是因?yàn)閮H在組織代碼這一點(diǎn)上,Module 比 Class 更純粹。Module 只組織代碼,將變量、函數(shù)等語法元素圈在一起,而不像 Class 會強(qiáng)加實(shí)例狀態(tài)、成員方法等額外概念

例如,Next.js 的 Page 定義就只是個(gè)文件模塊:

  1. // pages/about.js 
  2. function About() { 
  3.   return <div>About</div> 
  4.  
  5. export default About 

最簡單的 Page,只要默認(rèn)暴露出一個(gè) React 組件即可。需要用到更多功能,再按需暴露更多的既定 API:

  1. // pages/blog.js 
  2. function Blog({ posts }) { 
  3.   // Render posts... 
  4.  
  5. // API 1 
  6. export async function getStaticProps() { } 
  7. // API 2 
  8. export async function getStaticPaths() { } 
  9. // API 3 
  10. export async function getServerSideProps() { } 
  11. // API n 
  12. export async function xxx() { } 
  13.  
  14. export default Blog 

對比 Class 形式的 API 設(shè)計(jì),這種Module 式 API 設(shè)計(jì)更加純粹,不強(qiáng)加額外語法元素(尤其是 Class 這種根基龐大的語法元素,帶來一眾super()、bind(this)、static),在某些場景下不失為一種更好的選擇

文件約定路由

Next.js 里沒有Router.register、沒有new Route()、也沒有app.use(),沒有一切你能想到的路由定義 API

因?yàn)楦緵]有 API,路由采用的是文件路徑約定:

  1. // 靜態(tài)路由 
  2. pages/index.js → / 
  3. pages/blog/index.js → /blog 
  4. pages/blog/first-post.js → /blog/first-post 
  5. pages/dashboard/settings/username.js → /dashboard/settings/username 
  6.  
  7. // 動(dòng)態(tài)路由 
  8. pages/blog/[slug].js → /blog/:slug (/blog/hello-world) 
  9. pages/[username]/settings.js → /:username/settings (/foo/settings) 
  10. pages/post/[...all].js → /post/* (/post/2020/id/title) 

也就是說,通過源碼所在文件路徑來標(biāo)識路由,甚至還能支持通配符,這么神奇,當(dāng)然要親眼看看源碼目錄才能感受到視覺沖擊:

  1. pages 
  2. ├── _app.js 
  3. ├── _document.tsx 
  4. ├── api 
  5. │   ├── collection 
  6. │   │   ├── [id].tsx 
  7. │   │   └── index.tsx 
  8. │   ├── photo 
  9. │   │   ├── [id].tsx 
  10. │   │   ├── download 
  11. │   │   │   └── [id].tsx 
  12. │   │   └── index.tsx 
  13. │   ├── stats 
  14. │   │   └── index.tsx 
  15. │   └── user 
  16. │       └── index.tsx 
  17. ├── collection 
  18. │   └── [slug].tsx 
  19. └── index.tsx 

API 之間的無縫聯(lián)動(dòng)

通過前兩篇文章,我們知道 Next.js 要解決的問題是預(yù)渲染,圍繞預(yù)渲染探索出了 SSG、SSR 兩種渲染模式,并在此基礎(chǔ)上支持了包括 CSR 在內(nèi)的不同渲染模式混用:

  • ISR(Incremental Static Regeneration):增量靜態(tài)再生成,運(yùn)行時(shí)定期重新生成靜態(tài) HTML
  • SSG 降級 SSR:未命中預(yù)先生成的靜態(tài) HTML 時(shí),立即進(jìn)行 SSR
  • SSR 帶靜態(tài)緩存:SSR 完成之后,將結(jié)果緩存起來,下次命中靜態(tài)緩存直接返回(相當(dāng)于 SSG)
  • SSG 結(jié)合 CSR:編譯時(shí)生成靜態(tài)部分(頁面外框),CSR 填充動(dòng)態(tài)部分(頁面內(nèi)容)
  • SSR 聯(lián)動(dòng) CSR:URL 直接訪問走更快的 SSR,SPA 跳轉(zhuǎn)過來走體驗(yàn)更優(yōu)的 CSR

從 API 設(shè)計(jì)的角度乍一看,似乎需要給每種組合取個(gè)別致的名字,并暴露出專門的 API,就像 SSGwithFallback、SSRwithStaticCache、PartialSSG、SPAMode…

然而,Next.js 不僅支持了所有這些混用特性,而且沒有增加任何頂層 API,它的做法是增加一些選項(xiàng),例如:

  1. // SSG 基礎(chǔ)款 
  2. export async function getStaticProps(context) { 
  3.   return { 
  4.     props: {}, // will be passed to the page component as props 
  5.   } 
  6.  
  7. // SSG 變身 ISR,給返回值添上 revalidate 屬性 
  8. export async function getStaticProps(context) { 
  9.   return { 
  10.     props: {}, // will be passed to the page component as props 
  11.  
  12.     // Next.js will attempt to re-generate the page: 
  13.     // - When a request comes in 
  14.     // - At most once every second 
  15.     revalidate: 1, // In seconds 
  16.   } 
  17.  
  18. // SSG 感知路由的高級款,實(shí)現(xiàn)了 getStaticPaths 
  19. export async function getStaticPaths() { 
  20.   return { 
  21.     paths: [ 
  22.       { params: { ... } } // See the "paths" section below 
  23.     ], 
  24.     fallback: false 
  25.   }; 
  26.  
  27. // SSG 變身 SSR帶靜態(tài)緩存,fallback選項(xiàng)改為true 
  28. export async function getStaticPaths() { 
  29.   return { 
  30.     paths: [ 
  31.       { params: { ... } } // See the "paths" section below 
  32.     ], 
  33.     fallback: true 
  34.   }; 
  35.  
  36. // SSG 變身 SSG降級SSR,fallback選項(xiàng)改為'blocking' 
  37. export async function getStaticPaths() { 
  38.   return { 
  39.     paths: [ 
  40.       { params: { ... } } // See the "paths" section below 
  41.     ], 
  42.     fallback: 'blocking' 
  43.   }; 

這種基于細(xì)分選項(xiàng)的 API 聯(lián)動(dòng)用起來更輕量,始終保持帶給用戶的漸進(jìn)式體感,不需要一上來就了解全部 API、相關(guān)設(shè)計(jì)概念,從頂層區(qū)分我的場景屬于哪類,該用哪個(gè) API,而是隨著場景的深入,發(fā)現(xiàn)那個(gè)最合適的 API/選項(xiàng)就在那里

能從文檔夠明顯地感受到這種差異,例如,Next.js 介紹 ISR 的地方將用戶指引到與之關(guān)聯(lián)的 SSR 帶靜態(tài)緩存模式:

Incremental Static Regeneration

With getStaticProps you don’t have to stop relying on dynamic content, as static content can also be dynamic. Incremental Static Regeneration allows you to update existing pages by re-rendering them in the background as traffic comes in.

This works perfectly with fallback: true. Because now you can have a list of posts that’s always up to date with the latest posts, and have a blog post page that generates blog posts on-demand, no matter how many posts you add or update.

積分、互動(dòng)式新手教程

這一點(diǎn)算作文檔設(shè)計(jì)技巧(文檔,當(dāng)然也要有設(shè)計(jì)),看過許多官方文檔/教程,留下深刻印象的只有 3 個(gè):

  • Redux 文檔:故事性文檔,手把手一點(diǎn)點(diǎn)把 redux 設(shè)計(jì)出來,讀起來根本停不下來
  • Electron Demo App:交互式文檔,準(zhǔn)確地說是帶完整文檔的 Demo,在體驗(yàn) Demo App 的同時(shí)了解相關(guān)特性用法,是比React 在做中學(xué)更偷懶的辦法了
  • Next.js 教程:積分、互動(dòng)式新手教程,幾十頁的教程一口氣看完

P.S.Redux 文檔指的是2017 年的版本,現(xiàn)在貌似改過許多版,讀著很差勁了(這么點(diǎn)兒概念怎么能整出來那么多文檔)

積分、互動(dòng)式新手教程威力大到什么程度?

讓我能在困到迷糊的狀態(tài)下堅(jiān)持看完教程的全部內(nèi)容,答對所有測試題目,積滿 500 分(當(dāng)然,不用幻想,全對是沒有任何獎(jiǎng)勵(lì)的),事后回想起來也覺得不可思議,其中的技巧在于:

  • 教程與文檔分離:導(dǎo)航欄一級菜單明確區(qū)分 Docs 與 Learn,教程中的部分概念有鏈到文檔,但不看完全也完全跟得上
  • 積分:教程醒目位置置頂展示獲得積分,每點(diǎn)一篇加分
  • 互動(dòng):關(guān)鍵章節(jié)有測試題,答對題目也加分,總積分可分享社交平臺(Twitter)

如此看來,在文檔中融入少量在線教育的成熟模式,可能效果極佳

默認(rèn)提供最佳實(shí)踐

讀過體驗(yàn)科技與好的產(chǎn)品,對其中玉伯提出的默認(rèn)好用印象很深,而 Next.js 算是默認(rèn)好用在框架設(shè)計(jì)上的一個(gè)真實(shí)案例

例如:

  • Link 自動(dòng)預(yù)加載
  • Image 自動(dòng)懶加載
  • “自動(dòng)”采用最佳渲染模式:這個(gè)自動(dòng)不同于前兩個(gè),強(qiáng)調(diào)的是框架角度對用戶按需使用特性的回應(yīng),由框架來判斷渲染模式(該走 SSR 還是 SSG),而無需用戶顯式指定/切換

從生產(chǎn)活動(dòng)的角度來看,最佳實(shí)踐本就應(yīng)該是默認(rèn)提供的,將新出現(xiàn)的最佳實(shí)踐不斷地下沉到環(huán)境層,就像 npm package、ES Module、Babel 等,如今的前端開發(fā)者已經(jīng)幾乎不需要關(guān)心這些曾經(jīng)的最佳實(shí)踐

僅從框架設(shè)計(jì)角度而言,默認(rèn)好用要求在提供最佳實(shí)踐的基礎(chǔ)上更進(jìn)一步,要把最佳實(shí)踐做沒,讓使用者能夠偷懶地以為一切本該如此。因此,最佳實(shí)踐只是一個(gè)臨時(shí)態(tài),尚未形成最佳實(shí)踐的部分才是開發(fā)者需要關(guān)心,并體現(xiàn)差異化競爭力的地方,一旦形成廣泛認(rèn)同的最佳實(shí)踐,就應(yīng)該沉淀成為默認(rèn)的基礎(chǔ)設(shè)施,開發(fā)者無需關(guān)心即可獲得這些最佳實(shí)踐帶來的種種好處

從尚未形成最佳實(shí)踐,到提供最佳實(shí)踐,到默認(rèn)提供最佳實(shí)踐,這 3 個(gè)階段可以通過一個(gè)圖片懶加載的示例來理解:

  1. // 第一階段:尚未形成最佳實(shí)踐 
  2. scroll 
  3. IntersectionObserver 
  4. // 業(yè)務(wù)各自實(shí)現(xiàn),不存在用法示例 
  5.  
  6. // 第二階段:提供最佳實(shí)踐 
  7. React Lazy Load Component 
  8. // 用法示例 
  9. <LazyLoad height={683} offsetTop={200}> 
  10.   <img src='http://apod.nasa.gov/apod/image/1502/2015_02_20_conj_bourque1024.jpg' /> 
  11. </LazyLoad> 
  12.  
  13. // 第三階段:默認(rèn)提供最佳實(shí)踐 
  14. next/image 
  15. // 用法示例 
  16. <Image 
  17.   src="/me.png" 
  18.   alt="Picture of the author" 
  19.   layout="fill" 
  20. /> 

第三階段與第二階段的區(qū)別在于,開發(fā)者不必關(guān)心哪個(gè)組件能夠提供懶加載功能(選擇最佳實(shí)踐),直接使用組件庫中最普通的 Image 組件,該有的功能自然就有,而懶加載只是其中一項(xiàng)

向 Serverless 延伸

Serverless 浪潮之下,前端生態(tài)也正在發(fā)生著一些變化,涌現(xiàn)出各式各樣的一體化應(yīng)用:

  • 以前端項(xiàng)目/后端項(xiàng)目為主體的一體化應(yīng)用:如 Midway Serverless,支持集成 React、Vue 等前端項(xiàng)目
  • 以 SSR 為主體的一體化應(yīng)用:如 Next.js,支持將 SSR 和數(shù)據(jù)接口(API endpoints)部署成 Serverless Functions

Next.js 提供 SSR 支持,本就需要服務(wù)端環(huán)境,Serverless 的興起很好地解決了 SSR 渲染服務(wù)的運(yùn)維問題,因此,其 Vercel 平臺默認(rèn)支持以 Serverless Functions 的形式部署 SSR 服務(wù)與 API:

Pages that use Server-Side Rendering and API routes will automatically become isolated Serverless Functions. This allows page rendering and API requests to scale infinitely.

諸如此類的一體化應(yīng)用雖未形成最佳實(shí)踐,但傳統(tǒng)的前端框架正在歷經(jīng)變革。也許,在未來的某一天,取而代之的是與 Serverless 技術(shù)充分融合的一體化應(yīng)用框架,Universal 體系大行其道也未可知。

原文鏈接:https://mp.weixin.qq.com/s/F_4yg-0hsX0PSQ1oEOopZg

 

責(zé)任編輯:武曉燕 來源: 前端向后
相關(guān)推薦

2024-09-20 15:37:02

2024-09-18 15:58:05

2025-03-31 00:00:02

2024-12-13 08:37:32

2025-04-08 08:12:26

Next.js組件ChatGPT

2025-02-03 00:00:35

2024-04-01 07:58:49

Next.js 14ReactWeb應(yīng)用

2013-06-25 11:06:51

編程技巧蘋果

2024-11-25 07:39:48

2024-05-09 09:01:03

2025-01-17 09:29:42

2024-07-31 08:38:36

2024-04-28 10:56:34

Next.jsWeb應(yīng)用搜索引擎優(yōu)化

2024-09-04 10:27:53

2024-02-05 11:55:41

Next.js開發(fā)URL

2024-03-05 19:17:37

2020-12-14 11:40:27

Next.js SSRReact

2025-03-06 00:00:00

2024-12-16 08:40:51

2024-03-29 08:32:01

Node.jsNext.js組件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號