html與js模塊化解決方案##
html 模塊以預(yù)編譯的方式模塊編寫,例:界面包含三部分(head body footJS同一套項目里面必然會涉及到通用的部分(head footJs),各個界面不同主要在body體。
js 以模塊預(yù)加載的方式通過特定的方式去加載模塊js代碼。模塊化js主要以sea.js方式去加載。
項目初始化
- 執(zhí)行以下命令
$ npm install
注:可以通過cnpm安裝
- 構(gòu)建項目
$ gulp
目錄結(jié)構(gòu)
/project/
/dist # 最終輸出和使用的代碼目錄
/js # 最終輸出編譯后的js文件
/css # 最終輸出的樣式文件
x.html # 輸出html文件
/src # 源文件目錄
/scss # scss源文件目錄
/js # js源文件目錄
/html # html源文件目錄
模塊講解
1.html模塊
html構(gòu)建方式:
gulp.task("html", function() {
var distPath = './dist';
return gulp.src('src/html/*.html')
.pipe(includer({ debug : true}))
.pipe(replace("{{version}}", dateFormat('YmdHis')))
.pipe(htmlmin( { collapseWhitespace : true, minifyCSS : true, minifyJS : true }))
.pipe(gulp.dest(distPath))
.pipe(notify({ message: "HTML task complete!" }))
});
配置的解決方案:html模板之間主要以include的方式加載所需模塊。類似于tmodJS(artTemplate),壓縮html代碼最終輸出到dist文件中。模塊加載方式(例):
<!-- include "./components/html_head.html" -->
<title>架手架編譯html</title>
</head>
<body>
<div id="layout">
<!-- include "./components/header.html" -->
<div id="main">
中間內(nèi)容層
</div>
<!-- include "./components/footer.html" -->
</div>
<div id="load-module" data-main="p.index"></div>
<!-- include "./components/global_js.html" -->
</body>
</html>
2. js模塊化
在申明之前,先簡單了解下html 模塊中footJs模塊的定義:
<script type="text/javascript" src="js/sea.js"></script>
<script>
var VERSION = "{{version}}";
seajs.config({
base : "./js/",
alias : {
"jquery" : (!window.addEventListener) ? "jquery-1.11.3.min.js" : "jquery-2.2.4.min.js"
},
preload: ['jquery'], //使用use之前確保模塊已經(jīng)加載好
'map': [
[ /^(.*\/js\/(.*)(js|css))(.*)$/i, "$1?v=" + VERSION]
]
});
seajs.use('app.min', function() {
seajs.use('app');
});
</script>
VERSION主要配置版本號,做文件加載禁止緩存處理,map中的映射主要是為了加載模塊時,添加文件后綴禁止緩存。加載編譯后的app.min.js。界面的入口函數(shù)都在app.js模塊中去控制。那么,如何控制每個界面加載不同的js模塊?先看app.js模塊定義:
/**
* 初始化腳本模塊文件
*/
define(function(require, exports, module) {
var $ = require("jquery"),
WD = require("widget");
$(function(){
var $loadModule = $('#load-module'),
loadModule = $loadModule.attr('data-main');
console.log('app.js 初始化腳本模塊文件');
if (loadModule) {
require(loadModule); // 動態(tài)加載頁面模塊文件
}
});
});
所有界面的入口執(zhí)行函數(shù)都在app.js中通過獲取html每個界面body模板中定義的data-main中的參數(shù)動態(tài)加載相應(yīng)的界面以來文件。例如上述例子中定義的data-main="p.index"
在界面開始執(zhí)行入口主函數(shù)app.js后,會加載p.index.js模塊。再看p.index模塊定義:
/**
* 首頁腳本模塊文件
*/
define(function(require, exports, module) {
var $ = require('jquery');
var WD = require('widget');
console.log('p.index', WD);
console.log($);
....
var dialog = new WD.dialog();
});
在界面js模塊中引入組件模塊,業(yè)務(wù)模塊,視圖模塊,控制模塊。執(zhí)行主函數(shù)。其中,每個模塊都可以以模塊化的方式定義,具體情景看具體的業(yè)務(wù)定義,以組件模塊定義為例:
定義dialog組件
/**
* 一個對話框組件模塊
*/
define(function(require, exports, module) {
function Dialog() {
console.log('Dialog');
}
module.exports = Dialog;
});
再接著定義全局模塊引入所以定義好的組件模塊
/**
* 公共組件模塊文件的模塊集合
*/
define(function(require, exports, module) {
var dialog = require('./mt.dialog'); // 例:引入一個對話框組件模塊
exports.dialog = dialog;
//.... 其它組件模塊
exports.func1 = function() {
alert('方法1');
};
});
在這個組件模塊集合中,將所有模塊暴露出去。具體調(diào)用方式,上述p.index.js模塊中有定義。
構(gòu)建亮點介紹
- 動態(tài)的js,css版本控制VERISON
- html模板模塊劃分。
- 模塊化js腳本,更簡潔明了的管理js代碼
缺陷與不足
- 圖片資源文件沒有做處理。
- 低版本兼容性沒處理(后期再做介紹)
- 將sea升級為es6語法
總結(jié)
此篇與前面兩篇scss構(gòu)建相呼應(yīng),可以將scss編譯集成到項目里面。其中每個界面的執(zhí)行腳本,主要通過界面核心(body)模板中聲明的data-mian控制加載。以及編譯后,動態(tài)修改界面引入的js與css文件的版本。有效解決在開發(fā)時,重復(fù)編譯造成的緩存問題。至于此方案中優(yōu)化的問題(兼容性控制,子模塊定義方式,通用模塊定義),文章另做詳解