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十分不稳定,和antd结合出现了太多的问题,耽误了我非常多的时间。有位开发提供了一个稳定版本。next@7.0.2,推荐大家都修改下,避免打包和导出静态资源出现各种问题。

安装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.jsLink就可以直接路由跳转,不需要配置,还有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 提供输出静态页面:next export

serve 是很好用的本地服务器,我想大家都遇到打包后的html,路径不能直接访问把,就是因为默认是需要启动服务才能访问的,serve完美解决了我们的问题。

yarn global add serve
yarn export

发布到自己服务器上:

github提供了一个免费的服务器 GitHub Pages,这里可以展示自己的静态页面,如写个博客。

1. 怎么建github项目和关联远程,我这里就不说了,大家百度一下。
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. 执行代码:
yarn github
6. 访问页面:大家在github的项目找到setting,往下翻到GitHub Pages,点击链接就可以看到自己写的静态页面了。
image.png

image.png

作者的demo

github项目:https://github.com/muyu-zhilu/next-antd-ssr
发布的静态demo:https://muyu-zhilu.github.io/next-antd-ssr/

其他

为什么没用服务端server.js ?

next.js是默认服务端渲染,例如我们使用koa,是可以自由控制自己的路由,而且还可以写接口,做全栈开发。这里贴上我写的代码,供大家参考:

  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());

  // 防止出现控制台报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"
  },

结束了,如果喜欢的话,点个✨,谢谢。有什么疑问,可以随时联系我。
如果大家不想用next写服务端,其实是有koa2+react也可以搭建,还有egg.js可以写企业级应用。

有个名词叫同构应用,就是需要seo就用服务端渲染,不需要就用spa客户端渲染,不得不说路由跳转速度,spa单页特别快。所以之后的前端,不仅仅是页面搭建,而是创造更好体验的全栈工程师,一起加油吧!

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

推荐阅读更多精彩内容