前言:
next.js服務端渲染講真,坑是真不少。
我們這里結合antd構建簡單服務端運用。咱們這里只講最簡單的構建步驟,復雜場景請看官網。咱們要是就是快。
next官網文檔:http://nextjs.frontendx.cn/
1. 安裝腳手架
create-next-app 是next的腳手架會為你搭建好最基本的next框架。
構建步驟
yarn global add create-next-app
create-next-app my-project
cd my-project
yarn dev
經過上述步驟就可以訪問我們的頁面。默認端口是3000,但是經常被占用,所以
我們更改 package.json:
"scripts": {
- "dev": "next",
+ "dev": "next -p 3006",
"build": "next build",
"start": "next start"
},
頁面展示:

2. 加入antd
安裝antd和按需加載的babel-plugin-import。
yarn add antd babel-plugin-import
目前時間2019年5月,此時的next@8.1.0十分不穩(wěn)定,和antd結合出現(xiàn)了太多的問題,耽誤了我非常多的時間。有位開發(fā)提供了一個穩(wěn)定版本。next@7.0.2,推薦大家都修改下,避免打包和導出靜態(tài)資源出現(xiàn)各種問題。
安裝next@7.0.2
yarn remove next
yarn add next@7.0.2
跟目錄下建立.babelrc
{
"presets": ["next/babel"],
"plugins": [
// 可以使用裝飾器decorator
["@babel/plugin-proposal-decorators", { "legacy": true }],
// 讓我們可以使用根路徑,避免相對路徑的混亂,如import Head from '@/components/Head'
[
"module-resolver",
{
"alias": {
"@": "./"
}
}
],
// 按需加載并且可以使用less的配置
[
"import",
{
"libraryName": "antd",
"style": true
}
]
]
}
對于.babelrc的功能,我們需要安裝以下包:
yarn add @zeit/next-css @zeit/next-less less
yarn add babel-plugin-import
yarn add @babel/plugin-proposal-decorators
yarn add babel-plugin-module-resolver
根目錄有個next.config.js,專門用來修改next以及webpack的配置。更改如下:
const withLess = require('@zeit/next-less');
const WithCss = require('@zeit/next-css');
// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
require.extensions['.less'] = file => {};
}
module.exports = withLess(
WithCss({
lessLoaderOptions: {
modifyVars: {
'primary-color': '#1DA57A'
},
javascriptEnabled: true
}
})
);
其中modifyVars是修改antd的皮膚。
3. 編寫demo
根目錄pages下本身是有index.js,我們建兩個文件夾index.less和user.js,Link就可以直接路由跳轉,不需要配置,還有Router,詳情看官網。
index.js代碼更換
import React, { Fragment } from 'react';
import Link from 'next/link';
import Head from '@/components/Head';
import './index.less';
import { Button} from 'antd';
const Home = () => (
<Fragment>
<Head title={'next-ssr'} />
<h1>歡迎來到next</h1>
{/* Link內需要a標簽,不然爬蟲識別不了,不用a可以加passHref,提高爬蟲識別率 */}
<Link href="/userList" passHref>
<Button type="primary">用戶列表頁</Button>
</Link>
</Fragment>
);
export default Home;
新建的index.less
h1 {
color: green;
}
新建的user.js
const User = () => <h2>我是用戶列表頁</h2>;
export default User;
此時yarn dev,可以看到生效了。
4. 部署
package.json 代碼更改如下:
"scripts": {
"dev": "next -p 3006",
"start": "next start -p 3006",
"build": "next build",
"export": "next build && next export && serve out"
},
yarn build 就可以打包我們的項目,然后yarn start 就可以訪問。
yarn build
yarn start
next 提供輸出靜態(tài)頁面:next export。
serve 是很好用的本地服務器,我想大家都遇到打包后的html,路徑不能直接訪問把,就是因為默認是需要啟動服務才能訪問的,serve完美解決了我們的問題。
yarn global add serve
yarn export
發(fā)布到自己服務器上:
github提供了一個免費的服務器GitHub Pages,這里可以展示自己的靜態(tài)頁面,如寫個博客。
1. 怎么建github項目和關聯(lián)遠程,我這里就不說了,大家百度一下。
2. 更改 package.json,增加了github這個命令,大家可拆分看一下。
"scripts": {
"dev": "next -p 3006",
"start": "next start -p 3006",
"build": "next build",
"export": "next build && next export && serve out",
"github": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add out/ && git commit -m \"Deploy Next.js to gh-pages\" && git subtree push --prefix out origin gh-pages"
}
3. 在next.config.js增加配置:assetPrefix和publicRuntimeConfig
const withLess = require('@zeit/next-less');
const WithCss = require('@zeit/next-css');
// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
require.extensions['.less'] = file => {};
}
const prod = process.env.NODE_ENV === 'production';
module.exports = withLess(
WithCss({
lessLoaderOptions: {
modifyVars: {
'primary-color': '#1DA57A'
},
javascriptEnabled: true
},
// next-antd-ssr這個名字是你github項目名稱
assetPrefix: prod ? '/next-antd-ssr' : '',
publicRuntimeConfig: {
linkPrefix: prod ? '/next-antd-ssr' : ''
}
})
);
4. 將pages下的index.js更改:增加了linkPrefix和link中的as
import React, { Fragment } from 'react';
import Link from 'next/link';
import Head from '@/components/Head';
import './index.less';
import { Button} from 'antd';
import getConfig from 'next-server/config';
const { linkPrefix } = getConfig().publicRuntimeConfig;
const Home = () => (
<Fragment>
<Head title={'next-ssr'} />
<h1>歡迎來到next</h1>
{/* Link內需要a標簽,不然爬蟲識別不了,不用a可以加passHref,提高爬蟲識別率 */}
<Link href="/userList" passHref as={`${linkPrefix}/userList`}>
<Button type="primary">用戶列表頁</Button>
</Link>
</Fragment>
);
export default Home;
5. 執(zhí)行代碼:
yarn github
6. 訪問頁面:大家在github的項目找到setting,往下翻到GitHub Pages,點擊鏈接就可以看到自己寫的靜態(tài)頁面了。


作者的demo
github項目:https://github.com/muyu-zhilu/next-antd-ssr
發(fā)布的靜態(tài)demo:https://muyu-zhilu.github.io/next-antd-ssr/
其他
為什么沒用服務端server.js ?
next.js是默認服務端渲染,例如我們使用koa,是可以自由控制自己的路由,而且還可以寫接口,做全棧開發(fā)。這里貼上我寫的代碼,供大家參考:
- 在根目錄下建立
server.js
const Koa = require('koa');
const next = require('next');
const Router = require('koa-router');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = new Koa();
const router = new Router();
router.get('*', async ctx => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
});
server.use(async (ctx, next) => {
ctx.res.statusCode = 200;
await next();
});
server.use(router.routes());
// 防止出現(xiàn)控制臺報404錯誤
server.use(async (ctx, next) => {
ctx.res.statusCode = 200;
await next();
});
server.listen(3001, () => {
console.log('server is running at http://localhost:3001');
});
});
- 更改
package.json
nodemon可以自動重啟服務,-i ./pages是不需要重啟的路徑。
"scripts": {
"dev": "node ./server.js",
"build": "next build",
"start": "nodemon ./server.js -i ./pages ./components ./utils"
},
結束了,如果喜歡的話,點個?,謝謝。有什么疑問,可以隨時聯(lián)系我。
如果大家不想用next寫服務端,其實是有koa2+react也可以搭建,還有egg.js可以寫企業(yè)級應用。
有個名詞叫同構應用,就是需要seo就用服務端渲染,不需要就用spa客戶端渲染,不得不說路由跳轉速度,spa單頁特別快。所以之后的前端,不僅僅是頁面搭建,而是創(chuàng)造更好體驗的全棧工程師,一起加油吧!