代码自动化打包系统【原创】
一、?需求背景
XX項目需要開發(fā)一套前端組件打包系統(tǒng),來處理用戶的請求:
1.???????用戶通過平臺申請應(yīng)用;
2.???????選擇所需要的組件;
3.???????把組件的相關(guān)前端文件如js、css、html進行抽取、合并、壓縮、打包;
4.???????把壓縮包鏈接地址返回給用戶,用戶下載壓縮包。
針對上面的需求,我們選擇一個比較流行的前端代碼打包工具grunt。
二、?grunt簡介
什么是grunt?
官網(wǎng)給它的解釋是The JavaScript Task Runner。Grunt是基于Node.js的項目構(gòu)建工具,可以對項目文件壓縮、編譯、單元測試等任務(wù)通過Gruntfile配置用grunt命令自動執(zhí)行,節(jié)省大部分無聊的工作和時間。
為什么選grunt?
因為grunt有豐富的插件,能滿足打包所需要的合并、壓縮、打zip包等功能。
三、?系統(tǒng)運行環(huán)境
打包系統(tǒng)的運行需要下面的環(huán)境提供支持,在開發(fā)前需要對其一一安裝。
Node:Javascript運行環(huán)境(runtime)。實際上它是對Google V8引擎進行了封裝
npm:全稱Node Package Manager,是一個NodeJS包管理和分發(fā)工具
pm2:帶有負(fù)載均衡功能的Node應(yīng)用的進程管理器
Dnode:實現(xiàn)php與node之間的通信,提供雙向遠(yuǎn)程方法調(diào)用類庫
Grunt及其插件:grunt-contrib-clean,grunt-contrib-concat,grunt-contrib-copy,grunt-contrib-cssmin,grunt-contrib-less,grunt-contrib-uglify,grunt-contrib-watch,grunt-zip,load-grunt-tasks,gurnt依靠這些插件完成了代碼的合并、壓縮、打zip包等功能
四、?打包系統(tǒng)實現(xiàn)
先看一下流程圖
上圖的流程是經(jīng)過無數(shù)次修改后的方案,期間遇到很多問題,主要集中在php和grunt之間的調(diào)用和參數(shù)傳遞上。需要解決的問題:
1.???????怎樣從源代碼文件中根據(jù)所選擇的組件來抽取對應(yīng)的文件;
2.???????怎樣用php程序調(diào)用grunt命令
3.???????dnode可以作為php調(diào)用grunt命令的橋梁,php怎樣同步調(diào)用grunt命令
1.???????Gruntfile文件使用
用戶首先要選擇組件進行下載壓縮包,通過grunt命令給Gruntfile傳遞需要打包的組件列表,Gruntfile包含grunt的全部處理邏輯。
加載grunt插件
加載所需要的插件,寫在package.json文件里:
"devDependencies": {"grunt": "~0.4.0","grunt-contrib-clean": "^0.6.0", "grunt-contrib-concat": "^0.1.3", "grunt-contrib-copy": "^0.4.0", "grunt-contrib-cssmin": "^0.6.1", "grunt-contrib-uglify": "^0.9.1", "grunt-contrib-watch": "^0.3.1", "grunt-contrib-less": "^1.0.0", "load-grunt-tasks": "^3.2.0", "time-grunt": "^1.2.1", "grunt-zip": "^0.16.2" }源文件配置文件:
下面是loading組件的配置文件,html和一些通用js,css (less)?直接寫在GruntFile文件內(nèi)
{"app": "loading","less": ["src/app/loading/loading.less"],"js": ["src/vendor/common/pxloader.js", "src/app/loading/loading.js"] }Gruntfile參數(shù)接收:
var appArr = grunt.option('app').split(',');?(app為組件參數(shù)字符串,是組件名稱組合,名稱之間用逗號分隔)例如:’register,login,slider’。
Gruntfile根據(jù)獲取的組件列表讀取組件配置文件。
for (var i in appArr) {var confName = 'grunt_conf/' + appArr[i] + '.json'; confArr[i] = grunt.file.readJSON(confName); };Gruntfile根據(jù)參數(shù)app獲取組件名稱,然后又根據(jù)組件名稱獲取組件配置文件,通過配置文件,可以獲取源文件的文件列表,然后對這些組件的源文件進行組合、合并、壓縮,最后生成壓縮包
2.???????php調(diào)用grunt
由于生產(chǎn)環(huán)境php.ini的disable_functions把exec、shell_exec、system這樣可以執(zhí)行linux命令的函數(shù)禁用,但是Node可以調(diào)用,DNode可以實現(xiàn)php和Node之間的通信。這樣我們就可以實現(xiàn)php程序調(diào)用grunt命令。
Node打包Server
var PORT = 7083; var dnode = require('dnode'); var cp = require('child_process'); var server = dnode({ pack: function (params, callback) { var ls = cp.exec("grunt --app=" + params.coms, [], function(error, stdout, stderr){ if(error != null || stdout.indexOf('without errors') < 0){ callback('error'); }else{ callback('success'); } }); } }); server.listen(PORT);?
Php同步調(diào)用
為什么同步調(diào)用而不是異步?因為打包后要對壓縮包上傳,上傳前必須保證壓縮包存在,所以我們使用了回調(diào)函數(shù),并且可以根據(jù)回調(diào)函數(shù)的返回值判斷打包是否正常,同時也保證下一步上傳的正常進行。
/*** 源文件打包* @param string $components* @param string $path* @param string $fileName* @throws \H5EException */ private static function sourcePack($components){ $loop = new \React\EventLoop\StreamSelectLoop(); $dnode = new \DNode\DNode($loop); $port = 7083; self::$params = array('coms' => $components); $dnode->connect($port, function($remote, $connection) { $remote->pack(PackService::$params, function ($ret) use ($connection){ if ("success" != $ret) { throw new \H5EException("pack service error", Constants::SYSTEM_CODE); } $connection->end(); }); }); $loop->run(); }?
3.???????維持Node打包server的持續(xù)運行
node啟動打包server進程,一段時間后會莫名其妙的掛掉,pm2作為node的守護進程很好的解決了這個問題。
4.???????壓縮包上傳
壓縮包是根據(jù)版本來規(guī)劃的,當(dāng)版本改變后,用戶下載壓縮包就需要重新打包,但是同一版本的源文件沒必要重新打壓縮包,所以我們把壓縮包上傳資源服務(wù)器上,然后把資源鏈接保存在數(shù)據(jù)庫中,下一次只需從數(shù)據(jù)庫中查詢到該鏈接即可,而無須重復(fù)打包,這樣既提高了用戶下載的速度,又節(jié)省了服務(wù)器資源。
五、?后期改進
增加Node日志,目前缺少node日志,如果出現(xiàn)異常,很難定位的問題;
Node打包server接收參數(shù)時進行嚴(yán)格校驗;
六、 安全問題思考
A.?控制訪問頻率,和普通數(shù)據(jù)接口相比,打包接口耗時較長,消耗服務(wù)器資源較多,如果出現(xiàn)接口被惡意頻繁請求,可能會影響服務(wù)器性能,同時造成正常的打包失敗,有必要對訪問頻率做限制;
B.?在php層和node層都要進行嚴(yán)格校驗參數(shù),可以有效的防止因參數(shù)問題而帶來的意外;
C.?Node?代碼打包server運行的端口不能對外,阻止用戶通過外網(wǎng)直接訪問該端口。
轉(zhuǎn)載于:https://www.cnblogs.com/Felixdh/p/4986830.html
總結(jié)
以上是生活随笔為你收集整理的代码自动化打包系统【原创】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Exception raised dur
- 下一篇: Windows7 64位 plsql d