一個適合小頁面的模板開發工具,基於webpack,支持熱重載,將css、js打包到一個html模板文件中。
這個小工具的適用場景不廣,但設計思路能帶來不小的啓發。javascript
具體可移步:github.com/SP-Lyu/TDS
* 單純看成工做小總結寫了,其實能夠拆出不少細小但有用的文章css
TDS實際上是爲了一些小型的廣告模板服務的,當年接手這一塊只能手動生產這些模板,開發維護起來特別麻煩 (沒錯,本人就是靠發小廣告爲生)。html
<!-- 常見的廣告模板 -->
<!-- Head -->
<style> /* Style Sheet */ </style>
<div id="{{ADID}}" class="wrapper">
<img src="{{IMG}}" />
<img src="{{IMG}}" />
<img src="{{IMG}}" />
<div><a href="{{CLICK_URL}}">{{DESC}}</a></div>
<div class="logo">
<!-- LOGO logic -->
</div>
<script> // monitor // animate logic var id = {{ADID}}; var conf = { showtime: {{TIME}} // ... } // ... </script>
</div>
<!-- Tail -->
複製代碼
在一些搜索場景或者網盟場景下面的廣告前端邏輯,每每具有如下幾個特色:前端
因此對於商業廣告展示的前端開發,有這幾點須要關注:java
根據上述的訴求點,最終產出了一個模板開發工具,以命令行的形式完成模板的開發環境初始化、開發、打包、測試等。
命令大全:node
tpl -s 切換至不一樣的業務線
tpl -l 查看當前業務線中的模板
tpl -i <tpl_name> 初始化新模板
tpl -d <tpl_name> -p <port> [-q] 開發
tpl -b <tpl_name> [-q] [-u] [-c charset] 打包模板(-u:是否不壓縮HTML文件 -c:轉換至目標編碼)
tpl -B [-q] [-u] [-c charset] 打包當前業務線中全部模板
tpl --delete 刪除模板
複製代碼
下面介紹一下這個工具結合實際應用解決的幾個痛點:webpack
一般的頁面開發,都是前端只保留一個簡單的html,經過CDN、靜態文件、緩存等方式引入CSS與JS文件,但該方式並不徹底適用於廣告展示的應用場景。 廣告頁面 交互少,邏輯簡單 ,即便將css、js代碼徹底算上,亦不過15K左右大小,按照1MB/s的下載速度,傳輸僅須要15ms便可完成,而通常花在請求上的TTFB時間已大大超過這個值了。因此最耗時的不是資源下載,而是請求自己。
因此此處的優化思路應該是:css與js以行內引入的方式打包進模板,減小資源請求數,達到展示速度最快的目的。
TDS中採用了以ejs爲模板,將打包好的css與js以字符串的形式經過webpack
引入模板,達到行內引入的目的。 webpack配置:git
{
// ...
plagins:[
new MiniCssExtractPlugin({
filename: "main.css",
}),
new HtmlWebpackPlugin({
files:{
"css":[`./main.css`],
"js":[`./main.js`]
},
filename: `test.tpl`,
inject: false,
template: `test.ejs`,
title: tpl
}),
new OptimizeCSSAssetsPlugin({})
]
// ...
}
複製代碼
ejs模板引入:github
CSS:
<style type="text/css"><%= compilation.assets[htmlWebpackPlugin.files.css[0]].source() %></style>
JS:
<script></script>
複製代碼
組件化的過程當中,要考慮到 模塊可複用 以及 業務間的模塊獨立web
由於一些動畫邏輯(抽獎、彈窗、輪播等)在多套模板中是公用的,且隨着時間推移,這些邏輯的批量更改的需求若處理很差,會徒增不少開發量。就須要webpack
配合上必定的腳本,進行批量打包。
在TDS中,經過Node
引入webpack
進行打包,並經過commander.js
,將Node
程序命令化,從而達到批量打包的目的。
能夠移步packer.js中看到詳細的配置引入。
在開發的過程當中,因爲想要把熱重載也加入TDS工具中,調研了一下現有的幾種方法,但最終發現,能夠直接在Node環境下引入webpack-dev-server
啓動熱重載。如下是示例:
const webpack = require("webpack");
const WebpackDevServer = require("webpack-dev-server");
const compiler = webpack({
//webpack conf
});
const s = new WebpackDevServer(,{
quiet: false,
contentBase: './'
});
s.listen(8808, '0.0.0.0', function(){});
複製代碼
這種方式的引入,比用webpack-dev-middleware
+ webpack-hot-middleware
簡單多了(但不知道爲啥官方把它藏得那麼深,多是由於應用場景少吧)
官方例子
不一樣業務需求會存在多個模板,這裏還得考慮一下業務獨立的問題,能更好地將TDS應用於多業務線開發。因爲運用了commander.js
將TDS命令化,能夠進行不少定製,例如將開發區塊以業務線進行區分,加入了workspace
的概念,能夠執行tpl -s
切換工做區間,且以後的一切操做(新增、刪除、打包模板等),都是基於當前工做區間完成的。
每一個業務會有本身的初始化模板,存放至templage_xxx文件夾中,新增以後的模板文件放在src/xxx/
下,打包生成的模板則放在out/xxx/
下,這樣能保證每一個業務相互獨立不干擾。 這個實現起來也十分簡單,建立一個.user_config
文件記錄下當前用戶所處的業務線,以此做爲工做區間進行模板配置的讀取、操做便可。
// .user_config
{
current_workspace: 'buns'
}
複製代碼
一開始開發維護過程當中遇到的最蛋疼的問題就是,前端對於這種模板文件須要本身再去將值回填才能進行調試,對於前期的兼容性、交互、樣式等的測試十分不友好。TDS維護了一套簡單的測試方法:使用HtmlWebpackPlugin
打包ejs模板的時候,配置當前的打包選項,能夠區分出當前的開發環境以及須要用到的mock數據:
// webpack配置
new HtmlWebpackPlugin({
files:{
"css":['out/.tmp/main.css'],
"js":['out/.tmp/main.js'],
},
// ↓當前環境置爲開發環境
dev: true,
// ↓將文件以字符串數組的方式,寫入mock中
mocks: get_files(`${tpl_path}/mocks/`),
// ↓將文件以字符串數組的方式,寫入mock中
gmocks: get_files(`${tpl_path}/../Gmocks/`),
filename: tpl + '.html',
inject: false,
template: tpl_path + '/' + tpl + '.ejs',
name: tpl,
workspace
})
複製代碼
數據源直接能夠經過ejs文件中的htmlWebpackPlugin.options.dev
選項區分。
<% const ejs_env = htmlWebpackPlugin.options; %>
<% /*公共頭部*/ %>
<%= ejs_env.dev?ejs_env.gmocks['head.html'] : '' %>
<div id="current_show"></div>
<script></script>
<script>// handle window.__g_ad_data</script>
<% /*公共尾部*/ %>
<%= ejs_env.dev ? ejs_env.gmocks['tail.html'] : '' %>
複製代碼
這樣就能在本身開發過程當中維護一套有效的mock數據,打包項目代碼時,直接經過環境的判斷就能達到將後端模板字段打包的目的。
最終打包生成的模板:
<div id="current_show"></div>
<script></script>
<script>// handle window.__g_ad_data</script>
複製代碼
最後的總體產出,因爲加上了js、css、html的打包邏輯,對比以前的模板體積大約降低了30%左右,且去除了css、js的加載邏輯,頁面的總體加載時間(不算圖片)接近於一次http請求的時間。
且對於開發人員來講,先後端的開發能夠完全分離,再也不須要繁瑣的溝通成本。
commander.js
webpack NodeApi
webpack-dev-server NodeApi
* 有問題歡迎留言交流