1.前情提要
- 最近我司官網(wǎng)重構(gòu),一個(gè)官網(wǎng)配一個(gè)后臺(tái),目的是動(dòng)態(tài)配置官網(wǎng)內(nèi)容,以前都是數(shù)據(jù)庫寫死的,為了更好的運(yùn)營(yíng)網(wǎng)站,體現(xiàn)品牌影響力,于是有了這一次大變革。
2.需求分析
需求不復(fù)雜,基本就是幾大模塊的動(dòng)態(tài)設(shè)置,產(chǎn)品介紹,新聞,職位等等。 既然是企業(yè)官網(wǎng),就要考慮到幾點(diǎn)問題:
- seo
- 界面快速響應(yīng),帶來更好的用戶體驗(yàn)
我們都知道,單頁應(yīng)用兩大致命缺點(diǎn),一個(gè)就是seo不友好,另一個(gè)就是白屏?xí)r間較長(zhǎng)。所謂seo就是搜索引優(yōu)化,簡(jiǎn)單來說,單頁應(yīng)用dom結(jié)構(gòu)都是js動(dòng)態(tài)生成的,而爬蟲更喜歡靜態(tài)頁面,故單頁應(yīng)用不利于seo。而白屏加載主要是因?yàn)閱雾搼?yīng)用加載組件需要消耗時(shí)間,所以帶來不友好的用戶體驗(yàn)。這兩點(diǎn)在后臺(tái)管理上表現(xiàn)不明顯,但是用在企業(yè)官網(wǎng)或者博客之類的網(wǎng)站,就需要想辦法解決。
解決以上兩種問題的最常用手段就是利用服務(wù)端渲染,所謂服務(wù)端渲染就是服務(wù)器直接返回html結(jié)構(gòu),很久很久以前,前后端不分離的年代,jsp渲染的方式就屬于服務(wù)端渲染。單頁應(yīng)用服務(wù)端渲染的方式一般是使用node作為中間層,加載組件之后,再向前臺(tái)返回html結(jié)構(gòu),react vue也有相應(yīng)的api支持服務(wù)端渲染,但是自己去做比較麻煩,我們可以使用比較成熟的服務(wù)端渲染框架next.js。
3.next.js使用
安裝腳手架
npm install -g create-next-App
生成項(xiàng)目
create-next-app myWebsite
安裝成功之后會(huì)有相應(yīng)的提示:
cd myWebsite
yarn dev
瀏覽器打開localhost:3000,出現(xiàn)以下頁面,就表示一個(gè)項(xiàng)目啟動(dòng)成功了
下圖是腳手架生成完畢的項(xiàng)目結(jié)構(gòu)圖:
我們的主頁面將在pages下面進(jìn)行創(chuàng)建開發(fā),每個(gè)頁面就是一個(gè)路由,index.js為主入口,假如我們?cè)趐ages下創(chuàng)建一個(gè)product文件夾,product文件夾下創(chuàng)建一個(gè)index.js文件,那么在瀏覽器中輸入localhost:3000/product就能訪問到product頁面。
4.具體配置
- 項(xiàng)目中必然涉及組件開發(fā),所以根目錄下創(chuàng)建components文件,所有的組件都放在此文件夾下,注意:按照next.js的規(guī)則,組件內(nèi)是不能發(fā)送請(qǐng)求的,所有的請(qǐng)求需要放在主頁面中。
- 靜態(tài)文件放在哪里呢?例如圖片,css文件等。同樣在根目錄下建立static文件夾,可以在static文件夾下建立images或者css等文件
- 項(xiàng)目的UI框架我們選用antd, 使用npm install antd 或者yarn add antd安裝antd。安裝完畢之后需要配置antd按需加載,這個(gè)時(shí)候,需要在根目錄創(chuàng)建.babelrc文件,在此文件中,加入以下代碼:
{
"presets": ["next/babel"],
"plugins": [
[ "import",
{ "libraryName": "antd",
"style": "less"
} ], [ "@babel/plugin-proposal-decorators",
{ "legacy": true
} ] ] }
- 我們想在項(xiàng)目中使用css的同時(shí)也使用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模塊,這兩個(gè)模塊都是next.js中用來支持使用樣式文件的。使用之前請(qǐng)先npm install 安裝它們。在next.config.js文件中,可以自定義webpack配置,可以看到我這里配置了lessLoaderOption 用于動(dòng)態(tài)設(shè)置antd主題色,distDir,用于聲明打包之后的文件地址,還有一些圖片,svg等加載配置。使用之前都必須安裝其對(duì)應(yīng)的wenpack loader。這樣你的項(xiàng)目中才能使用靜態(tài)圖片等文件。
到此為止已經(jīng)可以正常使用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主題已經(jīng)可以生效了。
當(dāng)你需要在項(xiàng)目中配置跨域,怎么操作呢?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"
},
這樣一整套流程下來,你就可以開心的進(jìn)行業(yè)務(wù)開發(fā)了。 看一下完整的項(xiàng)目結(jié)構(gòu):
其他的next相應(yīng)知識(shí)點(diǎn),大家可以到官網(wǎng)https://nextjs.frontendx.cn/docs查看具體知識(shí)點(diǎn)。
提示:以上流程在進(jìn)行過程中如果提示你缺少某模塊,直接npm install先安裝一下就可以解決。
7.結(jié)語
有部署或者其他開發(fā)方面的問題,可以留下評(píng)論交流。