Next.js

我们为开源的Next.js感到非常自豪,它是一个服务器渲染的通用JavaScript webapps的小型框架,建立在React,Webpack和Babel的基础之上。

要开始使用它,在一个新的目录中运行: package.json

$ npm install next --save
$ mkdir pages

填充pages/index.js:

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

package.json像这样添加一个脚本:

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

并运行:

$ npm run dev

这篇博客文章将涉及项目的理念和设计决策。

要学习如何使用Next.js,请参阅自述文件,您可以在几分钟内了解该工具的全部功能。

首先我们将深入到项目的背景,然后描述6个基本原则:

  1. 零设置。使用文件系统作为API
  2. 只有JavaScript。一切都是一个功能
  3. 自动服务器呈现和代码分割
  4. 数据获取取决于开发者
  5. 预期是表现的关键
  6. 简单部署

背景

多年来,我们一直在追求通用JavaScript应用程序的愿景。

Node.js引导了客户端和服务器之间的代码共享,拓宽了世界各地许多开发者的贡献面。

许多尝试都是为了在Node上开发应用程序和网站而设计的。许多模板语言和框架出现了......但是前端和后端之间的技术鸿沟依然存在。

例如,如果你选择了Express和Jade,一些HTML将被服务器渲染,然后一个不同的代码库 (由jQuery或类似的库支持)将接管。

这种情况实际上并不比PHP的好。在许多方面,PHP实际上更适合于“服务器呈现HTML”作业。在异步/等待之前,很难在JS中查询数据服务。将错误限制在请求/响应的范围之内也是非常困难的。

然而,从那以后,显着的概念上的变化使我们能够缩小这个差距。其中最重要的是引入了纯渲染函数,该函数根据当时的可用数据返回UI的表示形式。

这个模型(被React普及)是非常重要的,但是这与大多数模板系统的工作原理没有什么不同。另一个关键概念是组件生命周期

生命周期钩子允许我们处理源自服务器的一些渲染的延续。例如,您可以从数据的静态表示开始,订阅来自服务器的实时更新,并随时间变化。或者也许它保持不变。

Next.js是我们如何推动这一愿景的。

零设置。使用文件系统作为API

工具对文件系统中的项目结构做了一些假设。

例如,我们通常通过创建一个新的目录,放置一个package.json内部,然后安装模块来启动一个Node.js项目./node_modules。

Next.js通过引入pages 顶级组件所在的子目录来扩展该结构。

例如,您可以使用以下命令来填充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>

我们相信这是一个很好的默认开始,并允许一个项目的快速探索。当需要更高级的路由时,我们将允许开发人员拦截请求并采取控制。

所有需要开始工作的项目是运行:

$ next

没有配置,除非需要。自动热码重新加载,错误报告,源地图,旧版浏览器的转换。

只有JavaScript。一切都是一个功能

Next.js中的每个路由只是一个ES6模块,用于导出一个扩展的函数或类React.Component。

这种方法与类似模型相比的优点是整个系统仍然是高度可组合和可测试的。例如,一个组件可以被直接渲染,或者被另一个顶层组件导入和渲染。

组件也可以引入对页面的更改: <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>
)

此外,不需要包装或转换,使这个系统完全可测试。您的测试套件可以简单地导入和浅显渲染您的路线。

我们也决定采用CSS-in-JS。我们使用优秀的glamor库,给我们完全不受限制的CSS的权力,而不需要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'
  }
})

我们认为这个模型提供了卓越的性能,可组合性和与服务器渲染流水线的集成。

自动服务器呈现和代码分割

迄今为止,两项任务同时非常困难和非常可取:

服务器渲染

  • 将应用程序的构建分割成更小的包
  • 使用Next.js,每个内部组件pages/都会自动获取服务器并且内联脚本。

当通过或路由器动态加载组件时,我们获取一个基于JSON的页面表示,同样包含它的脚本。 <Link prefetch />

这意味着某个页面可能有一个广泛的导入列表:

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

...不影响其他页面的性能。

这个细节对于那些在技术和业务需求截然不同的组件上进行协作的大型团队来说特别有用。团队或个人的表现处罚不会影响组织的其余部分。

数据获取取决于开发者

静态JSX的服务器渲染是一个重要的成就,但真实世界的应用程序处理来自不同的API调用和网络请求的动态数据。

Next.js对React组件合同做了非常重要的扩展:getInitialProps。

提取一些数据的页面如下所示:

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 }
  }
}

我们对于什么样的功能(像异步/等待)的立场可以概括为:我们的目标是V8的功能。由于我们的目标是在服务器和客户端之间进行代码共享,所以在执行Node上的代码以及在Chrome或Brave上开发时,这给我们带来了很好的性能。

正如你所看到的那样,契约是非常简单而且不可选择的:必须返回一个解析成JavaScript的对象,然后填充组件。 getInitialPropsPromise props

这使得Next.js在REST API,GraphQL甚至是全局状态管理库Redux上都能很好地发挥作用,在我们的wiki上你可以找到它的一个例子。

同样的方法允许加载不同的数据,这取决于组件是通过服务器呈现的还是通过客户端路由动态呈现的:

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容