Next.js

我們?yōu)殚_源的Next.js感到非常自豪鳞骤,它是一個(gè)服務(wù)器渲染的通用JavaScript webapps的小型框架阅羹,建立在React,Webpack和Babel的基礎(chǔ)之上愉舔。

要開始使用它艺配,在一個(gè)新的目錄中運(yùn)行: package.json

$ npm install next --save
$ mkdir pages

填充pages/index.js:

import React from 'react'
export default () => <div>Hello world!</div>

package.json像這樣添加一個(gè)腳本:

{
  "scripts": {
    "dev": "next"
  }
}

并運(yùn)行:

$ npm run dev

這篇博客文章將涉及項(xiàng)目的理念和設(shè)計(jì)決策察郁。

要學(xué)習(xí)如何使用Next.js衍慎,請(qǐng)參閱自述文件,您可以在幾分鐘內(nèi)了解該工具的全部功能绳锅。

首先我們將深入到項(xiàng)目的背景西饵,然后描述6個(gè)基本原則:

  1. 零設(shè)置。使用文件系統(tǒng)作為API
  2. 只有JavaScript鳞芙。一切都是一個(gè)功能
  3. 自動(dòng)服務(wù)器呈現(xiàn)和代碼分割
  4. 數(shù)據(jù)獲取取決于開發(fā)者
  5. 預(yù)期是表現(xiàn)的關(guān)鍵
  6. 簡單部署

背景

多年來眷柔,我們一直在追求通用JavaScript應(yīng)用程序的愿景。

Node.js引導(dǎo)了客戶端和服務(wù)器之間的代碼共享原朝,拓寬了世界各地許多開發(fā)者的貢獻(xiàn)面驯嘱。

許多嘗試都是為了在Node上開發(fā)應(yīng)用程序和網(wǎng)站而設(shè)計(jì)的。許多模板語言和框架出現(xiàn)了......但是前端和后端之間的技術(shù)鴻溝依然存在喳坠。

例如鞠评,如果你選擇了Express和Jade,一些HTML將被服務(wù)器渲染壕鹉,然后一個(gè)不同的代碼庫 (由jQuery或類似的庫支持)將接管剃幌。

這種情況實(shí)際上并不比PHP的好。在許多方面晾浴,PHP實(shí)際上更適合于“服務(wù)器呈現(xiàn)HTML”作業(yè)负乡。在異步/等待之前,很難在JS中查詢數(shù)據(jù)服務(wù)脊凰。將錯(cuò)誤限制在請(qǐng)求/響應(yīng)的范圍之內(nèi)也是非常困難的抖棘。

然而,從那以后狸涌,顯著的概念上的變化使我們能夠縮小這個(gè)差距切省。其中最重要的是引入了純渲染函數(shù),該函數(shù)根據(jù)當(dāng)時(shí)的可用數(shù)據(jù)返回UI的表示形式帕胆。

這個(gè)模型(被React普及)是非常重要的朝捆,但是這與大多數(shù)模板系統(tǒng)的工作原理沒有什么不同。另一個(gè)關(guān)鍵概念是組件生命周期懒豹。

生命周期鉤子允許我們處理源自服務(wù)器的一些渲染的延續(xù)右蹦。例如,您可以從數(shù)據(jù)的靜態(tài)表示開始歼捐,訂閱來自服務(wù)器的實(shí)時(shí)更新,并隨時(shí)間變化晨汹”ⅲ或者也許它保持不變。

Next.js是我們?nèi)绾瓮苿?dòng)這一愿景的淘这。

零設(shè)置剥扣。使用文件系統(tǒng)作為API

工具對(duì)文件系統(tǒng)中的項(xiàng)目結(jié)構(gòu)做了一些假設(shè)巩剖。

例如,我們通常通過創(chuàng)建一個(gè)新的目錄钠怯,放置一個(gè)package.json內(nèi)部佳魔,然后安裝模塊來啟動(dòng)一個(gè)Node.js項(xiàng)目./node_modules。

Next.js通過引入pages 頂級(jí)組件所在的子目錄來擴(kuò)展該結(jié)構(gòu)晦炊。

例如鞠鲜,您可以使用以下命令來填充pages/index.js路線的哪些地圖/:

import React from 'react'
export default () => <marquee>Hello world</marquee>

然后pages/about.js映射到: /about

import React from 'react'
export default () => <h1>About us</h1>

我們相信這是一個(gè)很好的默認(rèn)開始,并允許一個(gè)項(xiàng)目的快速探索断国。當(dāng)需要更高級(jí)的路由時(shí)贤姆,我們將允許開發(fā)人員攔截請(qǐng)求并采取控制。

所有需要開始工作的項(xiàng)目是運(yùn)行:

$ next

沒有配置稳衬,除非需要霞捡。自動(dòng)熱碼重新加載,錯(cuò)誤報(bào)告薄疚,源地圖碧信,舊版瀏覽器的轉(zhuǎn)換。

只有JavaScript街夭。一切都是一個(gè)功能

Next.js中的每個(gè)路由只是一個(gè)ES6模塊砰碴,用于導(dǎo)出一個(gè)擴(kuò)展的函數(shù)或類React.Component。

這種方法與類似模型相比的優(yōu)點(diǎn)是整個(gè)系統(tǒng)仍然是高度可組合和可測(cè)試的莱坎。例如衣式,一個(gè)組件可以被直接渲染,或者被另一個(gè)頂層組件導(dǎo)入和渲染檐什。

組件也可以引入對(duì)頁面的更改: <head>

import React from 'react'
import Head from 'next/head'
export default () => (
  <div>
    <Head>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
    </Head>
    <h1>Hi. I'm mobile-ready!</h1>
  </div>
)

此外碴卧,不需要包裝或轉(zhuǎn)換,使這個(gè)系統(tǒng)完全可測(cè)試乃正。您的測(cè)試套件可以簡單地導(dǎo)入和淺顯渲染您的路線住册。

我們也決定采用CSS-in-JS。我們使用優(yōu)秀的glamor庫瓮具,給我們完全不受限制的CSS的權(quán)力荧飞,而不需要CSS解析和編譯:

import React from 'react'
import css from 'next/css'

export default () => <p className={style}>Hi there!</p>

const style = css({
  color: 'red',
  ':hover': {
    color: 'blue'
  },
  '@media (max-width: 500px)': {
    color: 'rebeccapurple'
  }
})

我們認(rèn)為這個(gè)模型提供了卓越的性能,可組合性和與服務(wù)器渲染流水線的集成名党。

自動(dòng)服務(wù)器呈現(xiàn)和代碼分割

迄今為止叹阔,兩項(xiàng)任務(wù)同時(shí)非常困難和非常可却谩:

服務(wù)器渲染

  • 將應(yīng)用程序的構(gòu)建分割成更小的包
  • 使用Next.js耳幢,每個(gè)內(nèi)部組件pages/都會(huì)自動(dòng)獲取服務(wù)器并且內(nèi)聯(lián)腳本。

當(dāng)通過或路由器動(dòng)態(tài)加載組件時(shí),我們獲取一個(gè)基于JSON的頁面表示睛藻,同樣包含它的腳本启上。 <Link prefetch />

這意味著某個(gè)頁面可能有一個(gè)廣泛的導(dǎo)入列表:

import React from 'react'
import d3 from 'd3'
import jQuery from 'jquery'

...不影響其他頁面的性能。

這個(gè)細(xì)節(jié)對(duì)于那些在技術(shù)和業(yè)務(wù)需求截然不同的組件上進(jìn)行協(xié)作的大型團(tuán)隊(duì)來說特別有用店印。團(tuán)隊(duì)或個(gè)人的表現(xiàn)處罰不會(huì)影響組織的其余部分冈在。

數(shù)據(jù)獲取取決于開發(fā)者

靜態(tài)JSX的服務(wù)器渲染是一個(gè)重要的成就,但真實(shí)世界的應(yīng)用程序處理來自不同的API調(diào)用和網(wǎng)絡(luò)請(qǐng)求的動(dòng)態(tài)數(shù)據(jù)按摘。

Next.js對(duì)React組件合同做了非常重要的擴(kuò)展:getInitialProps包券。

提取一些數(shù)據(jù)的頁面如下所示:

import React from 'react'
import 'isomorphic-fetch'
export default class extends React.Component {
  static async getInitialProps () {
    const res = await fetch('https://api.company.com/user/123')
    const data = await res.json()
    return { username: data.profile.username }
  }
}

我們對(duì)于什么樣的功能(像異步/等待)的立場(chǎng)可以概括為:我們的目標(biāo)是V8的功能。由于我們的目標(biāo)是在服務(wù)器和客戶端之間進(jìn)行代碼共享院峡,所以在執(zhí)行Node上的代碼以及在Chrome或Brave上開發(fā)時(shí)兴使,這給我們帶來了很好的性能。

正如你所看到的那樣照激,契約是非常簡單而且不可選擇的:必須返回一個(gè)解析成JavaScript的對(duì)象发魄,然后填充組件。 getInitialPropsPromise props

這使得Next.js在REST API俩垃,GraphQL甚至是全局狀態(tài)管理庫Redux上都能很好地發(fā)揮作用励幼,在我們的wiki上你可以找到它的一個(gè)例子。

同樣的方法允許加載不同的數(shù)據(jù)口柳,這取決于組件是通過服務(wù)器呈現(xiàn)的還是通過客戶端路由動(dòng)態(tài)呈現(xiàn)的:

static async getInitialProps ({ res }) {
  return res
    ? { userAgent: res.headers['user-agent'] }
    : { userAgent: navigator.userAgent }
}

本文翻譯自:https://zeit.co/blog/next

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苹粟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子跃闹,更是在濱河造成了極大的恐慌嵌削,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件望艺,死亡現(xiàn)場(chǎng)離奇詭異苛秕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)找默,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門艇劫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惩激,你說我怎么就攤上這事店煞。” “怎么了风钻?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵顷蟀,是天一觀的道長。 經(jīng)常有香客問我骡技,道長衩椒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮毛萌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喝滞。我一直安慰自己阁将,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布右遭。 她就那樣靜靜地躺著做盅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窘哈。 梳的紋絲不亂的頭發(fā)上吹榴,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音滚婉,去河邊找鬼图筹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛让腹,可吹牛的內(nèi)容都是我干的远剩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼骇窍,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼瓜晤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腹纳,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤痢掠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后嘲恍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體足画,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蛔钙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锌云。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吁脱,死狀恐怖桑涎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兼贡,我是刑警寧澤攻冷,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站遍希,受9級(jí)特大地震影響等曼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一禁谦、第九天 我趴在偏房一處隱蔽的房頂上張望胁黑。 院中可真熱鬧,春花似錦州泊、人聲如沸丧蘸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽力喷。三九已至,卻和暖如春演训,著一層夾襖步出監(jiān)牢的瞬間弟孟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工样悟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拂募,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓乌奇,卻偏偏與公主長得像没讲,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子礁苗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容