您好,登錄后才能下訂單哦!
怎么使用node.js開發前端打包程序,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
我們在做前端開發的時候經常會在部署上線的時候做程序的打包和合并,我們接下來就會對如何使用 node.js 開發前端打包程序做非常深入的講解,希望能夠幫到有需要的同學。
我們現在做前端開發更多的是多人共同協作開發,每個人負責不同的模塊,便于開發和調試。這樣就導致我們***部署上線的時候需要把所有人開發的模塊進行合并,生成單個或多個文件上線。如果手動合并的話肯定是費時又費力,而且非常容易出錯,所以我們一般都是通過一些工具來實現自動合并的功能。
打包程序的原理非常簡單,入口文件->尋找依賴關系->替換依賴關系->生成文件,其中中間的兩個步驟是遞歸執行的。
我們先來看一下使用 node.js 如何完成一個簡單的文件合并功能:
// 打包文件內容 var contentList = []; // 排重列表 var loadedFileList = {}; // 打包主程序 function combine(filePath){ // 這里獲取入口文件的內容 var fileContent = fs.readFileSync(filePath); // 遍歷文件內容 fileContent.forEach(function(value){ // 這里的findImport是需要你來實現的方法,用正則來匹配依賴關系 var matchFile = findImport(value); if(matchFile){ //如果匹配到依賴關系 If(!loadedFileList[matchFile]){ //如果依賴關系不在排重列表中,遞歸調用combine combine(matchFile); contentList.push(‘\n’); } }else{ contentList.push(value); } }); }
***只要根據 contentList 里面的內容來生成文件就可以了,怎么樣,是不是很簡單呢?下面我們就要介紹另外一種方式,使用流來完成我們的打包程序。
在 node.js 中,流(Stream)是一個由不同對象實現的抽象接口。流可以是可讀的、可寫的、或者既可讀又可寫的。所有的流都是 EventEmitter 的實例。我們可以通過繼承接口來構造我們自己所需要的流。在我們的打包程序里面需要兩個流,一個負責按行輸出文件內容,另外一個負責處理依賴關系。所有的文件內容都在這兩個流里面循環流動,當所有的依賴關系都處理完畢之后就結束流動并生成對應的文件,這樣就達到我們的目的了。
讓我們先來看一下負責按行輸出文件內容的流是怎么樣的:
var Stream = require('stream').Stream, util = require('util'), path = require('path'), fs = require('fs'); // 構造函數 function LineStream() { this.writable = true; this.readable = true; this.buffer = ''; } module.exports = LineStream; // 繼承流接口 util.inherits(LineStream, Stream); // 重寫write方法,所有pipe過來的數據都會調用此方法 LineStream.prototype.write = function(data, encoding) { var that = this; // 把buffer轉換為string類型 if (Buffer.isBuffer(data)) { data = data.toString(encoding || 'utf8'); } var parts = data.split(/\n/g); // 如果有上一次的buffer存在就添加到最前面 if (this.buffer.length > 0) { parts[0] = this.buffer + parts[0]; } // 遍歷并發送數據 for (var i = 0; i < parts.length - 1; i++) { this.emit('data', parts[i]); } // 把***一行數據保存到buffer,使傳遞過來的數據保持連續和完整。 this.buffer = parts[parts.length - 1]; }; // end方法,在流結束時調用 LineStream.prototype.end = function() { // 如果還有buffer,發送出去 if(this.buffer.length > 0){ this.emit('data',this.buffer); this.buffer = ''; } this.emit('end'); };
這樣我們的 lineStream 就完成了,我們看到在 write 方法里面就做了一件事,分解傳遞過來的數據并按行發送出去,然后我們看下處理依賴關系的流 DepsStream。
var stream = require('stream').Stream; var util = require('util'); var fs = require('fs'); var path = require('path'); module.exports = DepsStream; util.inherits(DepsStream,stream); function DepsStream(){ this.writable = true; this.readable = true; this.buffer = ''; this.depsList = []; }; // 這里的write方法只發送數據,不對數據做任何的處理 DepsStream.prototype.write = function(data){ this.emit('data',data); }; // 我們在這里重新pipe方法,使其能夠處理依賴關系和生成最終文件 DepsStream.prototype.pipe = function(dest,opt){ var that = this; function ondata(chunk){ var matches = findImport(chunk); if(matches){ if(this.depsList.indexOf(matches) >= 0){ // 我們在這里把處理過后的數據pipe回lineStream dest.write('\n'); }else{ this.depsList.push(matches); var code = getFileContent(matches); // 我們在這里把處理過后的數據pipe回lineStream dest.write('\n' + code); } }else{ this.buffer += chunk + '\n'; } } function onend(){ // 生成最終文件 var code = this.buffer; fs.writeFileSync(filePublishUrl,code); console.log(filePublishUrl + ' combine done.'); } // 監聽end事件 that.on('end',onend); // 監聽data事件 that.on('data',ondata); }; // end方法 DepsStream.prototype.end = function(){ this.emit('end'); };
我們看到上面的程序里面我們在 pipe 方法里面監聽了 end 事件和 data 事件,ondata 方法主要用來對數據進行處理,發現有依賴關系的話就獲取對應依賴關系的文件并重新發回給 LineStream 進行處理。onend 方法用來生成最終的文件,我們來看一下最終的調用方法:
var fileStream = fs.createReadStream(filepath); var lineStream = new LineStream(); var depsStream = new DepsStream(); fileStream.pipe(lineStream); lineStream.pipe(depsStream); depsStream.pipe(lineStream);
看完上述內容,你們掌握怎么使用node.js開發前端打包程序的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。