美文网首页
next.js 采坑录(服务端渲染)

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

作者: 沐雨芝录 | 来源:发表于2019-05-23 15:31 被阅读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单页特别快。所以之后的前端,不仅仅是页面搭建,而是创造更好体验的全栈工程师,一起加油吧!

    相关文章

      网友评论

          本文标题:next.js 采坑录(服务端渲染)

          本文链接:https://www.haomeiwen.com/subject/nivvzqtx.html