next.js 采坑錄(服務(wù)端渲染)

前言:

next.js 服務(wù)端渲染講真棱烂,坑是真不少。
我們這里結(jié)合 antd 構(gòu)建簡(jiǎn)單服務(wù)端運(yùn)用喇伯。咱們這里只講最簡(jiǎn)單的構(gòu)建步驟喊儡,復(fù)雜場(chǎng)景請(qǐng)看官網(wǎng)。咱們要是就是快稻据。

next官網(wǎng)文檔:http://nextjs.frontendx.cn/

1. 安裝腳手架

create-next-app 是next的腳手架會(huì)為你搭建好最基本的next框架艾猜。

構(gòu)建步驟
yarn global add create-next-app
create-next-app my-project
cd my-project
yarn dev

經(jīng)過(guò)上述步驟就可以訪問(wèn)我們的頁(yè)面。默認(rèn)端口是3000捻悯,但是經(jīng)常被占用匆赃,所以

我們更改 package.json
"scripts": {
-   "dev": "next",
+   "dev": "next -p 3006",
    "build": "next build",
    "start": "next start"
  },

頁(yè)面展示:

image.png

2. 加入antd

安裝antd和按需加載的babel-plugin-import
yarn add antd babel-plugin-import

目前時(shí)間2019年5月今缚,此時(shí)的next@8.1.0十分不穩(wěn)定算柳,和antd結(jié)合出現(xiàn)了太多的問(wèn)題,耽誤了我非常多的時(shí)間姓言。有位開(kāi)發(fā)提供了一個(gè)穩(wěn)定版本瞬项。next@7.0.2,推薦大家都修改下事期,避免打包和導(dǎo)出靜態(tài)資源出現(xiàn)各種問(wè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 }], 

    // 讓我們可以使用根路徑,避免相對(duì)路徑的混亂兽泣,如import Head from '@/components/Head'
    [
      "module-resolver",
      {
        "alias": {
          "@": "./"
        }
      }
    ],

    // 按需加載并且可以使用less的配置
    [
      "import",
      {
        "libraryName": "antd",
        "style": true
      }
    ]
  ]
}

對(duì)于.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
根目錄有個(gè)next.config.js,專門(mén)用來(lái)修改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. 編寫(xiě)demo

根目錄pages下本身是有index.js,我們建兩個(gè)文件夾index.lessuser.js稠鼻,Link就可以直接路由跳轉(zhuǎn)冈止,不需要配置畜疾,還有Router鹃彻,詳情看官網(wǎng)。

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>歡迎來(lái)到next</h1>

    {/* Link內(nèi)需要a標(biāo)簽稚瘾,不然爬蟲(chóng)識(shí)別不了慌盯,不用a可以加passHref周霉,提高爬蟲(chóng)識(shí)別率 */}

    <Link href="/userList" passHref>
       <Button type="primary">用戶列表頁(yè)</Button>
    </Link>

  </Fragment>
);
export default Home;
新建的index.less
h1 {
  color: green;
}
新建的user.js
const User = () => <h2>我是用戶列表頁(yè)</h2>;
export default User;

此時(shí)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 就可以打包我們的項(xiàng)目俱箱,然后yarn start 就可以訪問(wèn)。
yarn build
yarn start
next 提供輸出靜態(tài)頁(yè)面:next export灭必。

serve 是很好用的本地服務(wù)器狞谱,我想大家都遇到打包后的html乃摹,路徑不能直接訪問(wèn)把,就是因?yàn)槟J(rèn)是需要啟動(dòng)服務(wù)才能訪問(wèn)的跟衅,serve完美解決了我們的問(wèn)題孵睬。

yarn global add serve
yarn export

發(fā)布到自己服務(wù)器上:

github提供了一個(gè)免費(fèi)的服務(wù)器 GitHub Pages,這里可以展示自己的靜態(tài)頁(yè)面与斤,如寫(xiě)個(gè)博客肪康。

1. 怎么建github項(xiàng)目和關(guān)聯(lián)遠(yuǎn)程,我這里就不說(shuō)了撩穿,大家百度一下磷支。
2. 更改 package.json,增加了github這個(gè)命令食寡,大家可拆分看一下雾狈。
"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增加配置:assetPrefixpublicRuntimeConfig
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這個(gè)名字是你github項(xiàng)目名稱
    assetPrefix: prod ? '/next-antd-ssr' : '',
    publicRuntimeConfig: {
      linkPrefix: prod ? '/next-antd-ssr' : ''
    }
  })
);
4. 將pages下的index.js更改:增加了linkPrefixlink中的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>歡迎來(lái)到next</h1>

    {/* Link內(nèi)需要a標(biāo)簽,不然爬蟲(chóng)識(shí)別不了抵皱,不用a可以加passHref善榛,提高爬蟲(chóng)識(shí)別率 */}

    <Link href="/userList" passHref as={`${linkPrefix}/userList`}>
       <Button type="primary">用戶列表頁(yè)</Button>
    </Link>

  </Fragment>
);
export default Home;
5. 執(zhí)行代碼:
yarn github
6. 訪問(wèn)頁(yè)面:大家在github的項(xiàng)目找到setting,往下翻到GitHub Pages呻畸,點(diǎn)擊鏈接就可以看到自己寫(xiě)的靜態(tài)頁(yè)面了移盆。
image.png

image.png

作者的demo

github項(xiàng)目:https://github.com/muyu-zhilu/next-antd-ssr
發(fā)布的靜態(tài)demo:https://muyu-zhilu.github.io/next-antd-ssr/

其他

為什么沒(méi)用服務(wù)端server.js ?

next.js是默認(rèn)服務(wù)端渲染伤为,例如我們使用koa咒循,是可以自由控制自己的路由,而且還可以寫(xiě)接口绞愚,做全棧開(kāi)發(fā)叙甸。這里貼上我寫(xiě)的代碼,供大家參考:

  1. 在根目錄下建立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)控制臺(tái)報(bào)404錯(cuò)誤
  server.use(async (ctx, next) => {
    ctx.res.statusCode = 200;
    await next();
  });

  server.listen(3001, () => {
    console.log('server is running at http://localhost:3001');
  });
});
  1. 更改package.json

nodemon可以自動(dòng)重啟服務(wù)位衩,-i ./pages是不需要重啟的路徑裆蒸。

"scripts": {
    "dev": "node ./server.js",
    "build": "next build",
    "start": "nodemon ./server.js  -i ./pages ./components ./utils"
  },

結(jié)束了,如果喜歡的話糖驴,點(diǎn)個(gè)?僚祷,謝謝。有什么疑問(wèn)贮缕,可以隨時(shí)聯(lián)系我久妆。
如果大家不想用next寫(xiě)服務(wù)端,其實(shí)是有koa2+react也可以搭建跷睦,還有egg.js可以寫(xiě)企業(yè)級(jí)應(yīng)用。

有個(gè)名詞叫同構(gòu)應(yīng)用肋演,就是需要seo就用服務(wù)端渲染抑诸,不需要就用spa客戶端渲染烂琴,不得不說(shuō)路由跳轉(zhuǎn)速度,spa單頁(yè)特別快蜕乡。所以之后的前端奸绷,不僅僅是頁(yè)面搭建,而是創(chuàng)造更好體驗(yàn)的全棧工程師层玲,一起加油吧号醉!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辛块,隨后出現(xiàn)的幾起案子畔派,更是在濱河造成了極大的恐慌,老刑警劉巖润绵,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件线椰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尘盼,警方通過(guò)查閱死者的電腦和手機(jī)憨愉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卿捎,“玉大人配紫,你說(shuō)我怎么就攤上這事∥缯螅” “怎么了躺孝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)趟庄。 經(jīng)常有香客問(wèn)我括细,道長(zhǎng),這世上最難降的妖魔是什么戚啥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任奋单,我火速辦了婚禮,結(jié)果婚禮上猫十,老公的妹妹穿的比我還像新娘览濒。我一直安慰自己,他們只是感情好拖云,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布贷笛。 她就那樣靜靜地躺著,像睡著了一般宙项。 火紅的嫁衣襯著肌膚如雪乏苦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音汇荐,去河邊找鬼洞就。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掀淘,可吹牛的內(nèi)容都是我干的旬蟋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼革娄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼倾贰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拦惋,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤匆浙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后架忌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吞彤,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年叹放,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饰恕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡井仰,死狀恐怖埋嵌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情俱恶,我是刑警寧澤雹嗦,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站合是,受9級(jí)特大地震影響了罪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜聪全,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一泊藕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧难礼,春花似錦娃圆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谦炬,卻和暖如春悦屏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工础爬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留散劫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓幕帆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赖条。 傳聞我的和親對(duì)象是個(gè)殘疾皇子失乾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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