整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Next.js 14 初學(xué)者指南 (一)

          Next.js 14 初學(xué)者指南 (一)

          當(dāng)今快速發(fā)展的網(wǎng)站開發(fā)領(lǐng)域,Next.js以其獨(dú)特的優(yōu)勢和便捷的功能,成為了前端開發(fā)者的新寵。Next.js是一個(gè)開源的JavaScript框架,它建立在流行的JavaScript庫React之上,專為構(gòu)建用戶界面而設(shè)計(jì)。作為一個(gè)專門用于構(gòu)建網(wǎng)絡(luò)應(yīng)用程序的框架,Next.js被廣泛描述為一個(gè)用于服務(wù)端渲染或靜態(tài)生成應(yīng)用程序的React框架。通過提供一系列工具和約定,Next.js極大地簡化了基于React的網(wǎng)絡(luò)應(yīng)用程序的開發(fā)過程,使得構(gòu)建快速、高性能且可擴(kuò)展的網(wǎng)站變得更加容易。

          Next.js提供的附加功能能夠讓你構(gòu)建生產(chǎn)就緒的應(yīng)用程序,這些功能包括路由、優(yōu)化渲染、數(shù)據(jù)獲取、打包、編譯等等。最吸引人的一點(diǎn)是,使用Next.js時(shí),你不需要安裝額外的包,因?yàn)镹ext.js提供了你所需的一切。要實(shí)現(xiàn)這些功能,只需遵循Next.js的觀點(diǎn)和約定即可。

          為什么學(xué)習(xí)Next.js對(duì)于前端開發(fā)者來說是一個(gè)明智的選擇

          1. 簡化路由:Next.js的文件系統(tǒng)基礎(chǔ)路由讓開發(fā)者輕松定義頁面和鏈接之間的關(guān)系。你無需額外配置,僅通過文件結(jié)構(gòu)就能自動(dòng)獲得強(qiáng)大的路由功能。
          2. API路由:Next.js允許你在同一個(gè)項(xiàng)目中創(chuàng)建API路由,這意味著你可以構(gòu)建前后端緊密集成的應(yīng)用程序,無需擔(dān)心跨域請(qǐng)求或配置復(fù)雜的后端服務(wù)。
          3. 雙重渲染優(yōu)勢:無論是客戶端渲染還是服務(wù)端渲染,Next.js都能提供支持,讓你根據(jù)項(xiàng)目需求和頁面特性選擇最合適的渲染方式。
          4. 數(shù)據(jù)獲取:Next.js提供了靜態(tài)生成和服務(wù)端渲染的數(shù)據(jù)獲取方法,如getStaticProps和getServerSideProps,讓數(shù)據(jù)管理變得簡單高效。
          5. 樣式方便:Next.js支持CSS模塊,使得組件級(jí)樣式變得簡單,同時(shí)也支持其他流行的CSS-in-JS庫,如styled-components,讓你能以更靈活的方式定義樣式。
          6. 優(yōu)化:Next.js對(duì)圖片、表單和腳本提供了自動(dòng)優(yōu)化,比如圖片懶加載和自動(dòng)壓縮,提升了網(wǎng)站的性能和加載速度。
          7. 開發(fā)和生產(chǎn)構(gòu)建系統(tǒng):Next.js提供了針對(duì)開發(fā)和生產(chǎn)環(huán)境優(yōu)化的構(gòu)建系統(tǒng),使得部署和測試變得更加高效。

          Next.js的一些核心優(yōu)勢

          1. 服務(wù)端渲染(SSR):Next.js支持服務(wù)端渲染,這意味著可以在服務(wù)器上預(yù)渲染頁面,然后將完全形成的HTML發(fā)送給客戶端。這種方式不僅提高了性能,還有助于改善SEO,因?yàn)樗阉饕婵梢宰ト〉酵暾捻撁鎯?nèi)容。
          2. 靜態(tài)站點(diǎn)生成(SSG):Next.js支持靜態(tài)站點(diǎn)生成,允許你在構(gòu)建時(shí)預(yù)渲染整個(gè)頁面。這種方式使頁面加載時(shí)間極快,非常適合內(nèi)容不經(jīng)常變化的場景。
          3. API路由:Next.js允許你在應(yīng)用程序內(nèi)創(chuàng)建API端點(diǎn),這樣你就可以在同一個(gè)代碼庫中構(gòu)建前端和后端,簡化了開發(fā)流程并提高了項(xiàng)目的一致性。
          4. 自動(dòng)代碼拆分:Next.js會(huì)自動(dòng)將你的JavaScript代碼分割成更小、優(yōu)化后的包。這樣做可以通過減少初始頁面加載時(shí)需要加載的代碼量來提高性能。
          5. 圖像優(yōu)化:Next.js內(nèi)置了對(duì)圖像優(yōu)化和高效服務(wù)的支持,通過如自動(dòng)大小調(diào)整、懶加載等特性,幫助提升性能和用戶體驗(yàn)。
          6. 基于文件的路由:Next.js采用基于文件的路由方式,使得路由變得簡單直觀。在pages目錄中創(chuàng)建文件,即可自動(dòng)為應(yīng)用生成路由。

          通過這些特性,Next.js為開發(fā)者提供了一個(gè)功能豐富、靈活且高效的平臺(tái),用于構(gòu)建各種規(guī)模和復(fù)雜度的Web應(yīng)用。無論是企業(yè)級(jí)應(yīng)用、電商網(wǎng)站還是個(gè)人博客,Next.js都能夠提供強(qiáng)大的支持,使得Web開發(fā)更加簡單、快捷,并且能夠達(dá)到高性能的要求。學(xué)習(xí)和掌握Next.js,無疑會(huì)讓你在現(xiàn)代Web開發(fā)的道路上更加得心應(yīng)手。

          創(chuàng)建一個(gè)新的Next.js項(xiàng)目的步驟

          打開你的命令行工具(如終端、命令提示符或PowerShell),并執(zhí)行以下命令,記得將<app-name>替換為你的項(xiàng)目名稱:

          npx create-next-app@latest <app-name>

          這個(gè)命令會(huì)自動(dòng)從npm下載并執(zhí)行create-next-app腳本,創(chuàng)建一個(gè)使用最新版本的Next.js的新項(xiàng)目。在這個(gè)過程中,腳本可能會(huì)詢問你是否想要配置TypeScript、ESLint或Tailwind CSS等選項(xiàng)。根據(jù)你的項(xiàng)目需求,跟隨提示進(jìn)行選擇。

          項(xiàng)目創(chuàng)建完成后,通過以下命令切換到項(xiàng)目目錄:

          cd <app-name>

          然后,啟動(dòng)開發(fā)服務(wù)器:

          npm run dev

          執(zhí)行此命令后,Next.js會(huì)啟動(dòng)一個(gè)本地開發(fā)服務(wù)器,并且通常會(huì)自動(dòng)打開你的默認(rèn)網(wǎng)頁瀏覽器顯示你的新Next.js應(yīng)用。如果沒有自動(dòng)打開,你可以手動(dòng)訪問http://localhost:3000來查看你的應(yīng)用。

          Routing

          在Next.js中,路由是構(gòu)建Web應(yīng)用程序的基礎(chǔ)之一,其獨(dú)特的基于文件系統(tǒng)的路由機(jī)制為開發(fā)者提供了高效且直觀的頁面管理方式。通過簡單地在代碼庫中添加文件和文件夾,你可以定義用戶可以在瀏覽器中訪問的URL路徑。下面是幾個(gè)關(guān)于Next.js路由的學(xué)習(xí)場景,讓我們更深入地了解如何在Next.js應(yīng)用中實(shí)現(xiàn)和管理路由。

          場景1:訪問根目錄

          當(dāng)用戶訪問根目錄(即localhost:3000)時(shí),顯示主頁。你可以通過在src/app目錄下創(chuàng)建page.tsx文件來實(shí)現(xiàn)這一點(diǎn)。

          // src/app/page.tsx
          
          export default function Home() {
              return <h1>Home Page</h1>;
          }
          

          這段代碼定義了一個(gè)簡單的React組件,當(dāng)用戶訪問應(yīng)用的根目錄時(shí),將展示“Home Page”。

          場景2:訪問/about頁面

          當(dāng)用戶訪問localhost:3000/about時(shí),顯示關(guān)于頁面。在src/app/about目錄下創(chuàng)建page.tsx文件來實(shí)現(xiàn)。

          // src/app/about/page.tsx
          
          export default function About() {
              return <h1>About Page</h1>;
          }
          

          場景3:嵌套路由

          Next.js允許通過在文件夾內(nèi)創(chuàng)建文件夾來創(chuàng)建路由層次結(jié)構(gòu)。

          // src/app/blog/page.tsx
          
          export default function Blog() {
              return <h1>Blog Page</h1>;
          }
          
          // src/app/blog/first/page.tsx
          
          export default function FirstBlog() {
              return <h1>First Blog Page</h1>;
          }
          

          這種方式適用于簡單的應(yīng)用程序結(jié)構(gòu),但對(duì)于復(fù)雜的應(yīng)用程序可能不是最佳選擇。

          場景4:動(dòng)態(tài)路由

          動(dòng)態(tài)路由允許基于URL中提供的參數(shù)動(dòng)態(tài)生成頁面。這意味著,你無需為每個(gè)可能的路由創(chuàng)建單獨(dú)的靜態(tài)頁面,而是可以使用動(dòng)態(tài)路由來處理URL中的模式或參數(shù)。

          // src/app/products/[productId]/page.tsx
          
          export default function ProductDetails({ params }: { params: { productId: string }; }) {
              return (
                  <>
                      <h1>Details about product {params.productId}</h1>
                  </>
              );
          }
          

          all segments

          在Next.js中,"Catch all"路由是一種強(qiáng)大的路由特性,它允許你匹配包括零個(gè)、一個(gè)或多個(gè)路徑段的路由。這種方式非常適用于當(dāng)你需要構(gòu)建像文檔頁面這樣的復(fù)雜和靈活的路由結(jié)構(gòu)時(shí)。通過使用雙括號(hào)[[...slug]]語法,你可以創(chuàng)建一個(gè)能夠捕獲所有傳入請(qǐng)求的動(dòng)態(tài)路由,并且根據(jù)URL的不同部分呈現(xiàn)不同的內(nèi)容。

          示例解讀

          在提供的示例中,我們創(chuàng)建了一個(gè)Docs組件,它利用"catch all"路由來展示文檔頁面。這個(gè)組件能夠根據(jù)URL中slug參數(shù)的不同,渲染出不同的文檔內(nèi)容。這里的slug是一個(gè)數(shù)組,它包含了URL中捕獲的所有動(dòng)態(tài)段。

          // src/app/docs/[[...slug]]/page.tsx
          
          export default function Docs({params}: {
              params: {
                  slug: string[];
              };
          }) {
              // 檢查slug參數(shù)的長度,以決定渲染哪種內(nèi)容
              if (params.slug?.length===2) {
                  return <h1>Viewing docs for feature {params.slug[0]} and concept {params.slug[1]}</h1>;
              } else if (params.slug?.length===1) {
                  return <h1>Viewing docs for feature {params.slug[0]}</h1>;
              }
              // 如果沒有提供slug參數(shù),渲染默認(rèn)的文檔頁面
              return <h1>Docs Page</h1>;
          }
          • 當(dāng)slug參數(shù)長度為2時(shí),假設(shè)URL為/docs/feature1/concept1,則頁面將渲染:“Viewing docs for feature feature1 and concept concept1”。
          • 當(dāng)slug參數(shù)長度為1時(shí),如果URL為/docs/feature1,頁面將渲染:“Viewing docs for feature feature1”。
          • 如果沒有提供slug參數(shù),即訪問/docs,頁面將渲染默認(rèn)的文檔頁面:“Docs Page”。

          優(yōu)勢

          使用"catch all"路由的優(yōu)勢在于,它為構(gòu)建具有靈活路由需求的應(yīng)用程序(如文檔網(wǎng)站、博客平臺(tái)等)提供了簡單而強(qiáng)大的解決方案。開發(fā)者可以輕松地管理和展示變化多端的內(nèi)容,而無需為每個(gè)可能的URL變體單獨(dú)設(shè)置路由規(guī)則。這不僅提高了開發(fā)效率,也使得應(yīng)用架構(gòu)更加清晰和易于維護(hù)。

          創(chuàng)建404頁面

          在Next.js中處理404錯(cuò)誤頁面是一個(gè)簡單而直接的過程,通過定義一個(gè)特定的組件,你可以為用戶提供一個(gè)更友好的錯(cuò)誤提示頁面,而不是默認(rèn)的瀏覽器錯(cuò)誤頁面。這對(duì)于改善用戶體驗(yàn)和維持網(wǎng)站的專業(yè)形象非常重要。

          通過在src/app目錄下創(chuàng)建一個(gè)not-found.tsx文件,你可以定義一個(gè)NotFound組件,當(dāng)用戶嘗試訪問一個(gè)不存在的頁面時(shí),將顯示該組件。

          // src/app/not-found.tsx
          
          export default function NotFound() {
              return (
                  <>
                      <h2>Page not found</h2>
                      <p>Could not find requested resource</p>
                  </>
              );
          }
          

          在Next.js中,當(dāng)用戶嘗試訪問一個(gè)不存在的路由時(shí),Next.js會(huì)自動(dòng)查找并渲染pages/404.js或src/pages/404.js文件(取決于你的項(xiàng)目結(jié)構(gòu))。如果你在這些位置定義了自定義404頁面,Next.js將渲染你定義的頁面而不是默認(rèn)的404頁面。

          私有文件夾

          在Next.js中使用私有文件夾是管理項(xiàng)目文件結(jié)構(gòu)的一個(gè)高效方式,尤其適合于那些想要將UI邏輯與路由邏輯分離、維護(hù)項(xiàng)目內(nèi)部文件組織一致性、在代碼編輯器中排序和分組文件、以及避免未來Next.js文件命名規(guī)范可能帶來的命名沖突的開發(fā)者。通過簡單地在文件夾名稱前加上下劃線_,你可以輕松地創(chuàng)建私有文件夾,這些文件夾及其所有子文件夾都會(huì)被Next.js的路由系統(tǒng)自動(dòng)忽略。

          假設(shè)你有一些庫文件或者一些只供內(nèi)部使用的組件,你不希望這些文件或組件被當(dāng)作頁面對(duì)外提供服務(wù)。你可以將這些文件放在一個(gè)前綴為下劃線的文件夾中,比如_lib。

          // src/app/_lib/page.tsx
          
          export default function PrivateRoute() {
            return <h1>You can't view this in the browser</h1>;
          }
          

          在上面的例子中,盡管我們創(chuàng)建了page.tsx文件,由于它位于_lib文件夾下,訪問localhost:3000/_lib將會(huì)顯示404錯(cuò)誤,因?yàn)镹ext.js自動(dòng)將_lib及其子文件夾從路由系統(tǒng)中排除了。

          路由分組

          在Next.js中組織和管理路由時(shí),有時(shí)候我們需要邏輯上對(duì)路由進(jìn)行分組,而又不希望這種分組影響到URL路徑結(jié)構(gòu)。這種需求在實(shí)際開發(fā)中非常常見,例如,你可能想要將所有與身份驗(yàn)證相關(guān)的頁面(如登錄、注冊(cè)、忘記密碼等)放在同一個(gè)文件夾下以提高開發(fā)體驗(yàn),但又不想在URL中體現(xiàn)這種文件結(jié)構(gòu)。

          使用路由分組解決問題

          Next.js提供了一種簡便的方法來實(shí)現(xiàn)這一點(diǎn):路由分組。通過在文件夾名周圍添加括號(hào),你可以告訴Next.js這個(gè)文件夾是用于邏輯分組的,并且不應(yīng)該影響到URL的結(jié)構(gòu)。

          例如,如果不使用路由分組,你可能會(huì)將登錄頁面放在/pages/auth/login.tsx,這將導(dǎo)致頁面的URL為localhost:3000/auth/login。但是,如果你想要保持login頁面的URL為localhost:3000/login,同時(shí)又想在項(xiàng)目文件中將這個(gè)頁面放在auth分組下,你可以通過路由分組來實(shí)現(xiàn)。

          實(shí)現(xiàn)路由分組

          要實(shí)現(xiàn)路由分組,只需要將相關(guān)的文件夾用括號(hào)括起來。以下是具體操作步驟:

          1. 創(chuàng)建分組文件夾:將auth文件夾更名為(auth)。
          2. 移動(dòng)頁面到分組文件夾:將login.tsx、register.tsx和forgot-password.tsx等頁面移動(dòng)到(auth)文件夾中。

          通過這種方式,login頁面的物理路徑可能是/pages/(auth)/login.tsx,但是在瀏覽器中訪問這個(gè)頁面的URL將會(huì)是localhost:3000/login,而不是localhost:3000/auth/login。

          路由分組的好處

          • 改善項(xiàng)目結(jié)構(gòu):路由分組允許開發(fā)者根據(jù)邏輯功能對(duì)文件和路由進(jìn)行分組,而不必?fù)?dān)心這種組織結(jié)構(gòu)會(huì)對(duì)URL路徑造成影響,從而使項(xiàng)目文件結(jié)構(gòu)更清晰、更有組織。
          • 提升開發(fā)體驗(yàn):對(duì)于開發(fā)者來說,能夠在不改變URL結(jié)構(gòu)的情況下邏輯性地組織路由和頁面,可以大大提升開發(fā)體驗(yàn)。
          • 增加靈活性:這種分組方式提供了額外的靈活性,讓開發(fā)者可以根據(jù)需要更自由地組織項(xiàng)目文件,而不受URL路徑限制。

          通過利用Next.js的路由分組功能,你可以在確保URL路徑簡潔的同時(shí),對(duì)項(xiàng)目中的文件和路由進(jìn)行有效的邏輯分組,這對(duì)于大型項(xiàng)目的開發(fā)和維護(hù)來說尤為重要。

          Layouts

          在構(gòu)建Web應(yīng)用時(shí),常常需要某些UI元素(如頭部導(dǎo)航和底部信息)在多個(gè)頁面間共享。這種需求通過使用布局(Layouts)來實(shí)現(xiàn)最為高效。布局允許開發(fā)者定義一個(gè)組件作為頁面的共享結(jié)構(gòu),然后將特定的頁面內(nèi)容注入到這個(gè)結(jié)構(gòu)中。Next.js通過支持布局,使得管理和重用頁面結(jié)構(gòu)變得簡單。

          根布局(Root Layout)

          根布局是應(yīng)用于所有路由的布局。你可以創(chuàng)建一個(gè)layout.js或layout.tsx文件來定義根布局,然后在其中包括所有頁面共享的元素,如頭部和底部。根布局組件應(yīng)該接受一個(gè)children屬性,這個(gè)屬性在渲染時(shí)會(huì)被填充為子頁面。

          // 示例:定義根布局
          export default function RootLayout({
            children,
          }: {
            children: React.ReactNode
          }) {
            return (
              <html lang="en">
                <body>
                  <header>
                    <p>Header</p>
                  </header>
            
                  {children}
               
                  <footer>
                    <p>Footer</p>
                  </footer>
                </body>
              </html>
            );
          }
          

          嵌套布局(Nested Layout)

          嵌套布局用于特定的路由段,只有當(dāng)這些路由段處于活動(dòng)狀態(tài)時(shí),定義在內(nèi)部的布局才會(huì)被渲染。通過在特定文件夾下定義layout.js(例如app/dashboard/layout.js),你可以為那個(gè)路由段及其子路由提供專用的布局。

          // 示例:定義特定路由段的嵌套布局
          export default function DashboardLayout({
            children,
          }: {
            children: React.ReactNode
          }) {
            return (
              <div>
                  <nav>
                    <p>Dashboard Navigation</p>
                  </nav>
          
                  {children}
              </div>
            );
          }
          

          這種方式允許你為應(yīng)用中的不同部分定義不同的布局結(jié)構(gòu),如儀表板、博客部分等,每個(gè)部分都可以有自己的頭部導(dǎo)航、側(cè)邊欄或其他共享元素。

          使用布局的好處

          • 一致性:通過使用布局,你可以確保應(yīng)用中的不同頁面共享相同的結(jié)構(gòu),這有助于保持界面的一致性。
          • 重用性:布局允許你在多個(gè)頁面間重用相同的UI結(jié)構(gòu),減少重復(fù)的代碼。
          • 可維護(hù)性:將共享元素放在布局中可以簡化頁面組件,使其更專注于頁面特定內(nèi)容的渲染,從而提高代碼的可維護(hù)性。

          使用根布局和嵌套布局,你可以靈活地定義應(yīng)用的頁面結(jié)構(gòu),同時(shí)保持代碼的清晰和組織性。這是構(gòu)建大型應(yīng)用時(shí)管理頁面布局的一種高效方法。

          結(jié)束

          在今天的文章中,我們一起探索了Next.js這個(gè)強(qiáng)大的JavaScript框架,從基本概念到路由、布局以及私有文件夾的高級(jí)特性,每一點(diǎn)都旨在幫助你更好地理解如何利用Next.js構(gòu)建高性能、易于維護(hù)的現(xiàn)代Web應(yīng)用。無論你是剛開始接觸Web開發(fā)的新手,還是希望提升項(xiàng)目質(zhì)量的資深開發(fā)者,Next.js都提供了豐富的功能和靈活性,以滿足不同的開發(fā)需求。

          我們的探索之旅還遠(yuǎn)沒有結(jié)束。在下篇文章中,我將繼續(xù)深入分享Next.js的更多精彩內(nèi)容,每一篇文章都旨在為你揭開Next.js高效開發(fā)的更多秘密,助你在Web開發(fā)的道路上更加得心應(yīng)手。

          別忘了關(guān)注「前端達(dá)人」,這里不僅有深入淺出的技術(shù)文章,還有最新的前端趨勢解讀,幫助你保持技術(shù)的前瞻性和競爭力。你的關(guān)注、點(diǎn)贊和轉(zhuǎn)發(fā)是對(duì)我最大的支持,也是我持續(xù)分享高質(zhì)量內(nèi)容的動(dòng)力。

          著現(xiàn)代Web應(yīng)用的發(fā)展,用戶界面變得越來越復(fù)雜,同時(shí)用戶對(duì)應(yīng)用的響應(yīng)速度和互動(dòng)性有著更高的期待。在這樣的背景下,Next.js 作為一個(gè)前沿的React框架,提供了一系列高級(jí)功能來滿足開發(fā)者的需求,今天我們來介紹 Next.js 14 的第二部分。

          推薦閱讀

          Next.js 14 初學(xué)者指南 (一)

          Metadata:在Next.js項(xiàng)目中優(yōu)化SEO

          在當(dāng)今這個(gè)信息爆炸的時(shí)代,擁有一個(gè)高可見度的網(wǎng)站已成為許多企業(yè)和個(gè)人的追求。搜索引擎優(yōu)化(SEO)是實(shí)現(xiàn)這一目標(biāo)的重要手段。為了讓你的Next.js應(yīng)用更好地被搜索引擎發(fā)現(xiàn),Next.js引入了一個(gè)非常實(shí)用的功能——元數(shù)據(jù)API。通過這個(gè)API,你可以為每個(gè)頁面定義元數(shù)據(jù),確保當(dāng)你的頁面被分享或索引時(shí)顯示準(zhǔn)確、相關(guān)的信息。

          1. 靜態(tài)元數(shù)據(jù)的配置

          靜態(tài)元數(shù)據(jù)是指在構(gòu)建時(shí)確定的有關(guān)頁面的信息,并且在運(yùn)行時(shí)不會(huì)改變。這些元數(shù)據(jù)與特定頁面相關(guān)聯(lián),可以包括標(biāo)題和描述等數(shù)據(jù)。例如,如果你有一個(gè)關(guān)于頁面,你可以這樣配置它的靜態(tài)元數(shù)據(jù):

          //src/app/about/page.tsx
          
          export const metadata={
            title: "關(guān)于我",
          };
          
          export default function About() {
            return <h1>關(guān)于我</h1>;
          }
          

          通過這種方式,當(dāng)你的“關(guān)于我”頁面被搜索引擎索引或被分享到社交媒體時(shí),其標(biāo)題會(huì)正確地顯示為“關(guān)于我”。

          2. 動(dòng)態(tài)生成的元數(shù)據(jù)

          與靜態(tài)元數(shù)據(jù)不同,動(dòng)態(tài)元數(shù)據(jù)允許你根據(jù)運(yùn)行時(shí)的動(dòng)態(tài)數(shù)據(jù)或條件生成頁面的元數(shù)據(jù)。這對(duì)于那些內(nèi)容經(jīng)常變化或依賴于用戶輸入的頁面非常有用。比如,你有一個(gè)展示產(chǎn)品詳情的頁面,可以這樣配置其元數(shù)據(jù):

          import { Metadata } from "next";
          
          type Props={
            params: {
               productId: string;
            };
          };
          
          export const generateMetadata=({ params }: Props ): Metadata=> {
            return {
                title: `產(chǎn)品 ${params.productId} 的詳情`,
            };
          };
          
          export default function ProductDetails({ params }: Props) {
              return <h1>產(chǎn)品 {params.productId} 的詳情</h1>;
          }
          

          甚至,你可以使用異步函數(shù)來生成元數(shù)據(jù),這在你需要從數(shù)據(jù)庫或API獲取數(shù)據(jù)時(shí)特別有用:

          export const generateMetadata=async ({ params }: Props): Promise<Metadata>=> {
              const title=await new Promise((resolve)=> {
                setTimeout(()=> {
                  resolve(`產(chǎn)品 ${params.productId}`);
                }, 100);
            });
            return { title: `產(chǎn)品 ${title} 的詳情`, };
          };
          

          3、元數(shù)據(jù)規(guī)則

          • layout.tsx 和 page.tsx 文件都可以導(dǎo)出元數(shù)據(jù)。如果在布局中定義,則適用于該布局中的所有頁面;如果在頁面中定義,則僅適用于該頁面。
          • 元數(shù)據(jù)按順序讀取,從根級(jí)別到最終頁面級(jí)別。
          • 如果同一路由的多個(gè)位置有元數(shù)據(jù),它們會(huì)被合并,但頁面元數(shù)據(jù)會(huì)替換布局元數(shù)據(jù)(如果它們有相同的屬性)。

          4、title metadata

          關(guān)于元數(shù)據(jù)中的title屬性,這是一個(gè)非常關(guān)鍵的部分,它直接影響到你的頁面在搜索引擎中的顯示標(biāo)題以及用戶在瀏覽器標(biāo)簽頁中看到的內(nèi)容。title可以是一個(gè)字符串或者是一個(gè)對(duì)象,這取決于你想如何控制標(biāo)題的顯示。

          當(dāng)你在layout.tsx文件中定義元數(shù)據(jù)時(shí),title字段提供了幾個(gè)有趣的選項(xiàng)來增加靈活性:

          //layout.tsx
          
          export const metadata: Metadata={
            title: {
              absolute: "",
              default: "",
              template: "%s | 網(wǎng)站名稱",
            },
            description: "",
          };
          
          • absolute:這是一個(gè)備選項(xiàng),用于設(shè)置一個(gè)絕對(duì)的標(biāo)題,通常在這里不會(huì)設(shè)置值。
          • default:這個(gè)值將作為默認(rèn)標(biāo)題,即如果子路由沒有指定自己的標(biāo)題,那么就會(huì)使用這個(gè)默認(rèn)值。
          • template:這是一個(gè)模板字符串,子路由的標(biāo)題名將替換%s。這樣,你可以很容易地為站點(diǎn)中的每個(gè)頁面添加一個(gè)統(tǒng)一的后綴或前綴,比如網(wǎng)站名稱或者是一個(gè)關(guān)鍵的標(biāo)識(shí)符。

          這個(gè)功能特別適合那些頁面結(jié)構(gòu)復(fù)雜、需要精細(xì)控制每個(gè)頁面標(biāo)題的網(wǎng)站。通過在不同級(jí)別(全局布局、頁面布局、單獨(dú)頁面)精心設(shè)計(jì)title的設(shè)置,可以確保無論用戶進(jìn)入網(wǎng)站的哪個(gè)部分,都能通過標(biāo)題快速了解內(nèi)容,并通過模板確保網(wǎng)站的整體品牌一致性得到維護(hù)。

          舉個(gè)例子,如果你的一個(gè)頁面沒有指定特定的標(biāo)題,那么它就會(huì)使用default中的值。而當(dāng)頁面指定了自己的標(biāo)題時(shí),template中定義的模式就會(huì)發(fā)揮作用,自動(dòng)將頁面的標(biāo)題和網(wǎng)站名稱進(jìn)行組合,形成一個(gè)既清晰又具有品牌特色的標(biāo)題展示。

          這種靈活性和自動(dòng)化的結(jié)合,不僅使得SEO優(yōu)化變得簡單,而且還能在提升用戶體驗(yàn)的同時(shí),加強(qiáng)網(wǎng)站品牌的影響力。

          通過精心設(shè)計(jì)每個(gè)頁面的元數(shù)據(jù),不僅可以提高網(wǎng)站的搜索引擎排名,還能提升用戶體驗(yàn),增加點(diǎn)擊率。在社交媒體時(shí)代,一個(gè)吸引人的頁面標(biāo)題和描述可以大大增加內(nèi)容的分享率。而Next.js提供的元數(shù)據(jù)API,讓這一切變得簡單而直接。

          Navigation:使用 Link 組件進(jìn)行導(dǎo)航

          在構(gòu)建一個(gè)動(dòng)態(tài)且互動(dòng)性強(qiáng)的網(wǎng)站時(shí),頁面間的導(dǎo)航是不可或缺的一環(huán)。Next.js 為此提供了非常便利的解決方案——Link 組件和 useRouter 鉤子,讓客戶端導(dǎo)航變得既簡單又高效。

          Link 組件是 Next.js 中用于實(shí)現(xiàn)路由跳轉(zhuǎn)的主要方式,它基于 HTML 的 <a> 元素進(jìn)行了擴(kuò)展,使得在 Next.js 應(yīng)用中的路由之間進(jìn)行導(dǎo)航變得非常簡便。使用 Link 組件時(shí),你只需要導(dǎo)入它并指定 href 屬性為目標(biāo)路徑即可:

          import Link from "next/link";
          
          <Link href="/blog">博客</Link>

          Navigation:程序化導(dǎo)航

          有時(shí)候,我們需要在代碼中根據(jù)某些條件或邏輯來動(dòng)態(tài)導(dǎo)航到不同的頁面,這時(shí)就可以使用 Next.js 提供的 useRouter 鉤子。useRouter 允許你訪問路由對(duì)象,通過這個(gè)對(duì)象,你可以控制應(yīng)用的路由行為,例如進(jìn)行頁面跳轉(zhuǎn)。

          以下是一個(gè)使用 useRouter 進(jìn)行程序化導(dǎo)航的示例:

          import { useRouter } from "next/router";
          
          const MyComponent=()=> {
            const router=useRouter();
          
            const handleClick=()=> {
              console.log("下單");
              router.push("/"); // 使用 router.push 方法跳轉(zhuǎn)到首頁
            };
          
            return (
              <button onClick={handleClick}>下單</button>
            );
          }
          

          在這個(gè)例子中,當(dāng)用戶點(diǎn)擊“下單”按鈕時(shí),handleClick 函數(shù)會(huì)被觸發(fā),然后應(yīng)用會(huì)使用 router.push("/") 代碼來跳轉(zhuǎn)到首頁。這種方式非常適合在用戶完成某些操作后需要自動(dòng)跳轉(zhuǎn)頁面的場景。

          無論是通過 Link 組件還是 useRouter 鉤子進(jìn)行導(dǎo)航,Next.js 都為開發(fā)者提供了極大的便利和靈活性。通過這些工具,你可以輕松地在你的應(yīng)用中實(shí)現(xiàn)復(fù)雜的導(dǎo)航邏輯,為用戶提供流暢且富有互動(dòng)性的網(wǎng)頁體驗(yàn)。

          Templates(模板)

          在構(gòu)建現(xiàn)代Web應(yīng)用時(shí),開發(fā)者常常需要在多個(gè)頁面之間共享某些布局或樣式。Next.js的模板(Templates)功能就是為此而生。模板類似于布局(Layouts),它們都可以包裹每個(gè)子布局或頁面。但模板和布局在功能上有一定的差異,特別是在處理頁面導(dǎo)航時(shí)。

          模板的特性

          當(dāng)用戶在共享同一模板的不同路由之間導(dǎo)航時(shí),模板會(huì)呈現(xiàn)一些獨(dú)特的行為:

          • 重新掛載組件:每次導(dǎo)航到新路由時(shí),即使新舊路由共享相同的模板,該模板的一個(gè)新實(shí)例也會(huì)被掛載。
          • DOM元素重建:模板中的DOM元素會(huì)在每次導(dǎo)航時(shí)被重新創(chuàng)建,而不是復(fù)用。
          • 狀態(tài)不保留:由于模板重新掛載,任何在模板中維持的狀態(tài)都將丟失,每次導(dǎo)航都是從新的狀態(tài)開始。
          • 效果重新同步:React的效果(effects)會(huì)在每次導(dǎo)航時(shí)重新同步,意味著例如useEffect中的代碼會(huì)在每次模板掛載時(shí)執(zhí)行。

          定義模板

          定義模板非常簡單,你只需要?jiǎng)?chuàng)建一個(gè)默認(rèn)導(dǎo)出的React組件,這個(gè)組件可以從template.js或template.tsx文件中導(dǎo)出。這個(gè)組件通常會(huì)接受children作為其屬性,并在其內(nèi)部渲染這些子元素:

          export default function Template({ children }: { children: React.ReactNode }) {
            return <div>{children}</div>
          }

          模板使用場景

          模板特別適合于那些需要在多個(gè)頁面之間共享相同布局,但又希望在每次頁面跳轉(zhuǎn)時(shí)能夠完全重置狀態(tài)和DOM的場景。這可以確保用戶在不同頁面間導(dǎo)航時(shí),能夠獲得一致且干凈的體驗(yàn),而不必?fù)?dān)心前一個(gè)頁面的狀態(tài)影響到當(dāng)前頁面。

          通過明智地使用模板,你可以在保持代碼組織和復(fù)用性的同時(shí),為用戶提供流暢且一致的瀏覽體驗(yàn)。

          loading.tsx

          loading.tsx 文件在 Next.js 應(yīng)用中扮演著特別的角色,它允許開發(fā)者為特定路由段創(chuàng)建加載狀態(tài),這些加載狀態(tài)在內(nèi)容加載時(shí)展示給用戶。使用 loading.tsx 可以有效地提升用戶體驗(yàn),特別是在網(wǎng)絡(luò)環(huán)境較差或內(nèi)容較多需要較長時(shí)間加載的場景下。

          創(chuàng)建加載狀態(tài)

          在 loading.tsx 文件中,你可以定義一個(gè)或多個(gè)加載狀態(tài)的 React 組件。這些組件可以是簡單的動(dòng)畫,如旋轉(zhuǎn)的加載指示器,或者更復(fù)雜的占位符布局,如骨架屏。

          // loading.tsx
          
          export default function Loading() {
              return (
                  <div className="loading-container">
                      <p>內(nèi)容加載中,請(qǐng)稍候...</p>
                      {/* 這里可以添加加載動(dòng)畫或圖標(biāo) */}
                  </div>
              );
          }
          

          使用加載狀態(tài)

          當(dāng)用戶導(dǎo)航到一個(gè)新的路由段,而這個(gè)路由段的內(nèi)容還在加載時(shí),你定義的加載狀態(tài)會(huì)立即顯示給用戶。這提供了一個(gè)視覺反饋,讓用戶知道應(yīng)用正在響應(yīng)其操作,并且內(nèi)容正在積極加載中。這樣可以避免用戶在看到空白頁面時(shí)感到困惑或者認(rèn)為應(yīng)用出現(xiàn)了問題。

          提升用戶體驗(yàn)

          利用 loading.tsx 實(shí)現(xiàn)的加載狀態(tài)可以大大提升應(yīng)用的用戶體驗(yàn):

          • 減少等待感:通過立即提供反饋,用戶感知到的等待時(shí)間會(huì)減少,即使實(shí)際加載時(shí)間沒有變短。
          • 增強(qiáng)應(yīng)用感知速度:快速響應(yīng)用戶操作的應(yīng)用給人的感覺更快,即使是在加載較重的內(nèi)容時(shí)也不例外。
          • 保持用戶參與:加載狀態(tài)可以是創(chuàng)造性的,提供額外的視覺元素或信息,保持用戶的參與度,避免他們?cè)诩虞d過程中離開。

          在設(shè)計(jì)加載狀態(tài)時(shí),重要的是要保持它的簡潔和與應(yīng)用整體風(fēng)格的一致性。加載狀態(tài)不僅是一種功能性需求,也是提升品牌體驗(yàn)和應(yīng)用專業(yè)度的機(jī)會(huì)。

          error.tsx

          在構(gòu)建現(xiàn)代web應(yīng)用時(shí),有效地管理和響應(yīng)錯(cuò)誤是至關(guān)重要的。Next.js 通過文件系統(tǒng)層次結(jié)構(gòu)中的 error.tsx 文件,為開發(fā)者提供了一種靈活而強(qiáng)大的方式來創(chuàng)建和管理錯(cuò)誤UI,以及處理特定路由段的錯(cuò)誤。

          創(chuàng)建針對(duì)性的錯(cuò)誤UI

          通過在應(yīng)用的不同路由級(jí)別添加 error.tsx 文件,你可以為這些路由定制特定的錯(cuò)誤處理UI。這種方法使得在用戶遇到錯(cuò)誤時(shí),能夠展示更具體、更友好的錯(cuò)誤消息和恢復(fù)選項(xiàng),而不是一個(gè)通用的錯(cuò)誤頁面。

          // 使用 'use client' 來指明這些錯(cuò)誤組件必須是客戶端組件
          
          'use client';
          
          import { useEffect } from 'react';
          
          export default function Error({
            error,
            reset,
          }: {
            error: Error & { digest?: string };
            reset: ()=> void;
          }) {
            useEffect(()=> {
              // 將錯(cuò)誤記錄到錯(cuò)誤報(bào)告服務(wù)中
              console.error(error);
            }, [error]);
          
            return (
              <div>
                <h2>出錯(cuò)了!</h2>
                <button onClick={()=> reset()}>
                  重試
                </button>
              </div>
            );
          }
          
          

          隔離錯(cuò)誤影響

          將 error.tsx 文件放置于應(yīng)用的不同級(jí)別,能夠幫助你更精確地控制錯(cuò)誤的影響范圍。例如,在特定的路由段出現(xiàn)錯(cuò)誤時(shí),只有那部分內(nèi)容會(huì)展示錯(cuò)誤信息,應(yīng)用的其他部分仍然可以正常工作。這樣既提高了應(yīng)用的魯棒性,也優(yōu)化了用戶體驗(yàn)。

          錯(cuò)誤恢復(fù)功能

          在 error.tsx 中,你可以提供恢復(fù)功能,如重試按鈕,允許用戶嘗試從錯(cuò)誤中恢復(fù),而無需重新加載整個(gè)頁面。這種快速響應(yīng)錯(cuò)誤并嘗試恢復(fù)的能力,對(duì)于保持應(yīng)用的交互性和用戶滿意度至關(guān)重要。

          嵌套路由中的錯(cuò)誤處理

          通過在嵌套的文件夾結(jié)構(gòu)中不同級(jí)別放置 error.tsx 文件,你可以實(shí)現(xiàn)更細(xì)粒度的錯(cuò)誤處理。這意味著,你可以為應(yīng)用中的不同部分定制不同的錯(cuò)誤處理策略和UI,使錯(cuò)誤處理更加靈活和用戶友好。

          這種方法利用了Next.js的文件系統(tǒng)路由和組件模型,提供了一種既簡潔又強(qiáng)大的錯(cuò)誤處理機(jī)制,幫助開發(fā)者構(gòu)建更加可靠和用戶友好的應(yīng)用。

          Parallel Routes(插槽)

          Next.js 的并行路由是一種高級(jí)路由機(jī)制,允許在同一布局中同時(shí)渲染多個(gè)頁面,極大地增強(qiáng)了頁面布局和內(nèi)容管理的靈活性。通過使用名為“插槽(slots)”的功能,開發(fā)者可以以模塊化的方式組織內(nèi)容。

          定義插槽

          要定義一個(gè)插槽,我們使用 @folder 命名約定。然后,每個(gè)插槽作為屬性傳遞給其對(duì)應(yīng)的 layout.tsx 文件。

          以儀表盤為例,你可以使用并行路由同時(shí)渲染用戶、收入和通知頁面:

          // dashboard/layout.tsx
          
          export default function DashboardLayout({
              children,
              users,
              revenue,
              notifications
          }: {
              children: React.ReactNode;
              users: React.ReactNode;
              revenue: React.ReactNode;
              notifications: React.ReactNode;
          }) {
              return (
                <>
                  <div>{children}</div>
                  <div>{users}</div>
                  <div>{revenue}</div>
                  <div>{notifications}</div>
                </>
              );
          }
          

          并行路由的一個(gè)優(yōu)勢是它們能夠?qū)蝹€(gè)布局劃分為各種插槽,使代碼更易于管理。

          獨(dú)立的路由處理

          布局的每個(gè)插槽,例如用戶分析或收入指標(biāo),都可以有自己的加載和錯(cuò)誤狀態(tài)。在不同頁面部分以不同速度加載或遇到獨(dú)特錯(cuò)誤的場景中,這種細(xì)粒度的控制尤其有益。

          路由內(nèi)的子導(dǎo)航

          你的儀表盤的每個(gè)插槽都可以實(shí)質(zhì)上作為一個(gè)小應(yīng)用程序運(yùn)行,完備自己的導(dǎo)航和狀態(tài)管理。這在諸如儀表盤這樣的復(fù)雜應(yīng)用中特別有用,不同部分服務(wù)于不同的目的。

          //dashboard/@notifications/page.tsx
          
          export default function Notifications() {
            return (
              <div>通知</div>
              <Link href="/dashboard/">歸檔</Link>
            );
          };
          
          //dashboard/@notifications/archieved/page.tsx
          
          export default function ArchivedNotifications() {
            return (
              <div>歸檔通知</div>
              <Link href="/dashboard/">默認(rèn)</Link>
            );
          };
          

          這種結(jié)構(gòu)不僅提升了代碼的模塊化和可讀性,而且還增強(qiáng)了用戶界面的交互性,使用戶能夠在儀表盤的不同部分之間流暢地導(dǎo)航,同時(shí)各部分能夠獨(dú)立地加載和處理數(shù)據(jù)。這樣的設(shè)計(jì)思想,為構(gòu)建復(fù)雜且高效的Web應(yīng)用提供了新的可能性。

          結(jié)束

          通過今天的分享,我們了解了Next.js并行路由的強(qiáng)大之處,以及它如何使我們能夠構(gòu)建更加動(dòng)態(tài)和響應(yīng)式的Web應(yīng)用。這項(xiàng)技術(shù)不僅提高了應(yīng)用的性能和用戶體驗(yàn),還讓代碼的組織和維護(hù)變得更加高效。

          在這信息爆炸的時(shí)代,我始終致力于探索前端技術(shù)的最新動(dòng)態(tài),為你帶來更多的技術(shù)干貨。如果你對(duì)今天的內(nèi)容感興趣,不妨點(diǎn)贊、關(guān)注、轉(zhuǎn)發(fā),并在評(píng)論區(qū)留下你的看法和問題。我非常期待你的反饋和互動(dòng)!

          此外,不要忘了關(guān)注「前端達(dá)人」,我將不定期分享更多關(guān)于前端開發(fā)的技術(shù)文章、教程和最佳實(shí)踐。讓我們一起在前端的道路上不斷進(jìn)步,探索更多可能性!

          者|Next.js 團(tuán)隊(duì)

          譯者|無明

          出處丨前端之巔

          在經(jīng)過 26 次金絲雀發(fā)布和 340 萬次下載之后,近日,我們正式發(fā)布了 Next.js 7.0,新功能包括:

          • DX 改進(jìn):啟動(dòng)速度提高 57%,重新編譯速度提高 42%;
          • 使用 react-error-overlay 更好地報(bào)告錯(cuò)誤;
          • 編譯管道升級(jí):Webpack 4 和 Babel 7;
          • 標(biāo)準(zhǔn)化的動(dòng)態(tài)導(dǎo)入;
          • 靜態(tài) CDN 支持;
          • 較小的初始 HTML 載荷;
          • App 和 Page 之間的 React Context(服務(wù)器端渲染)。

          DX 改進(jìn)

          Next.js 的主要目標(biāo)之一是提供最佳的性能和開發(fā)者體驗(yàn)。最新版本為構(gòu)建和調(diào)試管道帶來了很多重大改進(jìn)。

          得益于 Webpack 4 和 Babel 7,以及我們對(duì)代碼庫做出的很多改進(jìn)和優(yōu)化,Next.js 現(xiàn)在在開發(fā)過程中的啟動(dòng)速度提高了 57%。

          我們新增了增量編譯緩存,讓變更代碼的構(gòu)建速度快了 40%。

          以下是我們收集的一些示例數(shù)據(jù):


          因?yàn)槭褂昧?webpackbar,在開發(fā)和構(gòu)建的同時(shí)可以看到更好的實(shí)時(shí)反饋:


          使用 react-error-overlay 更好地報(bào)告錯(cuò)誤

          準(zhǔn)確地渲染錯(cuò)誤對(duì)于良好的開發(fā)和調(diào)試體驗(yàn)來說是至關(guān)重要的。到目前為止,我們可以渲染錯(cuò)誤消息和堆棧跟蹤信息。我們?cè)诖嘶A(chǔ)上更進(jìn)一步,我們使用 react-error-overlay 來豐富堆棧跟蹤信息:

          • 準(zhǔn)確的服務(wù)器端和客戶端錯(cuò)誤位置;
          • 高亮顯示錯(cuò)誤來源;
          • 完整的堆棧跟蹤信息。

          這是之前和之后的錯(cuò)誤顯示比較:


          另外,借助 react-error-overlay,你只需單擊特定代碼塊就可以輕松打開文本編輯器。

          支持 Webpack 4

          從發(fā)布第一個(gè)版本以來,Next.js 一直使用 Webpack 來打包代碼和重用豐富的插件。Next.js 現(xiàn)在使用了最新的 Webpack 4,其中包含很多改進(jìn)和 bug 修復(fù)。

          • 支持.mjs 源文件;
          • 代碼拆分改進(jìn);
          • 更好的搖樹優(yōu)化(刪除未使用的代碼)支持。

          另一個(gè)新功能是支持 WebAssembly,Next.js 甚至可以進(jìn)行 WebAssembly 服務(wù)器渲染。

          這里有一個(gè)例子:

          https://github.com/zeit/next.js/tree/canary/examples/with-webassembly

          CSS 導(dǎo)入

          因?yàn)槭褂昧?Webpack 4,我們引入了一種從捆綁包中提取 CSS 的新方法,這個(gè)插件叫作 mini-extract-css-plugin(https://github.com/webpack-contrib/mini-css-extract-plugin)。

          mini-extract-css-plugin 提供了 @zeit/next-css、@zeit/next-less、@zeit/next-sass 和 @zeit/next-stylus。

          這些 Next.js 插件的新版本解決了與 CSS 導(dǎo)入相關(guān)的 20 個(gè)問題,例如,現(xiàn)在支持 import() 動(dòng)態(tài)導(dǎo)入 CSS:

          // components/my-dynamic-component.js
          import './my-dynamic-component.css'
          export default ()=> <h1>My dynamic component</h1>
          // pages/index.js
          import dynamic from 'next/dynamic'
          const MyDynamicComponent=dynamic(import('../components/my-dynamic-component'))
          export default ()=> <div>
           <MyDynamicComponent/>
          </div>
          

          一個(gè)重大改進(jìn)是現(xiàn)在不再需要在 pages/_document.js 中添加一下內(nèi)容:

          <link rel="stylesheet" href="/_next/static/style.css" />
          

          Next.js 會(huì)自動(dòng)注入這個(gè) CSS 文件。在生產(chǎn)環(huán)境中,Next.js 還會(huì)自動(dòng)向 CSS URL 中添加內(nèi)容哈希,當(dāng)文件發(fā)生變更時(shí),最終用戶就不會(huì)得到舊文件,并且能夠獲得不可變的永久緩存。

          簡而言之,要在 Next.js 項(xiàng)目中支持導(dǎo)入.css 文件,只需要在 next.config.js 中注冊(cè) withCSS 插件:

          const withCSS=require('@zeit/next-css')
          module.exports=withCSS({/* my next config */})
          

          標(biāo)準(zhǔn)化動(dòng)態(tài)導(dǎo)入

          從版本 3 開始,Next.js 就通過 next/dynamic 來支持動(dòng)態(tài)導(dǎo)入。

          作為這項(xiàng)技術(shù)的早期采用者,我們必須自己編寫解決方案來處理 import()。

          因此,Next.js 逐漸缺失 Webpack 后來引入的一些功能,包括 import()。

          例如,無法手動(dòng)命名和捆綁某些文件:

          import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library')
          

          另一個(gè)例子是在 next/dyanmic 模塊之外使用 import()。

          從 Next.js 7 開始,我們不再直接使用默認(rèn)的 import(),Next.js 為我們提供了開箱即用的 import() 支持。

          這個(gè)變更也是完全向后兼容的。使用動(dòng)態(tài)組件非常簡單:

          import dynamic from 'next/dynamic'
          const MyComponent=dynamic(import('../components/my-component'))
          export default ()=> {
           return <div>
           <MyComponent />
           </div>
          }
          

          這段代碼的作用是為 my-component 創(chuàng)建一個(gè)新的 JavaScript 文件,并只在渲染< MyComponent/>時(shí)加載它。

          最重要的是,如果沒有進(jìn)行渲染,< script>標(biāo)記就不會(huì)出現(xiàn)在初始 HTML 文檔中。

          為了進(jìn)一步簡化我們的代碼庫并利用優(yōu)秀的 React 生態(tài)系統(tǒng),在 Next.js 7 中,我們使用 react-loadable 重寫了 next/dynamic 模塊。這為動(dòng)態(tài)組件引入了兩個(gè)很棒的新特性:

          • 使用 next/dynamic 的 timeout 選項(xiàng)設(shè)置超時(shí);
          • 使用 next/dynamic 的 delay 選項(xiàng)設(shè)置組件加載延遲。例如,如果導(dǎo)入非常快,可以通過這個(gè)選項(xiàng)讓加載組件在渲染加載狀態(tài)之前等待一小段時(shí)間。

          支持 Babel 7

          Next.js 6 中就已經(jīng)引入了 Babel 7 測試版。后來 Babel 7 穩(wěn)定版本發(fā)布,現(xiàn)在,Next.js 7 正在使用這個(gè)新發(fā)布的穩(wěn)定版 Babel 7。

          一些主要特性:

          • Typescript 支持,在 Next.js 中可以使用 @zeit/next-
          • typescript;
          • 片段語法<>支持;
          • babel.config.js 支持;
          • 通過 overrides 屬性將預(yù)設(shè) / 插件應(yīng)用于文件或目錄的子集。

          如果你的 Next.js 項(xiàng)目中沒有自定義 Babel 配置,那么就不存在重大變更。

          但如果你具有自定義 Babel 配置,則必須將相應(yīng)的自定義插件 / 預(yù)設(shè)升級(jí)到最新版本。

          如果你從 Next.js 6 以下的版本升級(jí),可以使用 babel-upgrade 工具。

          除了升級(jí)到 Babel 7 之外,當(dāng) NODE_ENV 被設(shè)置為 test 時(shí),Next.js Babel 預(yù)設(shè)(next/babel)現(xiàn)在默認(rèn)將 modules 選項(xiàng)設(shè)置為 commonjs。

          這個(gè)配置選項(xiàng)通常是在 Next.js 項(xiàng)目中創(chuàng)建自定義.babelrc 的唯一理由:

          {
           "env": {
           "development": {
           "presets": ["next/babel"]
           },
           "production": {
           "presets": ["next/babel"]
           },
           "test": {
           "presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
           }
           }
          }
          

          使用 Next.js 7,這將變成:

          {
           "presets": ["next/babel"]
          }
          

          現(xiàn)在可以刪除.babelrc,因?yàn)樵跊]有 Babel 配置時(shí),Next.js 將自動(dòng)使用 next/babel。

          較小的初始 HTML 載荷

          Next.js 在預(yù)渲染 HTML 時(shí)會(huì)將頁面內(nèi)容放在< html>、< head>、< body>結(jié)構(gòu)中,并包含頁面所需的 JavaScript 文件。

          這個(gè)初始載荷之前約為 1.62kB。在 Next.js 7 中,我們優(yōu)化了初始 HTML 載荷,現(xiàn)在為 1.5kB,減少了 7.4%,讓頁面變得更加精簡。


          我們主要通過以下幾種方式來縮小文件:

          • 移除 __next-error div;
          • 內(nèi)聯(lián)腳本被最小化,在未來的版本中,它們將被完全移除;
          • 去掉未使用的 NEXT_DATA 屬性,例如 nextExport 和 assetPrefix 屬性。

          靜態(tài) CDN 支持

          在 Next.js 5 中,我們引入了 assetPrefix 支持,讓 Next.js 可以自動(dòng)從某個(gè)位置(通常是 CDN)加載資源。如果你的 CDN 支持代理,可以使用這種辦法。你可以像這樣請(qǐng)求資源:

          https://cdn.example.com/_next/static/<buildid>/pages/index.js
          

          通常,CDN 先檢查緩存中是否包含這個(gè)文件,否則直接從源中請(qǐng)求文件。

          不過,某些解決方案需要將目錄直接預(yù)先上傳到 CDN 中。這樣做的問題在于 Next.js 的 URL 結(jié)構(gòu)與.next 文件夾中的文件夾結(jié)構(gòu)不匹配。例如我們之前的例子:

          https://cdn.example.com/_next/static/<buildid>/pages/index.js
          // 映射到:
          .next/page/index.js
          

          在 Next.js 7 中,我們改變了.next 的目錄結(jié)構(gòu),讓它與 URL 結(jié)構(gòu)相匹配:

          https://cdn.example.com/_next/static/<buildid>/pages/index.js
          // 映射到:
          .next/static/<buildid>/pages/index.js
          

          盡管我們建議使用代理類型的 CDN,但新結(jié)構(gòu)也允許不同類型 CDN 的用戶將.next 目錄上傳到 CDN。

          styled-jsx 3

          我們也引入了 styled-jsx 3,Next.js 的默認(rèn) CSS-in-JS 解決方案,現(xiàn)在已經(jīng)為 React Suspense 做好了準(zhǔn)備。

          如果一個(gè)組件不屬于當(dāng)前組件作用域的一部分,那么該如何設(shè)置這個(gè)子組件的樣式呢?例如,如果你將一個(gè)組件包含在父組件中,并只有當(dāng)它被用在父組件中時(shí)才需要特定的樣式:

          const ChildComponent=()=> <div>
           <p>some text</p>
          </div>
          export default ()=> <div>
           <ChildComponent />
           <style jsx>{`
           p { color: black }
           `}</style>
          </div>
          

          上面的代碼試圖選擇 p 標(biāo)簽,但其實(shí)不起作用,因?yàn)?styled-jsx 樣式被限定在當(dāng)前組件,并沒有泄漏到子組件中。解決這個(gè)問題的一種方法是使用:global 方法,將 p 標(biāo)記的前綴移除。但這樣又引入了一個(gè)新問題,即樣式泄露到了整個(gè)頁面中。

          在 styled-jsx 3 中,通過引入一個(gè)新的 API css.resolve 解決了這個(gè)問題,它將為給定的 syled-jsx 字符串生成 className 和< style>標(biāo)簽(styles 屬性):

          import css from 'styled-jsx/css'
          const ChildComponent=({className})=> <div>
           <p className={className}>some text</p>
          </div>
          const { className, styles }=css.resolve`p { color: black }`
          export default ()=> <div>
           <ChildComponent className={className} />
           {styles}
          </div>
          

          這個(gè)新 API 可以將自定義樣式傳給子組件。

          由于這是 styled-jsx 的主要版本,如果你使用了 styles-jsx/css,那么在捆綁包大小方面有一個(gè)重大變化。在 styled-jsx 2 中,我們將生成外部樣式的“scoped”和“global”版本,即使只使用“scoped”版本,我們也會(huì)將“global”版本包含在內(nèi)。

          使用 styled-jsx 3 時(shí),全局樣式必須使用 css.global 而不是 css,這樣 styled-jsx 才能對(duì)包大小進(jìn)行優(yōu)化。

          App 和 Page 之間的 React Context(服務(wù)器端渲染)

          從 Next.js 7 開始,我們支持 pages/_app.js 和頁面組件之間的 React Context API。

          以前,我們無法在服務(wù)器端的頁面之間使用 React 上下文。原因是 Webpack 保留了內(nèi)部緩存模塊而不是使用 require.cache,我們開發(fā)了一個(gè)自定義 Webpack 插件來改變這種行為,以便在頁面之間共享模塊實(shí)例。

          這樣我們不僅可以使用新的 React 上下文,在頁面之間共享代碼時(shí)還能減少 Next.js 的內(nèi)存占用。


          社 區(qū)

          從 Next.js 首次發(fā)布以來,就已獲得相當(dāng)多的用戶,從財(cái)富 500 強(qiáng)公司到個(gè)人博客。我們非常高興看到 Next.js 的采用量一直在增長。

          目前,超過 12,500 個(gè)被公開索引的域名在使用 Next.js。我們有超過 500 名貢獻(xiàn)者,他們至少提交過一次代碼。在 GitHub 上,這個(gè)項(xiàng)目已經(jīng)有 29,000 個(gè) star。自首次發(fā)布以來,已提交了大約 2200 個(gè)拉取請(qǐng)求。

          Next.js 社區(qū)在 spectrum.chat/next-js 上擁有近 2000 名成員。

          英文原文

          https://nextjs.org/blog/next-7


          主站蜘蛛池模板: 精品视频一区二区三区四区五区| 无码人妻AⅤ一区二区三区| 国产在线精品一区二区在线观看 | 日韩在线视频一区二区三区| 国产午夜精品一区理论片飘花| 亚洲日韩一区二区一无码| 亚洲AV成人一区二区三区AV | 亚洲日韩精品无码一区二区三区| 国模无码一区二区三区| 久久精品国产第一区二区三区| 国产一区玩具在线观看| 亚洲AV永久无码精品一区二区国产| 色欲AV蜜桃一区二区三| 久久久国产精品亚洲一区| 久久精品国产一区| 国精产品一区一区三区免费视频| 一区二区三区免费视频播放器| 无码国产精品一区二区高潮| 无码丰满熟妇浪潮一区二区AV | 成人日韩熟女高清视频一区| 插我一区二区在线观看| 精品伦精品一区二区三区视频| 日本一区二区三区免费高清在线| 国产在线观看一区二区三区四区 | 亚洲高清偷拍一区二区三区| 波霸影院一区二区| 亚洲福利精品一区二区三区| 久久国产精品一区| 国产午夜福利精品一区二区三区| 国产免费一区二区三区不卡| 秋霞午夜一区二区| 国产91久久精品一区二区| 亚洲综合一区无码精品| 秋霞日韩一区二区三区在线观看 | 熟妇人妻系列av无码一区二区| 任你躁国产自任一区二区三区 | 后入内射国产一区二区| 变态拳头交视频一区二区| 亚洲国产精品无码久久一区二区| 久久久老熟女一区二区三区| 亚洲av无码一区二区三区人妖 |