记一次使用next.js开发官网经历

11,376 阅读5分钟

1.前情提要

  • 最近我司官网重构,一个官网配一个后台,目的是动态配置官网内容,以前都是数据库写死的,为了更好的运营网站,体现品牌影响力,于是有了这一次大变革。

2.需求分析

需求不复杂,基本就是几大模块的动态设置,产片介绍,新闻,职位等等。 既然是企业官网,就要考虑到几点问题:

  • SEO
  • 界面快速响应,带来更好的用户体验

我们都知道,单页应用两大致命缺点,一个就是seo不友好,另一个就是白屏时间较长。所谓seo就是搜索引优化,简单来说,单页应用dom结构都是js动态生成的,而爬虫更喜欢静态页面,故单页应用不利于seo。而白屏加载主要是因为单页应用加载组件需要消耗时间,所以带来不友好的用户体验。这两点在后台管理上表现不明显,但是用在企业官网或者博客之类的网站,就需要想办法解决。

解决以上两种问题的最常用手段就是利用服务端渲染,所谓服务端渲染就是服务器直接返回html结构,很久很久以前,前后端不分离的年代,jsp渲染的方式就属于服务端渲染。单页应用服务端渲染的方式一般是使用node作为中间层,加载组件之后,再向前台返回html结构,react vue也有响应的api支持服务端渲染,但是自己去做比较麻烦,我们可以使用比较成熟的服务端渲染框架next.js。

3.next.js使用

安装脚手架

npm install -g create-next-app

生成项目

create-next-app myWebsite

安装成功之后会有相应的提示:

cd myWebsite

yarn dev

浏览器打开localhost:3000,出现以下页面,就表示一个项目启动成功了

下图是脚手架生成完毕的项目结构图:

我们的主页面将在pages下面进行创建开发,每个页面就是一个路由,index.js为主入口,假如我们在pages下创建一个product文件夹,product文件夹下创建一个index.js文件,那么在浏览器中输入localhost:3000/product就能访问到product页面。

4.具体配置

  • 项目中必然涉及组件开发,所以根目录下创建components文件,所有的组件都放在此文件夹下,注意:按照next.js的规则,组件内是不能发送请求的,所有的请求需要放在主页面中。

  • 静态文件放在哪里呢?例如图片,css文件等。同样在根目录下建立static文件夹,可以在static文件夹下建立images或者css等文件

  • 项目的UI框架我们选用antd, 使用npm install antd 或者yarn add antd安装antd。安装完毕之后需要配置antd按需加载,这个时候,需要在根目录创建.babelrc文件,在此文件中,加入以下代码:

{
    "presets": ["next/babel"],
    "plugins": [
      [
        "import",
        {
          "libraryName": "antd",
          "style": "less"
        }
      ],
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ]
    ]
  }
  • 我们想在项目中使用css的同时也使用less文件,改怎么做呢?在根目录下建立next.config.js文件,在此文件中加入以下代码:
const withCss = require("@zeit/next-css");
const widthLess = require('@zeit/next-less');
if (typeof require !== 'undefined') {
    require.extensions['.css'] = file => { }
}

module.exports = widthLess(withCss({
  lessLoaderOptions: {
    javascriptEnabled: true,
    importLoaders: 1,
    localIdentName: "[local]___[hash:base64:5]",
  },
  distDir: 'build',
  webpack: (config, { dev }) => {
      config.module.rules.push(
          {
            test: /\.(png|jpg|svg|eot|otf|ttf|woff|gif|woff2)$/,
            use: {
              loader: "url-loader?limit=8024",
              options: {
                name: "[name].[ext]"
              }
            }
          },
          {
              test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
              loader: require.resolve('file-loader'),
              options: {
                  name: '/static/media/[name].[hash:8].[ext]'
              }
          }
      )
      // config.plugins.push(new CleanWebpackPlugin())
      return config
  }
}))

可以看到我们使用了@zeit/next-css 和@zeit/next-less模块,这两个模块都是next.js中用来支持使用样式文件的。使用之前请先npm install 安装它们。在next.config.js文件中,可以自定义webpack配置,可以看到我这里配置了lessLoaderOption 用于动态设置antd主题色,distDir,用于声明打包之后的文件地址,还有一些图片,svg等加载配置。使用之前都必须安装其对应的wenpack loader。这样你的项目中才能使用静态图片等文件。

到此为止已经可以正常使用antd,但是如果你想自定义antd主题色,怎么处理? 根目录新建asserts文件夹,文件夹中建立antd-customs.less 和styles.les文件,分别加入以下css样式

@primary-color: #29CCB1;

@layout-header-height: 40px;
@border-radius-base: 4px;
@import "~antd/dist/antd.less";
@import "./antd-custom.less";

然后在pages下建立_app.js文件,在文件中加入以下代码

import App from 'next/app'
import '../asserts/styles.less'


export default App

ok,你自定义的antd主题已经可以生效了。

当你需要在项目中配置跨域,怎么操作呢?next.js支持自定义server。同样在根目录下,新建server.js, 加入如下代码:

// server.js
const express = require('express')
const next = require('next')
const { createProxyMiddleware  } = require('http-proxy-middleware')

const devProxy = {
    '/api/v': {
        target: 'http://192.168.3.18:8092', // 端口自己配置合适的
        // pathRewrite: {
        //     '^/api': '/'
        // },
        changeOrigin: true
    }
}

const port = parseInt(process.env.PORT, 10) || 80
const dev = process.env.NODE_ENV !== 'production'
const app = next({
    dev
})
const handle = app.getRequestHandler()

app.prepare()
    .then(() => {
        const server = express()

        if (dev && devProxy) {
            Object.keys(devProxy).forEach(function(context) {
                server.use(createProxyMiddleware (context, devProxy[context]))
            })
        }
        server.all('*', (req, res) => {
            handle(req, res)
        })

        server.listen(port, err => {
            if (err) {
                throw err
            }
            console.log(`> Ready on http://localhost:${port}`)
        })
    })
    .catch(err => {
        console.log('An error occurred, unable to start the server')
        console.log(err)
    })

然后 在package.json文件中 配置:

  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "cross-env NODE_ENV=production node server.js"
  },

这样一整套流程下来,你就可以开心的进行业务开发了。 看一下完整的项目结构:

其他的next相应知识点,大家可以到官网https://nextjs.frontendx.cn/docs查看具体知识点。

提示:以上流程在进行过程中如果提示你缺少某模块,直接npm install先安装以下就可以解决。

5.结语

有部署或者其他开发方面的问题,可以留下评论交流。谨以此文献给从未使用过next.js的小伙伴,助你快速入门

本文使用 mdnice 排版