者|Next.js 團隊
譯者|無明
出處丨前端之巔
在經過 26 次金絲雀發布和 340 萬次下載之后,近日,我們正式發布了 Next.js 7.0,新功能包括:
Next.js 的主要目標之一是提供最佳的性能和開發者體驗。最新版本為構建和調試管道帶來了很多重大改進。
得益于 Webpack 4 和 Babel 7,以及我們對代碼庫做出的很多改進和優化,Next.js 現在在開發過程中的啟動速度提高了 57%。
我們新增了增量編譯緩存,讓變更代碼的構建速度快了 40%。
以下是我們收集的一些示例數據:
因為使用了 webpackbar,在開發和構建的同時可以看到更好的實時反饋:
使用 react-error-overlay 更好地報告錯誤
準確地渲染錯誤對于良好的開發和調試體驗來說是至關重要的。到目前為止,我們可以渲染錯誤消息和堆棧跟蹤信息。我們在此基礎上更進一步,我們使用 react-error-overlay 來豐富堆棧跟蹤信息:
這是之前和之后的錯誤顯示比較:
另外,借助 react-error-overlay,你只需單擊特定代碼塊就可以輕松打開文本編輯器。
從發布第一個版本以來,Next.js 一直使用 Webpack 來打包代碼和重用豐富的插件。Next.js 現在使用了最新的 Webpack 4,其中包含很多改進和 bug 修復。
另一個新功能是支持 WebAssembly,Next.js 甚至可以進行 WebAssembly 服務器渲染。
這里有一個例子:
https://github.com/zeit/next.js/tree/canary/examples/with-webassembly
因為使用了 Webpack 4,我們引入了一種從捆綁包中提取 CSS 的新方法,這個插件叫作 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 導入相關的 20 個問題,例如,現在支持 import() 動態導入 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>
一個重大改進是現在不再需要在 pages/_document.js 中添加一下內容:
<link rel="stylesheet" href="/_next/static/style.css" />
Next.js 會自動注入這個 CSS 文件。在生產環境中,Next.js 還會自動向 CSS URL 中添加內容哈希,當文件發生變更時,最終用戶就不會得到舊文件,并且能夠獲得不可變的永久緩存。
簡而言之,要在 Next.js 項目中支持導入.css 文件,只需要在 next.config.js 中注冊 withCSS 插件:
const withCSS=require('@zeit/next-css') module.exports=withCSS({/* my next config */})
從版本 3 開始,Next.js 就通過 next/dynamic 來支持動態導入。
作為這項技術的早期采用者,我們必須自己編寫解決方案來處理 import()。
因此,Next.js 逐漸缺失 Webpack 后來引入的一些功能,包括 import()。
例如,無法手動命名和捆綁某些文件:
import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library')
另一個例子是在 next/dyanmic 模塊之外使用 import()。
從 Next.js 7 開始,我們不再直接使用默認的 import(),Next.js 為我們提供了開箱即用的 import() 支持。
這個變更也是完全向后兼容的。使用動態組件非常簡單:
import dynamic from 'next/dynamic' const MyComponent=dynamic(import('../components/my-component')) export default ()=> { return <div> <MyComponent /> </div> }
這段代碼的作用是為 my-component 創建一個新的 JavaScript 文件,并只在渲染< MyComponent/>時加載它。
最重要的是,如果沒有進行渲染,< script>標記就不會出現在初始 HTML 文檔中。
為了進一步簡化我們的代碼庫并利用優秀的 React 生態系統,在 Next.js 7 中,我們使用 react-loadable 重寫了 next/dynamic 模塊。這為動態組件引入了兩個很棒的新特性:
Next.js 6 中就已經引入了 Babel 7 測試版。后來 Babel 7 穩定版本發布,現在,Next.js 7 正在使用這個新發布的穩定版 Babel 7。
一些主要特性:
如果你的 Next.js 項目中沒有自定義 Babel 配置,那么就不存在重大變更。
但如果你具有自定義 Babel 配置,則必須將相應的自定義插件 / 預設升級到最新版本。
如果你從 Next.js 6 以下的版本升級,可以使用 babel-upgrade 工具。
除了升級到 Babel 7 之外,當 NODE_ENV 被設置為 test 時,Next.js Babel 預設(next/babel)現在默認將 modules 選項設置為 commonjs。
這個配置選項通常是在 Next.js 項目中創建自定義.babelrc 的唯一理由:
{ "env": { "development": { "presets": ["next/babel"] }, "production": { "presets": ["next/babel"] }, "test": { "presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]] } } }
使用 Next.js 7,這將變成:
{ "presets": ["next/babel"] }
現在可以刪除.babelrc,因為在沒有 Babel 配置時,Next.js 將自動使用 next/babel。
Next.js 在預渲染 HTML 時會將頁面內容放在< html>、< head>、< body>結構中,并包含頁面所需的 JavaScript 文件。
這個初始載荷之前約為 1.62kB。在 Next.js 7 中,我們優化了初始 HTML 載荷,現在為 1.5kB,減少了 7.4%,讓頁面變得更加精簡。
我們主要通過以下幾種方式來縮小文件:
在 Next.js 5 中,我們引入了 assetPrefix 支持,讓 Next.js 可以自動從某個位置(通常是 CDN)加載資源。如果你的 CDN 支持代理,可以使用這種辦法。你可以像這樣請求資源:
https://cdn.example.com/_next/static/<buildid>/pages/index.js
通常,CDN 先檢查緩存中是否包含這個文件,否則直接從源中請求文件。
不過,某些解決方案需要將目錄直接預先上傳到 CDN 中。這樣做的問題在于 Next.js 的 URL 結構與.next 文件夾中的文件夾結構不匹配。例如我們之前的例子:
https://cdn.example.com/_next/static/<buildid>/pages/index.js // 映射到: .next/page/index.js
在 Next.js 7 中,我們改變了.next 的目錄結構,讓它與 URL 結構相匹配:
https://cdn.example.com/_next/static/<buildid>/pages/index.js // 映射到: .next/static/<buildid>/pages/index.js
盡管我們建議使用代理類型的 CDN,但新結構也允許不同類型 CDN 的用戶將.next 目錄上傳到 CDN。
我們也引入了 styled-jsx 3,Next.js 的默認 CSS-in-JS 解決方案,現在已經為 React Suspense 做好了準備。
如果一個組件不屬于當前組件作用域的一部分,那么該如何設置這個子組件的樣式呢?例如,如果你將一個組件包含在父組件中,并只有當它被用在父組件中時才需要特定的樣式:
const ChildComponent=()=> <div> <p>some text</p> </div> export default ()=> <div> <ChildComponent /> <style jsx>{` p { color: black } `}</style> </div>
上面的代碼試圖選擇 p 標簽,但其實不起作用,因為 styled-jsx 樣式被限定在當前組件,并沒有泄漏到子組件中。解決這個問題的一種方法是使用:global 方法,將 p 標記的前綴移除。但這樣又引入了一個新問題,即樣式泄露到了整個頁面中。
在 styled-jsx 3 中,通過引入一個新的 API css.resolve 解決了這個問題,它將為給定的 syled-jsx 字符串生成 className 和< style>標簽(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>
這個新 API 可以將自定義樣式傳給子組件。
由于這是 styled-jsx 的主要版本,如果你使用了 styles-jsx/css,那么在捆綁包大小方面有一個重大變化。在 styled-jsx 2 中,我們將生成外部樣式的“scoped”和“global”版本,即使只使用“scoped”版本,我們也會將“global”版本包含在內。
使用 styled-jsx 3 時,全局樣式必須使用 css.global 而不是 css,這樣 styled-jsx 才能對包大小進行優化。
App 和 Page 之間的 React Context(服務器端渲染)
從 Next.js 7 開始,我們支持 pages/_app.js 和頁面組件之間的 React Context API。
以前,我們無法在服務器端的頁面之間使用 React 上下文。原因是 Webpack 保留了內部緩存模塊而不是使用 require.cache,我們開發了一個自定義 Webpack 插件來改變這種行為,以便在頁面之間共享模塊實例。
這樣我們不僅可以使用新的 React 上下文,在頁面之間共享代碼時還能減少 Next.js 的內存占用。
從 Next.js 首次發布以來,就已獲得相當多的用戶,從財富 500 強公司到個人博客。我們非常高興看到 Next.js 的采用量一直在增長。
目前,超過 12,500 個被公開索引的域名在使用 Next.js。我們有超過 500 名貢獻者,他們至少提交過一次代碼。在 GitHub 上,這個項目已經有 29,000 個 star。自首次發布以來,已提交了大約 2200 個拉取請求。
Next.js 社區在 spectrum.chat/next-js 上擁有近 2000 名成員。
英文原文
https://nextjs.org/blog/next-7
瀏覽器大戰
第一次瀏覽器大戰發生在上個世紀90年代,微軟發布了它的IE瀏覽器,和網景公司的Netscape Navigator瀏覽器大打出手。 ?
第二次瀏覽器大戰發生在20世紀。 ?
戰爭產物:Internet Explorer 9
元老級內核之一,由微軟開發,并于1997年10月首次在ie 4.0中使用,憑借其windows壟斷優勢,Trident市場占有率一直很高。然而壟斷并非,沒有競爭就沒有進步,長期以往,Trident內核一度停滯不前,更新緩慢,甚至一度與W3C標準脫節。2011年,從ie 9開始,Trident開始支持HTML5和CSS 3,因此我們也經常會看到有些網站在瀏覽時會提示用戶(在Internet Explorer 9.0+以上瀏覽效果最佳)。前端程序員做瀏覽器兼容一般也不再會考慮ie 8之前的瀏覽器了。
元老級內核之一,由Netscape公司Mozilla組織開發。1998年,Netscape在于IE瀏覽器競爭失利之后,成立了非正式組織Mozilla,由其開發新一代內核,后命名為“Gecko”。FireFox也是這班人開發出來了,因此這也就是Mozilla一直使用的內核。 Gecko的特點是代碼完全公開,因此其開發程度很高,全世界的程序員都可以為其編寫代碼,增加功能。
這是蘋果公司開發的內核,也是其旗下產品Ssfari瀏覽器使用的內核。Webkit引擎包含了WebCode排版引擎和JavaScriptCode解析引擎,分別是從KDE的KHTML和KJS衍生而來,它們都是自由軟件,在GPL條約下授權,同時支持BSD系統開發。 Chrome、360極速瀏覽器以及搜狗高速瀏覽器也使用Webkit作為內核(在腳本理解方面,Chorome使用自己研發的V8引擎)。
這是由Google和Opera Software開發的瀏覽器排版引擎,Google計算將這個渲染引擎作為Chromium計劃的一部分,并且在2013年4月公布了這一消息。這一渲染引擎是開源引擎Webkit中WebCore組件的一個分支,并且在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex瀏覽器中使用
由于各大主流瀏覽器由不同的廠家開發,所用的核心架構和代碼也很難重和,這就為各種莫名其妙的Bug(代碼錯誤)提供了溫床。再加上各大廠商出于自身利益考慮而設置的種種技術壁壘,都讓CSS應用起來比想象得要麻煩。瀏覽器的兼容問題是我們必須去克服的。
1)圖片有邊框BUG
當圖片加<a href=“#”></a>在IE上會出現邊框
Hack:給圖片加border:0;或者border:0 none;
2)圖片間隙
div中的圖片間隙BUG
描述:在div中插入圖片時,圖片會將div下方撐大大約三像素。
hack1:將</div>與<img>寫在一行上;
hack2:將<img>轉為塊狀元素,給<img>添加聲明:display:block;
3) 雙倍浮向(雙倍邊距)(只有IE6出現)
描述:當Ie6及更低版本瀏覽器在解析浮動元素時,會錯誤地把浮向邊邊界(margin)加倍顯示。
hack:給浮動元素添加聲明:display:inline;
4)默認高度(IE6、IE7)
描述:在IE6及以下版本中,部分塊元素擁有默認高度(在16px左右;)
hack1:給元素添加聲明:font-size:0;
hack2:給元素添加聲明:overflow:hidden;
5)表單元素對齊不一致
描述:表單元素行高對齊方式不一致
hack:給表單元素添加聲明:float:left;
6)按鈕元素默認大小不一
描述:各瀏覽器中按鈕元素大小不一致
hack1: 統一大小/(用a標記模擬)
hack2:input外邊套一個標簽,在這個標簽里寫按鈕的樣式,把input的邊框去掉。
hack3:如果這個按鈕是一個圖片,直接把圖片作為按鈕的背景圖即可。
7)鼠標指針bug
描述:cursor屬性的hand屬性值只有IE9以下瀏覽器識別,其它瀏覽器不識別該聲明,cursor屬性的pointer屬性值IE6.0以上版本及其它內核瀏覽器都識別該聲明。
hack: 如統一某元素鼠標指針形狀為手型,
應添加聲明:cursor:pointer cursor: ;
auto默認
crosshair加號
text文本
wait等待
help幫助
progress過程
inherit繼承
move移動
ne-resize向上或向右移動
pointer手形
8)透明屬性
兼容其他瀏覽器寫法:opacity:value;(value的取值范圍0-1; 例:opacity:0.5;)
IE瀏覽器寫法:filter:alpha(opacity=value);取值范圍 1-100(整數)
1.下劃線屬性過濾器
當在一個屬性前面增加了一個下劃線后,由于符合標準的瀏覽器不能識別帶有下劃線的屬性而忽略了這個聲明,但是在IE6及更低版本瀏覽器中會繼續解析這個規則。
語法:選擇符{_屬性:屬性值;}
2. !important
關鍵字過濾器 它表示所附加的聲明具有最高優先級的意思。但由于IE6及更低版本不能識別它, 我們可以利用IE6的這個Bug作為過濾器來兼容IE6和其它標準瀏覽器。
語法:選擇符{屬性:屬性值!important;}
3. *屬性過濾器
當在一個屬性前面增加了*后,該屬性只能被IE7瀏覽器識別,其它瀏覽器混略該屬 性的作用。
語法:選擇符{*屬性:屬性值;}
4. :IE版本識別;其它瀏覽器都不識別
語法:選擇符{屬性:屬性值;}
5. >5. \0 : IE8 及以上版本識別;其它瀏覽器都不識別
家好,我是Echa。
好消息,2023年10月26號Next.js 官方研發團隊Lee Robinson 和Tim Neutkens一起對外宣布Next.js 14 正式發布。距離上一個Next.js 13.5 版本(2023年9月19日),只用了短短37 天時間,而且直接跨越式從 Next.js 13.5 跳到 14版本,從側面說明了Next.js 研發團隊技術實力非常不錯的,但其Github倉庫的 star 數已超過 114k,并且在全球擁有超過 114w名用戶。Next.js 官方研發團隊真厲害,給咱們開發人員帶來了很多方便,小編舉起大拇指點贊。
Next.js Github 主頁
但是又會有人說前端太卷了,根本學不過來;還有人會說各自為了完成KPI;粉絲們你們怎么看呢?歡迎在評論下說出自己的看法。
借此機會,小編先給大家詳細介紹一下Next.js 到底是什么,能做什么,有哪些優點等等,只有徹底了解了Next.js ,才能說出自己觀點。希望對大家有所幫助,多了解,多學點有益無害,說不定哪天團隊開發項目中就用上,你說是不是?下面小編給大家一一介紹上面的問題。
傳送門:https://nextjs.org/
Github:https://github.com/vercel/next.js
Next.js 中文官網
Next.js是一個流行的React框架,為開發人員提供了許多有用的功能和便利,用于構建現代化、可擴展的Web應用程序,用于構建React應用程序。它在React的基礎上提供了一些增強功能,包括服務器渲染(SSR)、靜態生成(SSG)、路由等。Next.js的目標是簡化React應用程序的開發流程,并提供更好的性能。
Next.js 為您提供生產環境所需的所有功能以及最佳的開發體驗:包括靜態及服務器端融合渲染、 支持 TypeScript、智能化打包、 路由預取等功能無需任何配置。
因為全球領先的公司都在使用并喜愛 Next.js。
選擇 Next.js原因如下:
自動編譯并打包。從一開始就為生產環境而優化。
在一個項目中同時支持構建時預渲染頁面(SSG)和請求時渲染頁面(SSR)。
在構建之后以增量的方式添加并更新靜態預渲染的頁面。
自動配置并編譯 TypeScript。
快速、可靠的實時編輯體驗,已在 Facebook 級別的應用上規模上得到驗證。
每個 pages 目錄下的組件都是一條路由。
創建 API 端點(可選)以提供后端功能。
使用 CSS 模塊創建組件級的樣式。內置對 Sass 的支持。
采用由 Google Chrome 小組創建的、并經過優化的打包和拆分算法。
小編描述了這么多,不如直接上圖:
為什么選擇 Next.js
Next.js官網描述是:這是一個用于生產環境的React框架,對這句話的理解得關注這兩個關鍵詞:
生產環境:能用于生產就得考慮到方方面面功能,比如性能怎么保證、SSR/CSR/SSG等渲染機制的支持、打包、路由支持、css module,對開發環境的友好,是否能內置支持TypeScript,配置方面也盡可能簡化
React框架:所以Next.js是基于React開發,跟Vue和Angular無關。
要從頭開始使用 React 構建一個完整的 Web 應用程序,需要考慮許多重要的細節:
一個框架就可以解決上述這些問題。但是,這樣的框架必須具有正確的抽象級別,否則它將不是很有用。它還需要具有出色的“開發人員體驗”,以確保您和您的團隊在編寫代碼時擁有出色的體驗。
Next.js 官方案例提供了周邊框架的搭建案例,方便開發者配置相關框架和插件,具體如下:
Next.js 官方案例
前面內容小編也有提到了Next.js 優勢,具體如下:
Next.js 插件
完善的工程化機制
你不需要自己去配置 webpack 方案,它已經內置了以下工程化基礎:
也做了一些打包優化功能:
Next.js 渲染方法總共分四種:客戶端渲染(CSR)、服務器端渲染(SSR)、靜態站點生成(SSG)和增量靜態生成(ISR)。
渲染是將React代碼轉換成HTML的過程。用戶選擇的渲染方法取決于所處理的數據以及用戶對性能的關注程度。
在Next.js中,渲染的用途非常廣泛。用戶可以用靜態或增量方式渲染客戶端或服務器端頁面。
小編讓大家看看這些方法是如何工作的以及每種方法有怎樣的表現。具體如下:
客戶端渲染(CSR)
當用戶需要頻繁更新數據或不想預渲染頁面時,應該使用客戶端渲染(CSR)。用戶可以在頁面層面或組件層面實現CSR。在頁面層面,Next.js在運行時獲取數據;而在組件層面執行操作時,它在頁面掛載時獲取數據。正因為如此,CSR可能導致性能變慢。
使用useEffect()鉤子在客戶端渲染頁面,如下所示:
import { useState, useEffect } from 'react'
function Home() {
const [data, setData]=useState(null)
const [isLoading, setLoading]=useState(false)
useEffect(()=> {
setLoading(true)
fetch('/api/get-data')
.then((res)=> res.json())
.then((data)=> {
setData(data)
setLoading(false)
})
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No data</p>
return (
<div>
// Use data
</div>
)
}
還可以使用SWR鉤子。它緩存數據,一旦數據過時,就重新驗證數據。
import useSWR from 'swr'
const fetcher=(...args)=> fetch(...args).then((res)=> res.json())
function Home() {
const { data, error }=useSWR('/api/data', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
return (
<div>
// Use data
</div>
)
}
在Next.js 13中,用戶需要使用客戶端組件,為此在文件頂部添加“use client”指令。
"use client";
export default ()=> {
return (
<div>
// Client component
</div>
);
};
SSR和CSR的區別在于,在SSR中,從服務器上的每個頁面請求獲取數據;而在CSR中,從客戶端獲取數據。
服務器端渲染(SSR)
服務器端渲染(SSR)
就服務器端渲染(SSR)而言,當用戶訪問網頁時,瀏覽器向服務器發送關于該頁面的請求。服務器從數據庫獲取必要的數據(如果需要的話),并將其與頁面內容一同發送到瀏覽器。然后瀏覽器將其顯示給用戶。
瀏覽器對用戶點擊的每個鏈接發出此請求,這意味著服務器每次都處理請求。這可能會降低網站的性能。然而,服務器端渲染非常適合使用動態數據的頁面。
每當用戶請求時,使用getServerSideProps重新構建頁面。
export default function Home({ data }) {
return (
<main>
// Use data
</main>
);
}
export async function getServerSideProps() {
// Fetch data from external api
const res=await fetch('https://.../data')
const data=await res.json()
// Will be passed to the page component as props
return { props: { data } }
}
getServerSideProps只在服務器上運行,它是這樣運行的:
在新版本中,用戶可以選擇使用頁面或布局中的動態數據獲取來享用服務器端渲染。
動態數據獲取是fetch()請求,它通過將緩存選項設置為“no-store”來選擇退出緩存。
fetch (https://..。', {cache: 'no-store'});
或者,將revalidate設置為0:
fetch (https://..。', {next: {revalidate: 0}});
靜態站點生成(SSG)
就靜態站點生成(SSG)而言,頁面在構建期間只獲取一次數據。靜態生成頁面非常快,性能良好,因為所有頁面都事先構建。SSG因此非常適合使用靜態內容(比如銷售頁面或博客)的頁面。
在Next.js中,用戶必須從想要靜態渲染的頁面中導出 getStaticProps函數。
export default function Home({ data }) {
return (
<main>
// Use data
</main>
);
}
export async function getStaticProps() {
// Fetch data from external API at build time
const res=await fetch('https://.../data')
const data=await res.json()
// Will be passed to the page component as props
return { props: { data } }
}
用戶還可以在getStaticProps里面查詢數據庫。
export async function getStaticProps() {
// Call function to fetch data from database
const data=await getDataFromDB()
return { props: { data } }
}
在Next.js 13中,靜態渲染是默認操作,內容被獲取和緩存,除非用戶關閉了緩存選項。
async function getData() {
const res=await fetch('https://.../data');
return res.json();
}
export default async function Home() {
const data=await getData();
return (
<main>
// Use data
</main>
);
}
增量靜態生成(ISR)
有時用戶想使用SSG,但又想定期更新內容,這時候增量靜態生成(ISG)大有幫助。
ISG讓用戶可以在構建靜態頁面后在指定的時間間隔后創建或更新靜態頁面。這樣一來,用戶不需要重建整個站點,只需重建需要它的頁面。
ISG保留了SSG的優點,又增加了為用戶提供最新內容的好處。ISG非常適合站點上那些使用不斷變化的數據的頁面。比如說,用戶可以使用ISR渲染博文,以便在編輯文章或添加新文章后博客保持更新。
若要使用ISR,將revalidate屬性添加到頁面上的getStaticProps函數中。
export async function getStaticProps() {
const res=await fetch('https://.../data')
const data=await res.json()
return {
props: {
data,
},
revalidate: 60
}
}
在這里,當請求在60秒后到來時,Next.js將嘗試重新構建頁面。下一個請求將產生帶有更新頁面的響應。
在Next.js 13中,使用fetch中的revalidate,就像這樣:
fetch (https://..。/data', {next: {revalidate: 60}});
用戶可以將時間間隔設置為最適合其數據的任何時間間隔。
如何選擇渲染方法?
到目前為止,用戶已了解了Next.js中的四種渲染方法:CSR、SSR、SSG和ISG。每種方法都適用于不同的情況。CSR適用于需要新數據的頁面。SSR適用于使用動態數據的頁面,但它對SEO較為友好。
SSG適合數據基本上靜態的頁面,而ISG最適合含有用戶想要間隔更新的數據的頁面。SSG和ISG從性能和SEO方面來說都很出色,因為數據預獲取,用戶還可以緩存數據。
系統環境需求
安裝設置
我們建議使用 create-next-app創建新的 Next.js 應用程序,它會自動為你設置所有內容。創建項目,請運行:
npx create-next-app@latest
# or
yarn create next-app
如果你希望使用 TypeScript 開發項目,可以通過 --typescript 參數創建 TypeScript 項目:
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
安裝完成后:
手動安裝設置
為你的項目安裝 next、react 和 react-dom :
npm install next react react-dom
# or
yarn add next react react-dom
打開 package.json 文件并添加 scripts 配置段:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
這些腳本涉及開發應用程序的不同階段:
Next.js 是圍繞著 頁面(pages) 的概念構造的。一個頁面(page)就是一個從 pages 目錄下的 .js、.jsx、.ts 或 .tsx 文件導出的 React 組件。
頁面(page) 根據其文件名與路由關聯。例如,pages/about.js 被映射到 /about。甚至可以在文件名中添加動態路由參數。
在你的項目中創建一個 pages 目錄。
為 ./pages/index.js 文件填充如下內容:
function HomePage() {
return <div>Welcome to Next.js!</div>
}
export default HomePage
到目前為止,我們得到了:
此外,任何 Next.js 應用程序從一開始就是可以投入到生產環境中。
Next.js 14 官方正式發布該版本的主要更新如下:
可以通過以下命令來立即升級最新版本:
npx create-next-app@latest
Next.js 編譯器
自 Next.js 13 發布以來,Next 團隊一直致力于提高 Next.js 中 Pages 和 App Router 的本地開發性能。
之前,Next 團隊通過重寫 Next.js 的 next dev 和其他部分以實現這一目標。然而,后來改變了方法,采取了更漸進的方式。現在,重點是首先支持所有 Next.js 的功能,因此基于 Rust 的編譯器很快就會穩定下來。
Next.js 使用基于 Rust 引擎的 Turbopack,現在已經通過了 5000 個 next dev 的集成測試。這些測試涵蓋了過去 7 年中的錯誤修復和重現。
在大型 Next.js 應用 vercel.com 上進行測試時,可以看到:
該基準測試是大型應用(和大型模塊圖)性能改進的實際結果。現在,next dev 的 90% 測試已經通過,在使用 next dev --turbo 時,應該會看到更快、更可靠的性能表現。
一旦達到 100% 的測試通過,將在即將發布的次要版本中將 Turbopack 移至穩定版本。另外,還將繼續支持使用 webpack 進行自定義配置和生態系統插件。
可以在 areweturboyet.com 上關注通過測試的百分比。
表單和數據變更
Next.js 9 引入了 API Routes,這是一種快速構建后端端點的方法,可以與前端代碼一起使用。
例如,可以在 api/ 目錄中創建一個新文件:
//pages/api/submit.ts
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const data=req.body;
const id=await createItem(data);
res.status(200).json({ id });
}
然后,在客戶端,可以使用 React 和 onSubmit 等事件處理程序來獲取 API 路由:
//pages/index.tsx
import { FormEvent } from 'react';
export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData=new FormData(event.currentTarget);
const response=await fetch('/api/submit', {
method: 'POST',
body: formData,
});
// Handle response if necessary
const data=await response.json();
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
現在,隨著 Next.js 14 的推出,希望簡化開發者在編寫數據變更時的體驗。此外,還希望在用戶網絡連接較慢或從低功率設備提交表單時改善用戶體驗。
服務端操作(穩定)
如果不想手動創建 API Route,那么可以定義一個函數,在服務端安全地運行,并直接從 React 組件中調用它。
App Router 構建在 React canary 通道上,對于框架 采用新功能來說是穩定的。從 v14 開始,Next.js 已升級到最新的 React canary,其中包括穩定的服務器操作。
App Router 是建立在 React canary 通道上的,這個通道對于框架來采用新功能是穩定的。從 v14 開始,Next.js 已經升級到了最新的 React canary 版本,其中包含穩定的服務端操作功能。
前面 Pages Router 的例子可以簡化為一個文件:
// app/page.tsx
export default function Page() {
async function create(formData: FormData) {
'use server';
const id=await createItem(formData);
}
return (
<form action={create}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
服務端操作對于之前使用過服務端中心框架的開發者來說應該會很熟悉。它是建立在 Web 基礎知識(如表單和 FormData Web API)之上的。
通過表單使用服務端操作對于漸進增強是有幫助的,但并不是必需的。也可以直接將其作為函數調用,而無需使用表單。在使用 TypeScript 時,這提供了完整的端到端類型安全性,確保客戶端和服務端之間的安全性。
數據變更、頁面重新渲染或重定向可以在一次網絡往返中完成,確保在客戶端上顯示正確的數據,即使上游提供者的響應速度較慢。此外,可以組合和重用不同的操作,包括在同一個路由中使用多個不同的操作。
緩存、重新驗證、重定向等
服務端操作深度集成到整個 App Router 模型中。你可以:
部分預渲染(預覽)
Next.js 中正在開發的部分預渲染推出了預覽版,它是一種針對動態內容的編譯器優化,可以實現快速的初始靜態響應。
部分預渲染建立在對服務端渲染(SSR)、靜態站點生成(SSG)和增量靜態重新驗證(ISR)進行了十年的研究和開發的基礎上。
Motivation(動機)
目前存在過多的運行時、配置選項和渲染方法需要考慮。希望在享受靜態網頁的速度和可靠性的同時,也能支持完全動態、個性化的響應。不過,擁有出色的性能和個性化體驗不應以復雜性為代價。
面臨的挑戰是創建更好的開發體驗,簡化現有模型,而無需引入新的需要學習的 API。雖然部分緩存服務端內容的方法已經存在,但這些方法仍然需要滿足旨在實現的開發者體驗和可組合性目標。
部分預渲染不需要學習新的 API。
建立在 React Suspense 之上
部分預渲染是由 Suspense 邊界定義的。以下是它的工作原理。考慮以下電子商務頁面:
// app/page.tsx
export default function Page() {
return (
<main>
<header>
<h1>My Store</h1>
<Suspense fallback={<CartSkeleton />}>
<ShoppingCart />
</Suspense>
</header>
<Banner />
<Suspense fallback={<ProductListSkeleton />}>
<Recommendations />
</Suspense>
<NewProducts />
</main>
);
}
啟用部分預渲染后,該頁面將根據 <Suspense /> 邊界生成靜態骨架,它包含了頁面的結構和布局,但不包含動態內容。React Suspense 的fallback也會被預渲染。
然后,在靜態骨架中,Suspense 的fallback將被動態組件替換,例如讀取 cookie 來確定購物車內容,或者根據用戶顯示橫幅廣告。
當發出請求時,立即提供靜態 HTML 骨架:
<main>
<header>
<h1>My Store</h1>
<div class="cart-skeleton">
<!-- Hole -->
</div>
</header>
<div class="banner" />
<div class="product-list-skeleton">
<!-- Hole -->
</div>
<section class="new-products" />
</main>
由于 <ShoppingCart /> 組件需要讀取cookie以查看用戶會話,因此該組件將作為同一HTTP請求的一部分進行流式傳輸,與靜態骨架一起加載,這樣就不需要額外的網絡往返。
// app/cart.tsx
import { cookies } from 'next/headers'
export default function ShoppingCart() {
const cookieStore=cookies()
const session=cookieStore.get('session')
return ...
}
為了獲得最細粒度的靜態骨架,可能需要添加額外的 <Suspense /> 邊界。然而,如果今天已經在使用 loading.js,那么這是一個隱式的 <Suspense /> 邊界,因此不需要更改即可生成靜態骨架。
即將到來
部分預渲染正在積極開發中,將在即將發布的次要版本中分享更多更新。
元數據改進
在頁面內容從服務端流式傳輸之前,需要先向瀏覽器發送關于視口、顏色方案和主題等重要元數據。
確保這些meta標簽與初始頁面內容一起發送可以提供流暢的用戶體驗,防止由于更改主題顏色或視口變化而導致頁面閃爍或布局偏移。
在 Next.js 14 中,將阻塞和非阻塞的元數據解耦。只有一小部分元數據選項是阻塞的,希望確保非阻塞的元數據不會阻止部分預渲染頁面提供靜態骨架。
以下元數據選項現已棄用,并將在未來的主要版本中從元數據中刪除:
從 Next.js 14 開始,使用新的選項 viewport 和 generateViewport 來替換這些選項。所有其他元數據選項保持不變。
Next.js Learn 課程
在 Next.js Learn 上發布了全新的免費課程。本課程教授:
其他更新
一行代碼,可能會創造出下一個讓人驚嘆的產品;
一個創新,可能會開啟一個全新的科技時代;
一份初心,可能會影響到無數人的生活;
無論是在大公司工作,還是在小團隊奮斗;
無論是資深的程序員,還是剛剛入行的新手;
每個人的代碼,都有力量改變世界。
創作不易,喜歡的老鐵們加個關注,點個贊,打個賞,后面會不定期更新干貨和技術相關的資訊,速速收藏,謝謝!你們的一個小小舉動就是對小編的認可,更是創作的動力。
創作文章的初心是:沉淀、分享和利他。既想寫給現在的你,也想貪心寫給 10 年、20 年后的工程師們,現在的你站在浪潮之巔,面對魔幻的互聯網世界,很容易把一條河流看成整片大海。未來的讀者已經知道了這段技術的發展歷史,但難免會忽略一些細節。如果未來的工程師們真的創造出了時間旅行機器,可以讓你回到現在。那么小編的創作就是你和當年工程師們的接頭暗號,你能感知到他們在這個時代的鍵盤上留下的余溫。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。