前端技術(shù)更新可以說(shuō)是“白駒過(guò)隙”当娱,如何搭建一個(gè)合格的前端架構(gòu)能夠適配我們現(xiàn)在快速迭代和千變?nèi)f化的迭代需求呢考榨?我認(rèn)為要通過(guò)(規(guī)范制定冀惭,模塊化管理云头,組件管理溃槐,自動(dòng)化打包測(cè)試)
規(guī)范制定
如圖所示 想找到孩子的玩具 是非常困難的 熊孩子都是調(diào)皮的 那怎么讓這些熊孩子的玩具都能放在該放的地方呢 昏滴。最好的辦法就是 不在規(guī)定地方的玩具不能玩谣殊。
對(duì)于我們的 代碼也是? 相應(yīng)的規(guī)范可以讓自己和團(tuán)隊(duì)程序員更加容易理解代碼 梳理邏輯 也能讓程序員保持良好的心情? 主要規(guī)范有以下幾點(diǎn)
1 CSS規(guī)范
? ? ? ?戳我查看CSS規(guī)范
2 HTML規(guī)范
? ? ? 戳我查看HTML規(guī)范
3 JS規(guī)范
? ? ? ?戳我查看JS規(guī)范
4 文件目錄規(guī)范
5 GIT使用發(fā)布規(guī)范
? ? ?戳我查看git常用命令
6 接口規(guī)范
? ? 戳我查看阿里云前后端分離之API規(guī)范
7 UI規(guī)范
8 組件數(shù)據(jù)傳遞規(guī)范
?模塊化管理
什么是模塊化思想呢,簡(jiǎn)單說(shuō)就是 做該做的事情 具有原子性 單一性 例如 一個(gè)臺(tái)電腦 需要 CPU 需要主板? 電源 組裝 起來(lái)? 抚恒,模塊化的意思就是 電源只做電源的事情 那就是供電 俭驮,至于是給風(fēng)扇供電 還是給CPU供電 他是不用知道的混萝,電源只需要暴露一個(gè) 接口 參數(shù)是需要多少伏的電即可逸嘀。于此同理 模塊化就是 單一功能的拆分
模塊化是指在解決某一個(gè)復(fù)雜問(wèn)題或者一系列的雜糅問(wèn)題時(shí)崭倘,依照一種分類(lèi)的思維把問(wèn)題進(jìn)行系統(tǒng)性的分解以之處理绳姨。模塊化是一種處理復(fù)雜系統(tǒng)分解為代碼結(jié)構(gòu)更合理阔挠,可維護(hù)性更高的可管理的模塊的方式∏聪桑可以想象一個(gè)巨大的系統(tǒng)代碼揩局,被整合優(yōu)化分割成邏輯性很強(qiáng)的模塊時(shí)凌盯,對(duì)于軟件是一種何等意義的存在驰怎。
在團(tuán)隊(duì)開(kāi)發(fā)的過(guò)程中如果不考慮模塊化會(huì)遇到下列問(wèn)題:
命名沖突:每個(gè)人都有自己的開(kāi)發(fā)習(xí)慣,或者說(shuō)開(kāi)發(fā)過(guò)程中新老交替,模塊復(fù)雜就會(huì)導(dǎo)致命名一樣的情況 比如js装获,都是時(shí)間的意思那么就會(huì)出現(xiàn)下面的代碼
var time = "" //界面A
var time = ""http://界面B
代碼重復(fù):一個(gè)小小的時(shí)間日期格式化函數(shù)可能寫(xiě)了30個(gè)版本,有些可能代碼完全相同绩郎,另外CSS也存在這個(gè)問(wèn)題 肋杖,不當(dāng)是命名重復(fù) 還有代碼重復(fù) 功能重復(fù)?
所以這時(shí)候我們需要模塊化開(kāi)發(fā)的概念用來(lái)?提升開(kāi)發(fā)效率和方便后期維護(hù)?
1 JS模塊化?
先說(shuō)說(shuō)Node.js?中關(guān)于module.exports與exorts的區(qū)別
exports = module.exports = {};?
exports是module.exports的一個(gè)引用require引用模塊后,返回給調(diào)用者的是module.exports而不是exportsexports.xxx津畸,相當(dāng)于在導(dǎo)出對(duì)象上掛屬性肉拓,該屬性對(duì)調(diào)用模塊直接可見(jiàn)exports =相當(dāng)于給exports對(duì)象重新賦值暖途,調(diào)用模塊不能訪(fǎng)問(wèn)exports對(duì)象及其屬性如果此模塊是一個(gè)類(lèi),就應(yīng)該直接賦值module.exports欺栗,這樣調(diào)用者就是一個(gè)類(lèi)構(gòu)造器征峦,可以直接new實(shí)例
假如有模塊a.js代碼如下:
exports.str = 'a';
exports.fn = function() {};
對(duì)a模塊的調(diào)用:
var a = require('./a');
console.log(a.str);
console.log(a.fn());
這樣用是對(duì)的瘤旨,如果改造a如下:
exports.str = 'a';
?exports = function fn() {};?
?在調(diào)用a模塊時(shí)自然沒(méi)用fn屬性了因宇。
再改造下a模塊:
exports.str = 'a';?
?module.exports = function fn() {};?
?這時(shí)a模塊其實(shí)就是fn函數(shù)的引用,也就是說(shuō)可以require('./a')()這樣使用贺辰,而同時(shí)不再有str屬性了饲化。
ES6中的模塊化
首先ES6 的模塊自動(dòng)采用嚴(yán)格模式,不管你有沒(méi)有在模塊頭部加上"use strict";巢块。
嚴(yán)格模式主要有以下限制。
變量必須聲明后再使用
函數(shù)的參數(shù)不能有同名屬性丹鸿,否則報(bào)錯(cuò)
不能使用with語(yǔ)句
不能對(duì)只讀屬性賦值越走,否則報(bào)錯(cuò)
不能使用前綴 0 表示八進(jìn)制數(shù),否則報(bào)錯(cuò)
不能刪除不可刪除的屬性卜高,否則報(bào)錯(cuò)
不能刪除變量delete prop弥姻,會(huì)報(bào)錯(cuò)南片,只能刪除屬性delete global[prop]
eval不會(huì)在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會(huì)自動(dòng)反映函數(shù)參數(shù)的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對(duì)象
不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
增加了保留字(比如protected掺涛、static和interface)
ES6的模塊化的特點(diǎn)
每一個(gè)模塊只加載一次, 每一個(gè)JS只執(zhí)行一次疼进, 如果下次再去加載同目錄下同文件薪缆,直接從內(nèi)存中讀取。 一個(gè)模塊就是一個(gè)單例,或者說(shuō)就是一個(gè)對(duì)象区丑;
每一個(gè)模塊內(nèi)聲明的變量都是局部變量魄鸦, 不會(huì)污染全局作用域绢记;
模塊內(nèi)部的變量或者函數(shù)可以通過(guò)export導(dǎo)出;
一個(gè)模塊可以導(dǎo)入別的模塊
export多對(duì)象
export let getStore = function (name) {
? ? return JSON.parse(localStorage.getItem(name))
}
/**
*? 設(shè)置本地存儲(chǔ)書(shū)籍 統(tǒng)一用Object或者Array
*/
export let setStore = function (name, val = {}) {
? ? localStorage.setItem(name, JSON.stringify(val))
}
然后import
import?{a]getStore,setStore} from?'../../export/util.js';
如果不想暴露變量的名稱(chēng):使用as可以重命名關(guān)鍵字
export?{getStore as A, setStore as B} from?'../../export/util.js';
想要了解ES6模塊化的可以點(diǎn)這里ES6模塊化
SASS/LESS模塊化
定義基礎(chǔ)顏色抽高,字體,間距
// Colors
$black:? ? ? ? hsl(0, 0%, 4%) !default
$black-bis:? ? hsl(0, 0%, 7%) !default
$black-ter:? ? hsl(0, 0%, 14%) !default
// Typography
$family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !default
$family-monospace: monospace !default
$render-mode: optimizeLegibility !default
……
定義基礎(chǔ)的方法 工具類(lèi)
定義基礎(chǔ)組件
………………
什么是SASS 戳這里?Sass基本介紹
組件管理
? ?什么是組件
? 組件就是 最原子的DOM結(jié)構(gòu) 和 這些原子組件組成的業(yè)務(wù)組件
?例如 一個(gè)Button 一個(gè)懂拾, CheckBox
?一個(gè)分頁(yè)組件唐断, 一個(gè) 輪播圖組件
?甚至是 一個(gè)訂單提交組件? 支付組件
我們不當(dāng)要知道自己的項(xiàng)目中應(yīng)該使用哪些組件 應(yīng)該拆分哪些組件 而且要理解這些組件之間的關(guān)系 比如 UI組件 業(yè)務(wù)組件?
前面我們已經(jīng)制定了UI規(guī)范那么程序員在寫(xiě)代碼的過(guò)程中 比如一個(gè)按鈕我們完全可以寫(xiě)一些基礎(chǔ)的按鈕庫(kù)讓團(tuán)隊(duì)調(diào)用 典型的例子? bootstrap?
我們來(lái)看看vuetify的按鈕調(diào)用
戳我查看button
其實(shí)很多業(yè)務(wù)組件我們也是可以封裝好的
例如 Vant 甚至把商品的SKU篩選做成了組件
我們?cè)谧銮岸思軜?gòu)的時(shí)候 千萬(wàn)別忘了把這些基礎(chǔ)組件抽離忿墅,用以提高開(kāi)發(fā)效率望薄,方便代碼維護(hù)
另附
自動(dòng)化打包測(cè)試
自動(dòng)化包含了 以下幾點(diǎn)
?1 打包發(fā)布自動(dòng)化
2 HTML JS CSS檢查自動(dòng)化
3 圖片壓縮 靜態(tài)資源壓縮 自動(dòng)化
4 緩存清除自動(dòng)化
5 工具函數(shù)UI組件測(cè)試自動(dòng)化
下面介紹4個(gè)常用的打包工具
工具??webpack
webpack?是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)花嘶。當(dāng) webpack 處理應(yīng)用程序時(shí)拆撼,它會(huì)遞歸地構(gòu)建一個(gè)依賴(lài)關(guān)系圖(dependency graph)留量,其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè)?bundle纸淮。
工具 grunt
為何要用構(gòu)建工具峭竣?
一句話(huà):自動(dòng)化扛吞。對(duì)于需要反復(fù)重復(fù)的任務(wù)键耕,例如壓縮(minification)蚁孔、編譯、單元測(cè)試囤捻、linting等,自動(dòng)化工具可以減輕你的勞動(dòng),簡(jiǎn)化你的工作晴埂。當(dāng)你在?Gruntfile?文件正確配置好了任務(wù),任務(wù)運(yùn)行器就會(huì)自動(dòng)幫你或你的小組完成大部分無(wú)聊的工作捷枯。
工具glup
通過(guò)代碼優(yōu)于配置的策略,Gulp 讓簡(jiǎn)單的任務(wù)簡(jiǎn)單蟆盐,復(fù)雜的任務(wù)可管理石挂。
利用 Node.js 流的威力疾瓮,你可以快速構(gòu)建項(xiàng)目并減少頻繁的 IO 操作凸椿。
Gulp 嚴(yán)格的插件指南確保插件如你期望的那樣簡(jiǎn)潔高質(zhì)得工作笑旺。
通過(guò)最少的 API,掌握 Gulp 毫不費(fèi)力馍资,構(gòu)建工作盡在掌握:如同一系列流管道筒主。
工具poi
A zero-config bundler for the web.
相比webpack 和grunt 他更加快速 用最少的配置文件 做最多的自動(dòng)化打包
小結(jié):
前端框架可以圍繞這4大塊來(lái)搭建,但是里面具體的細(xì)節(jié) 還是有很多需要完善的迷帜,規(guī)范的制定每個(gè)公司都有自己的標(biāo)準(zhǔn)物舒,大家可以取其精華,慢慢沉淀戏锹,每一個(gè)技術(shù)細(xì)節(jié)深究起來(lái)都是學(xué)無(wú)止境的冠胯。 我們要適應(yīng)變革,快速提高自己的軟實(shí)力锦针。具體羅列以下幾點(diǎn)
1 要根據(jù)項(xiàng)目的具體情況來(lái)定制打包工具
? ?有些是CMS活動(dòng)界面 有些是商品詳情界面 還有些是一些靜態(tài)說(shuō)明界面荠察,那么打包工具可以配置不同的任務(wù)去適配這些場(chǎng)景 ,比如發(fā)布的環(huán)境 請(qǐng)求接口的地址 以及打包的策略奈搜,但是每個(gè)項(xiàng)目都一定要配置好代理跨域和環(huán)境切換(當(dāng)然大家也可以多個(gè)模板項(xiàng)目)
2 根據(jù)實(shí)際情況合理的拆分基礎(chǔ)組件 和業(yè)務(wù)組件
我們不能過(guò)度的拆分 悉盆,什么意思呢? ? 打個(gè)比方---一篇完整的文章 需要255個(gè)漢字和30個(gè)標(biāo)點(diǎn)符號(hào)組成 那么我們不能拆分成255個(gè)字符組件和 30個(gè)標(biāo)點(diǎn)組件 馋吗,這樣拆分基礎(chǔ)組件太多了焕盟,如果有些漢字只能以詞組形式出現(xiàn) 那么我們的最小單元就可以是詞組,而不是單個(gè)的漢字本身宏粤。合理的拆分 能讓我們的開(kāi)發(fā)效率事半功倍脚翘。過(guò)度的拆分反而會(huì)阻礙開(kāi)發(fā)效率。
3 不要過(guò)度的使用不穩(wěn)定的版本
在BABLE出來(lái)之前 我自己也不怎么用ES6 但是在有解決方案以后就開(kāi)始大量的使用了绍哎,不能抵制新的技術(shù) 也不能再?zèng)]有合理的解決方案之前 過(guò)度的使用他到生產(chǎn)環(huán)境中来农,所以我們選擇前端框架的時(shí)候 最好選擇穩(wěn)定版本,新的技術(shù)框架可以用在小型的項(xiàng)目中學(xué)習(xí)和試水崇堰,等社區(qū)成熟了在開(kāi)始大量使用沃于。
4 package.json的鎖定
項(xiàng)目依賴(lài)文件創(chuàng)建以后 在發(fā)布生成環(huán)境一定的時(shí)間內(nèi)可以鎖定所有依賴(lài)模塊的版本號(hào)涩咖,如果確實(shí)有重大BUG或者需要使用新版本中的方法的時(shí)候在打開(kāi)。這樣團(tuán)隊(duì)中所有人的環(huán)境保持一致繁莹,減少由于版本不對(duì)造成的差異性或者BUG檩互。
其實(shí)前端還需要考慮負(fù)載均衡,數(shù)據(jù)緩存蒋困,前端日志盾似,數(shù)據(jù)統(tǒng)計(jì)敬辣,SEO優(yōu)化雪标,性能監(jiān)控,容災(zāi)機(jī)制溉跃,自適應(yīng)村刨,流程自動(dòng)化測(cè)試,版本兼容等等……革命尚未成功 大家還需努力撰茎!