next.js 是一个轻量级的react同构框架,使用它可以快速的开发出基于服务端渲染的react应用。它在支持ssr的同时支持快速导出静态站点,相比与常规的SPA页面,利用ssr我们能够得到更好的SEO和首屏响应时间等。这次恰好赶上从零开始的海外wap主站项目,借此机会一探next.js的究竟。之前组内使用的前后端同构脚手架是react-starter-kit,它很不错但总感觉有点重;一直想找机会试一试React官方推荐的Next,so~~机会来啦!
是什么
- a lightweight framework for static and server‑rendered applications built with React.
- includes styling and routing solutions out of the box
特点
- 轻量
- 默认支持ssr
- 自动 code splitting
- 简洁的路由 (page based)
- HMR & 明确的错误提示
- 自由组合Express等Node.js HTTP server
- Babel 、Webpack等零配置&可扩展
开始一个next项目
1 | mkdir hello-next |
package.json:
1 | "scripts": { |
路由
pages即路由:根据pages目录默认生成路由配置
路由:
- / : pages/index.js
- /about : pages/about.js
- /a : pages/a/index.js
- /b/c : pages/b/c/index.js
问题1:a/index.js 与a.js 谁的优先级高
问题2:动态路由(稍后解决)
client side Routing
with
1 | import Link from 'next/link' |
常用属性:
- prefetch
- URL object
- Replace
Imperatively
1 | import Router from 'next/router' |
- Router包含以下属性&API : route/pathname/query/asPath/push/replace等
- Router内包含事件 : routeChangeStart/routeChangeComplete/routeChangeError/beforeHistoryChange/hashChangeStart/hashChangeComplete
1 | e.g. |
Higher Order Component
1 | import { withRouter } from 'next/router' |
组件被注入router props,其包含属性同 next/router
.
Custom server and routing
- client side:利用asPath属性
- server side:自定义server.js
- package.json:修改scripts
asPath
1 | <Link href="/a/b" as="/ab"> |
Next称之为:Clean URLs with Route Masking
但这就存在个问题,这样可以做到client 端路由跳转
当手动刷新如/course/detail/2这种路由,server端认识吗?
server.js
1 | const express = require('express') |
package.json
1 | "scripts": { |
styled-jsx
1 | function HelloWorld() { |
其他css解决方案:
- @zeit/next-css
- @zeit/next-sass
- @zeit/next-less
- @zeit/next-stylus
Fetching data & component lifecycle
getInitialProps
1 | class HelloUA extends React.Component { |
- Next提供了一个新的生命周期:getInitialProps
- 只允许用于pages,不支持子组件中使用
- 在页面加载时执行,并将返回的Object作为props
- 页面首次加载只会在服务端执行,之后通过路由API或者Link组件跳转,才会在客户端执行
- 接收一个context对象,包含:
- pathname - path section of URL
- query - query string section of URL parsed as an object
- asPath - String of the actual path (including the query) shows in the browser
- req - HTTP request object (server only)
- res - HTTP response object (server only)
- err - Error object if any error is encountered during the rendering
Static file serving
- 根目录下创建static文件夹
- 通过’/static/xxx’引用静态文件
- 建议按照这个约定来,后面方便使用官方提供的配置项配置cdn
Note: Don’t name the static directory anything else. The name is required and is the only directory that Next.js uses for serving static assets.
next.config.js
1 | const withCSS = require('@zeit/next-css') |
head 、document、error
head
1 | import Head from 'next/head' |
为避免标签重复,可以使用key属性
_document.js
1 | import Document, { Html, Head, Main, NextScript } from 'next/document' |
- Is rendered on the server side
- Is used to change the initial server side rendered document markup
- Commonly used to implement server side rendering for css-in-js libraries like styled-components or emotion. styled-jsx is included with Next.js by default.
_error.js
404 或 500 错误 next会自动渲染到内置的error.js. 若希望自定义error页面,创建_error.js即可
1 | class Error extends React.Component { |
next-routes
- 为了简化next原生路由系统在动态路由的规划上复杂的部分
- 符合Express风格的路由参数匹配
- 方便为请求处理添加中间件
- 主要还是看着清爽、用着也简单
1 | const routes = require('next-routes') |
lru-cache
基于“最近最少使用”的服务端缓存