next.js 采坑录(服务端渲染)

2019-05-23  本文已影响0人  沐雨芝录

前言:

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单页特别快。所以之后的前端,不仅仅是页面搭建,而是创造更好体验的全栈工程师,一起加油吧!

上一篇下一篇

猜你喜欢

热点阅读