日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
使用node.js開(kāi)發(fā)前端打包程序

我們?cè)谧銮岸碎_(kāi)發(fā)的時(shí)候經(jīng)常會(huì)在部署上線的時(shí)候做程序的打包和合并,我們接下來(lái)就會(huì)對(duì)如何使用 node.js 開(kāi)發(fā)前端打包程序做非常深入的講解,希望能夠幫到有需要的同學(xué)。

柴桑網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、自適應(yīng)網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)從2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

我們現(xiàn)在做前端開(kāi)發(fā)更多的是多人共同協(xié)作開(kāi)發(fā),每個(gè)人負(fù)責(zé)不同的模塊,便于開(kāi)發(fā)和調(diào)試。這樣就導(dǎo)致我們***部署上線的時(shí)候需要把所有人開(kāi)發(fā)的模塊進(jìn)行合并,生成單個(gè)或多個(gè)文件上線。如果手動(dòng)合并的話肯定是費(fèi)時(shí)又費(fèi)力,而且非常容易出錯(cuò),所以我們一般都是通過(guò)一些工具來(lái)實(shí)現(xiàn)自動(dòng)合并的功能。

打包程序的原理非常簡(jiǎn)單,入口文件->尋找依賴關(guān)系->替換依賴關(guān)系->生成文件,其中中間的兩個(gè)步驟是遞歸執(zhí)行的。
我們先來(lái)看一下使用 node.js 如何完成一個(gè)簡(jiǎn)單的文件合并功能:

 
 
 
  1. // 打包文件內(nèi)容
  2. var contentList = [];
  3. // 排重列表
  4. var loadedFileList = {};
  5. // 打包主程序
  6. function combine(filePath){
  7.     // 這里獲取入口文件的內(nèi)容
  8.     var fileContent = fs.readFileSync(filePath);
  9.     // 遍歷文件內(nèi)容
  10.     fileContent.forEach(function(value){
  11.         // 這里的findImport是需要你來(lái)實(shí)現(xiàn)的方法,用正則來(lái)匹配依賴關(guān)系
  12.         var matchFile = findImport(value);
  13.         if(matchFile){
  14.             //如果匹配到依賴關(guān)系
  15.             If(!loadedFileList[matchFile]){
  16.                 //如果依賴關(guān)系不在排重列表中,遞歸調(diào)用combine
  17.                 combine(matchFile);
  18.                 contentList.push(‘\n’);
  19.             }
  20.         }else{
  21.             contentList.push(value);
  22.         }
  23.     });
  24. }

***只要根據(jù) contentList 里面的內(nèi)容來(lái)生成文件就可以了,怎么樣,是不是很簡(jiǎn)單呢?下面我們就要介紹另外一種方式,使用流來(lái)完成我們的打包程序。

在 node.js 中,流(Stream)是一個(gè)由不同對(duì)象實(shí)現(xiàn)的抽象接口。流可以是可讀的、可寫的、或者既可讀又可寫的。所有的流都是 EventEmitter 的實(shí)例。我們可以通過(guò)繼承接口來(lái)構(gòu)造我們自己所需要的流。在我們的打包程序里面需要兩個(gè)流,一個(gè)負(fù)責(zé)按行輸出文件內(nèi)容,另外一個(gè)負(fù)責(zé)處理依賴關(guān)系。所有的文件內(nèi)容都在這兩個(gè)流里面循環(huán)流動(dòng),當(dāng)所有的依賴關(guān)系都處理完畢之后就結(jié)束流動(dòng)并生成對(duì)應(yīng)的文件,這樣就達(dá)到我們的目的了。

讓我們先來(lái)看一下負(fù)責(zé)按行輸出文件內(nèi)容的流是怎么樣的:

 
 
 
  1. var Stream = require('stream').Stream,
  2.     util = require('util'),
  3.     path = require('path'),
  4.     fs = require('fs');
  5. // 構(gòu)造函數(shù)
  6. function LineStream() {
  7.     this.writable = true;
  8.     this.readable = true;
  9.     this.buffer = '';
  10. }
  11. module.exports = LineStream;
  12. // 繼承流接口
  13. util.inherits(LineStream, Stream);
  14. // 重寫write方法,所有pipe過(guò)來(lái)的數(shù)據(jù)都會(huì)調(diào)用此方法
  15. LineStream.prototype.write = function(data, encoding) {
  16.     var that = this;
  17.     // 把buffer轉(zhuǎn)換為string類型
  18.     if (Buffer.isBuffer(data)) {
  19.         data = data.toString(encoding || 'utf8');
  20.     }
  21.     var parts = data.split(/\n/g);
  22.     // 如果有上一次的buffer存在就添加到最前面
  23.     if (this.buffer.length > 0) {
  24.         parts[0] = this.buffer + parts[0];
  25.     }
  26.     // 遍歷并發(fā)送數(shù)據(jù)
  27.     for (var i = 0; i < parts.length - 1; i++) {
  28.         this.emit('data', parts[i]);
  29.     }
  30.     // 把***一行數(shù)據(jù)保存到buffer,使傳遞過(guò)來(lái)的數(shù)據(jù)保持連續(xù)和完整。
  31.     this.buffer = parts[parts.length - 1];
  32. };
  33. // end方法,在流結(jié)束時(shí)調(diào)用
  34. LineStream.prototype.end = function() {
  35.     // 如果還有buffer,發(fā)送出去
  36.     if(this.buffer.length > 0){
  37.         this.emit('data',this.buffer);
  38.         this.buffer = '';
  39.     }
  40.     this.emit('end');
  41. };

這樣我們的 lineStream 就完成了,我們看到在 write 方法里面就做了一件事,分解傳遞過(guò)來(lái)的數(shù)據(jù)并按行發(fā)送出去,然后我們看下處理依賴關(guān)系的流 DepsStream。

 
 
 
  1. var stream = require('stream').Stream;
  2. var util = require('util');
  3. var fs = require('fs');
  4. var path = require('path');
  5. module.exports = DepsStream;
  6. util.inherits(DepsStream,stream);
  7. function DepsStream(){
  8.     this.writable = true;
  9.     this.readable = true;
  10.     this.buffer = '';
  11.     this.depsList = [];
  12. };
  13. // 這里的write方法只發(fā)送數(shù)據(jù),不對(duì)數(shù)據(jù)做任何的處理
  14. DepsStream.prototype.write = function(data){
  15.     this.emit('data',data);
  16. };
  17. // 我們?cè)谶@里重新pipe方法,使其能夠處理依賴關(guān)系和生成最終文件
  18. DepsStream.prototype.pipe = function(dest,opt){
  19.     var that = this;
  20.     function ondata(chunk){
  21.         var matches = findImport(chunk);
  22.         if(matches){
  23.             if(this.depsList.indexOf(matches) >= 0){
  24.                 // 我們?cè)谶@里把處理過(guò)后的數(shù)據(jù)pipe回lineStream
  25.                 dest.write('\n');
  26.             }else{
  27.                 this.depsList.push(matches);
  28.                 var code = getFileContent(matches);
  29.                 // 我們?cè)谶@里把處理過(guò)后的數(shù)據(jù)pipe回lineStream
  30.                 dest.write('\n' + code);
  31.             }
  32.         }else{
  33.             this.buffer += chunk + '\n';
  34.         }
  35.     }
  36.     function onend(){
  37.         // 生成最終文件
  38.         var code = this.buffer;
  39.         fs.writeFileSync(filePublishUrl,code);
  40.         console.log(filePublishUrl + ' combine done.');
  41.     }
  42.     // 監(jiān)聽(tīng)end事件
  43.     that.on('end',onend);
  44.     // 監(jiān)聽(tīng)data事件
  45.     that.on('data',ondata);
  46. };
  47. // end方法
  48. DepsStream.prototype.end = function(){
  49.     this.emit('end');
  50. };

我們看到上面的程序里面我們?cè)?pipe 方法里面監(jiān)聽(tīng)了 end 事件和 data 事件,ondata 方法主要用來(lái)對(duì)數(shù)據(jù)進(jìn)行處理,發(fā)現(xiàn)有依賴關(guān)系的話就獲取對(duì)應(yīng)依賴關(guān)系的文件并重新發(fā)回給 LineStream 進(jìn)行處理。onend 方法用來(lái)生成最終的文件,我們來(lái)看一下最終的調(diào)用方法:

 
 
 
  1. var fileStream = fs.createReadStream(filepath);
  2. var lineStream = new LineStream();
  3. var depsStream = new DepsStream();
  4. fileStream.pipe(lineStream);
  5. lineStream.pipe(depsStream);
  6. depsStream.pipe(lineStream);

怎么樣,是不是非常簡(jiǎn)單,感興趣的同學(xué)趕快嘗試一下吧。


當(dāng)前題目:使用node.js開(kāi)發(fā)前端打包程序
文章鏈接:http://m.5511xx.com/article/codgjis.html