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

前言:

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

頁面展示:

image.png

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.lessuser.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增加配置: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這個名字是你github項目名稱
    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>歡迎來到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)頁面了。
image.png

image.png

作者的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ā)。這里貼上我寫的代碼,供大家參考:

  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)控制臺報404錯誤
  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可以自動重啟服務,-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)造更好體驗的全棧工程師,一起加油吧!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容