最近一月實習入職,體驗了一把 994 的生活 (由於週三我學校還有課,一週實習四天),也算是馬老師口中的 「身在福中」 了,雖然非常疲憊,可是確實收穫頗多,公司裏面不少不少大佬,於我眼界、技術、想法都提高增益了不少,特別是技術,我一個一直在學習 Vue 的菜虛鯤忽然進了 React 項目組,羊入狼羣,不知所措,不過還好的是有點 Vue 的底子,因此學起來也不算太難...javascript
這個月也一直在負責搭建一個相似螞蟻金服的設計語言網站,受益不淺,項目也差很少完成了,立刻上線了,因此也花些時間理一理這個項目的技術實現,由於是公司項目,爲了保密(不失業),因此我這裏不會貼任何源代碼,由於我這個項目與螞蟻金服的 AntDesign 非常類似,因此我以後的介紹都以 AntDesign 爲例 伏願:不現魚之相,仍識漁之意,一道非漁之魚,君其饗之!css
先放一張 AntDesign 的官網截圖html
開始剖析:前端
其實整個站點結構極其簡單,我已經都畫出來了:java
- 數據驅動 DOM,將一些靜態的數據抽離出來,避免臃腫重複的 DOM 結構
- 組件化,使各個頁面類似的結構抽離出來,造成一個組件
相似 FreeMarker 模版引擎,不過不一樣於 FreeMaker 依託於 Java 相得益彰, Mustache 是根正苗紅的前端模板引擎,十分友好好上手,語法和應用搭配 React 簡直不要太爽node
利用 Sass 不再用寫麪條同樣的臃腫醜陋的 CSS 了,其中的對於 CSS 變量,函數,CSS 結構的拓展優化很是得好,又由於瀏覽器只會識別 CSS 文件,這時候須要 Gulp 自動化構建工具了,Gulp 不只僅能夠將 Sass 文件打包成 CSS 文件,並且能夠作到自動化構建,巴拉巴拉……具體可自行了解react
當進行大型項目開發的時候,項目組不止一我的在開發,並且項目在版本迭代的時候須要維護,這時候代碼規範就極其重要了 ##技術實現 以上介紹了大概介紹了技術棧,那麼接下來就是怎麼實現螞蟻金服的 AntDesign 的技術實現了!So,讓咱們一層層揭下AntDesign 的
衣服面紗吧! #####組件化 在前文中我就提到: React 的好處之一:將各個頁面類似的結構抽離出來,造成一個組件 AntDesign 站點網頁的頭部,底部,側邊欄,錨點定位欄,先後頁跳轉都是結構相同的部分,因此這些均可以抽離出來,放置在一個Components
文件夾中,單獨成一個組件,文件目錄相似這樣:jquery
Components
|—— Header.js
|—— NavBar.js
|—— PageNav.js
|—— PageTurn.js
└── Footer.js
複製代碼
頭部和尾部結構並不複雜,並且可能是靜態的固定的數據,因此能夠直接寫,而後引入各個頁面中數組
側邊欄能夠直接寫樣式,經過重複的 DOM 結構堆砌而成 可是能夠利用 React 的好處之二:數據驅動 DOM,將一些靜態的數據抽離出來,避免臃腫重複的 DOM 結構 1.將側邊導航欄的內容數據抽成一個數組,獨立在在一個獨立的
NavData.js
文件中而後export
出去 2.在NavBar.js
中引入NavData.js
,經過Array.map()
方法將數組依次遍歷而後生成重複的相同DOM瀏覽器
Example:
export const allMenus = [
{
text: 'Ant Design',
type: 'design',
menus: [
{ text: '介紹', type: 'design1', url: '/design/introduce.html' },
{ text: '設計價值觀', type: 'design2', url: '/design/design-values.html' },
{ text: '實踐案例', type: 'design3', url: '/design/practice-case.html' },
],
},
{
text: '原則',
type: 'principle',
menus: [
...//省略原則的子選項
],
},
...//省略後續的菜單選項
];
複製代碼
能夠將菜單欄的菜單如此抽出構成一個數組,而後將數組 allMenus
遍歷生成 DOM
allMenus
#####正文內容渲染 正文內容每頁都不同,因此是沒法抽離成組件的,因此這個須要單獨寫,可是每個 HTML 文件除<body></body>
標籤其中的內容不同,其餘均可以複用,因此這時候 Mustache 就派上用場了:render()
中寫頁面內容 DOMexport
出去,這樣就能在寫錨點定位欄組件和頁面跳轉組件的時候使用props
接收數據export
出來的數據內容,即相似上文的將導航欄抽成一個數組同樣,同理,將全部的頁面也抽成一個數組,以後就能夠再使用Array.map()
方法,配合 Mustache 一一將 React 渲染成 html 文件 Example: 我用 AntDesign 菜單欄的第一項 'Ant Design' 的 '介紹' 頁面爲例:
每一個頁面有本身的頭部菜單類別(headType)、主菜單類別(firstType)、子菜單類別(subType)、錨點內容(affixList),那麼咱們就能夠直接在頁面中定製化而後暴露出去:
import React, { Component } from 'react';
export default class Introduce extends Component {
render() {
return (
<div className="content">
{/* '介紹' 頁面的 DOM 結構*/}
</div>
);
}
}
Introduce.headType = 'design';
Introduce.firstType = 'design';
Introduce.subType = 'design1';
Introduce.affixList = [
'設計資源',
'前端實現',
'誰在使用',
'社區評價',
'如何貢獻',
];
複製代碼
以此類推,建立這麼一個數組,來管理這麼多的頁面數據:
import Introduce from '../src/pages/design/Introduce';
import DesignValues from '../src/pages/design/DesignValues';
import PracticeCase from '../src/pages/design/PracticeCase';
...//將每一個頁面 export 的都引進來
export const allPages = [
{
mainCpn: Introduce,
title: '介紹',
name: 'design/introduce.html',
},
{
mainCpn: DesignValues,
title: '設計價值觀',
name: 'design/design-values.html',
},
{
mainCpn: BarrierFree,
title: '實踐案例',
name: 'design/practice-case.html',
},
...//省略其餘頁面
];
複製代碼
base.html
做爲渲染的基礎模版,在<body></body>
中定義一個變量,做爲 Mustache 內容填充的插槽:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{title}}</title>
<link rel="stylesheet" href="/css/base.css?v={{version}}" />
</head>
<body>
<div id="app">{{{ssrHtml}}}</div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script type="text/javascript" src="/js/base.js?v={{version}}"></script>
</html>
複製代碼
fs
這個 node 模塊讀取base.html
的內容,而後做爲 Mustache.render()
方法的渲染對象參數,再將以前構建好的頁面數組賦值給 base.html
定義好的變量 ssrHtml ,再一一遍歷做爲被渲染對象,而後再使用fs
寫出各個 HTML 文件如此這般,最後便生成了整個項目的目錄文件 哦,對了,爲何會引入了 Jquery? 由於這個項目有自適應,因此會有動畫和操做 DOM ,並且 React 只是單純地直接渲染 DOM ,沒有操做數據來驅動 DOM ,因此沒有和 Jq 衝突,因此能夠放心地使用 Jq (其實用到 Jq 的地方也很少,就一些滾動監聽之類的幾個方法)
其實有不少細節的,可是不少細節一聊就暴露我這個公司項目的源碼啊什麼的了,並且因爲時間實力緣由,可能不少問題講不清晰,歡迎留言私信!定當改進加勉!