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先安裝一下就可以解決。
7.結語
有部署或者其他開發方面的問題,可以留下評論交流。