自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端:如何基于Node.JS從零構(gòu)建線上自動(dòng)化打包工作流?

開(kāi)發(fā) 前端 自動(dòng)化
NodeJS在前端領(lǐng)域正扮演著越越重要的地位,它不僅可以讓前端工作者使用javascript編寫后端代碼,還能方便地搭建響應(yīng)速度快、易于擴(kuò)展的網(wǎng)絡(luò)應(yīng)用。Node.js 使用事件驅(qū)動(dòng),非阻塞I/O 模型而得以輕量和高效,非常適合在分布式設(shè)備上運(yùn)行數(shù)據(jù)密集型的實(shí)時(shí)應(yīng)用。

前言

NodeJS在前端領(lǐng)域正扮演著越越重要的地位,它不僅可以讓前端工作者使用javascript編寫后端代碼,還能方便地搭建響應(yīng)速度快、易于擴(kuò)展的網(wǎng)絡(luò)應(yīng)用。Node.js 使用事件驅(qū)動(dòng),非阻塞I/O 模型而得以輕量和高效,非常適合在分布式設(shè)備上運(yùn)行數(shù)據(jù)密集型的實(shí)時(shí)應(yīng)用。

[[417435]]

所以作為一名優(yōu)秀的前端工程師,非常有必要了解和掌握Node.js。筆者接下來(lái)將通過(guò)對(duì)H5-Dooring項(xiàng)目中的實(shí)時(shí)在線下載代碼功能來(lái)帶大家掌握如何從零構(gòu)建線上自動(dòng)化打包工作流。

你將收獲

  • 設(shè)計(jì)一款在線工作流的基本思路
  • nodejs常用API的使用
  • nodejs如何使用父子進(jìn)程
  • 使用child_process的exec實(shí)現(xiàn)解析并執(zhí)行命令行指令
  • http://socket.io實(shí)現(xiàn)消息實(shí)時(shí)推送
  • 使用jszip實(shí)現(xiàn)服務(wù)端壓縮文件并支持前端下載zip包

正文

我們都用過(guò)諸如gulp,webpack之類的自動(dòng)化工具,他們能很方便地幫我們打包編譯代碼,并以一種相對(duì)優(yōu)雅的方式編寫我們的工程代碼。但是我們仔細(xì)思考之后就能發(fā)現(xiàn), 這些產(chǎn)物的背后都是靠nodejs和babel做底層支持。我們無(wú)非就是設(shè)計(jì)一種架構(gòu)模式,通過(guò)babel的加載器和nodejs的服務(wù)能力,將代碼由JS - AST - JS的過(guò)程(這里忽略css和插件處理)。

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

在吹完牛逼之后,我們開(kāi)始介紹如何設(shè)計(jì)一款在線工作流。

1. 設(shè)計(jì)一款在線工作流的基本思路

在線工作流是個(gè)泛指,其實(shí)任何產(chǎn)品線都有屬于自己特色的工作流,但最終還是要回歸業(yè)務(wù)。所以筆者在這里專門介紹一下H5-Dooring的實(shí)時(shí)下載代碼的在線工作流。我們看看下面的設(shè)計(jì)流程:

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

以上就是我們需要做的在線實(shí)時(shí)打包下載代碼的工作流,由于nodejs是單線程的,為了不阻塞進(jìn)程我們可以采用父子進(jìn)程通信的方式和異步模型來(lái)處理復(fù)雜耗時(shí)任務(wù),為了通知用戶任務(wù)的完成狀況, 我們可以用socket做雙向通信。在當(dāng)前的場(chǎng)景下就是代碼編譯壓縮完成之后,通知給瀏覽器,以便瀏覽器顯示下載狀態(tài)彈窗。一共有三種狀態(tài):進(jìn)行中,已完成,失敗。對(duì)應(yīng)如下圖所示界面:

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

H5-Dooring

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

H5-Dooring

至于為什么沒(méi)有出現(xiàn)下載失敗的狀態(tài),不要問(wèn)我,問(wèn)就是沒(méi)有失敗過(guò)(完了,找虐了)。

以上就是H5-Dooring實(shí)時(shí)編譯下載的工作流設(shè)計(jì),至于線上更多的實(shí)際需求,我們也可以參考以上設(shè)計(jì)去實(shí)現(xiàn),接下來(lái)筆者來(lái)具體介紹實(shí)現(xiàn)過(guò)程。

2.nodejs如何使用父子進(jìn)程

我們要想實(shí)現(xiàn)一個(gè)自動(dòng)化工作流, 要考慮的一個(gè)關(guān)鍵問(wèn)題就是任務(wù)的執(zhí)行時(shí)機(jī)以及以何種方式執(zhí)行. 因?yàn)橛脩粝螺d代碼之前需要等H5頁(yè)面打包編譯壓縮完成之后才能下載, 而這個(gè)過(guò)程需要一定的時(shí)間(8-30s), 所以我們可以認(rèn)定它為一個(gè)耗時(shí)任務(wù).

當(dāng)我們使用nodejs作為后臺(tái)服務(wù)器時(shí), 由于nodejs本身是單線程的,所以當(dāng)用戶請(qǐng)求傳入nodejs時(shí), nodejs不得不等待這個(gè)"耗時(shí)任務(wù)"完成才能進(jìn)行其他請(qǐng)求的處理, 這樣將會(huì)導(dǎo)致頁(yè)面其他請(qǐng)求需要等待該任務(wù)執(zhí)行結(jié)束才能繼續(xù)進(jìn)行, 所以為了更好的用戶體驗(yàn)和流暢的響應(yīng),我們不得不考慮多進(jìn)程處理. 好在nodejs設(shè)計(jì)支持子進(jìn)程, 我們可以把耗時(shí)任務(wù)放入子進(jìn)程中來(lái)處理,當(dāng)子進(jìn)程處理完成之后再通知主進(jìn)程. 整個(gè)流程如下圖所示:

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

nodejs有3種創(chuàng)建子進(jìn)程的方式,這里筆者簡(jiǎn)單介紹一下fork的方式。使用方式如下:

 

  1. // child.js 
  2. function computedTotal(arr, cb) { 
  3.     // 耗時(shí)計(jì)算任務(wù) 
  4.  
  5. // 與主進(jìn)程通信 
  6. // 監(jiān)聽(tīng)主進(jìn)程信號(hào) 
  7. process.on('message', (msg) => { 
  8.   computedTotal(bigDataArr, (flag) => { 
  9.     // 向主進(jìn)程發(fā)送完成信號(hào) 
  10.     process.send(flag); 
  11.   }) 
  12. }); 
  13.  
  14. // main.js 
  15. const { fork } = require('child_process'); 
  16.  
  17. app.use(async (ctx, next) => { 
  18.   if(ctx.url === '/fetch') { 
  19.     const data = ctx.request.body; 
  20.     // 通知子進(jìn)程開(kāi)始執(zhí)行任務(wù),并傳入數(shù)據(jù) 
  21.     const res = await createPromisefork('./child.js', data) 
  22.   } 
  23.  
  24.   // 創(chuàng)建異步線程 
  25.   function createPromisefork(childUrl, data) { 
  26.     // 加載子進(jìn)程 
  27.     const res = fork(childUrl) 
  28.     // 通知子進(jìn)程開(kāi)始work 
  29.     data && res.send(data) 
  30.     return new Promise(reslove => { 
  31.         res.on('message', f => { 
  32.             reslove(f) 
  33.         }) 
  34.     })   
  35.   } 
  36.  
  37.   await next() 
  38. }) 

 

在H5-Dooring線上打包的工作流中,我們會(huì)用到child_process的exec方法,來(lái)解析并執(zhí)行命令行指令。至于父子進(jìn)程的更多應(yīng)用,大家可以自行探索。

3. 使用child_process的exec實(shí)現(xiàn)解析并執(zhí)行命令行指令

在上面介紹的dooring工作流中,我們知道為了實(shí)現(xiàn)實(shí)時(shí)打包,我們需要一個(gè)H5 Template項(xiàng)目,作為打包的母版,當(dāng)用戶點(diǎn)擊下載時(shí),會(huì)將頁(yè)面的json schema數(shù)據(jù)傳給node服務(wù)器, node服務(wù)器再將json schema進(jìn)行數(shù)據(jù)清洗最后生成template.json文件并移動(dòng)到H5 Template母版中,此時(shí)母版拿到數(shù)據(jù)源并進(jìn)行打包編譯,最后生成可執(zhí)行文件。

以上的過(guò)程很關(guān)鍵, 這里筆者畫個(gè)大致的流程圖:

 

前端:如何基于NodeJS從零構(gòu)建線上自動(dòng)化打包工作流?

 

H5-Dooring

為了實(shí)現(xiàn)以上過(guò)程,我們需要兩個(gè)關(guān)鍵環(huán)節(jié): 1. 將用戶配置的數(shù)據(jù)進(jìn)行處理并生成json文件,然后移動(dòng)到H5 Template母版中 2. 在母版中自動(dòng)執(zhí)行打包編譯腳本

第一個(gè)環(huán)節(jié)很好實(shí)現(xiàn),我們只需要用nodejs的fs模塊生成文件到指定目錄即可,這里筆者重點(diǎn)介紹第二個(gè)環(huán)節(jié)的實(shí)現(xiàn)。

當(dāng)我們將json數(shù)據(jù)生成到H5 Template中之后,就可以進(jìn)行打包了,但是這個(gè)過(guò)程需要自動(dòng)化地去處理,不能像我們之前啟動(dòng)項(xiàng)目一樣,手動(dòng)執(zhí)行npm start或者yarn start。我們需要程序自動(dòng)幫我們執(zhí)行這個(gè)命令行指令,筆者在查nodejs API突然發(fā)現(xiàn)了child_process的exec方法,可以用來(lái)解析指令,這個(gè)剛好能實(shí)現(xiàn)我們的需求,所以我們開(kāi)始實(shí)現(xiàn)它。代碼如下:

 

  1. import { exec } from 'child_process' 
  2. const outWorkDir = resolve(__dirname, '../h5_landing'
  3. const fid = uuid(8, 16) 
  4. const cmdStr = `cd ${outWorkDir} && yarn build ${fid}` 
  5.  
  6. // ...exec相關(guān)代碼 
  7. const filePath = resolve(__dirname, '../h5_landing/src/assets/config.json'
  8. const res = WF(filePath, data) 
  9.  
  10. exec(cmdStr, function(err,stdout,stderr){ 
  11.   if(err) { 
  12.     // 錯(cuò)誤處理 
  13.   } else { 
  14.     // 成功處理 
  15.   } 
  16. }) 

 

以上代碼我們不難理解,我們只需要定義好打包的指令字符串(方式和命令行操作幾乎一致),然后傳入給exec的第一個(gè)參數(shù),他就會(huì)幫我們解析字符串并執(zhí)行對(duì)應(yīng)的命令行指令。在執(zhí)行完成之后,我們可以根據(jù)回調(diào)函數(shù)(第二個(gè)參數(shù))里的參數(shù)值來(lái)判斷執(zhí)行結(jié)果。整個(gè)過(guò)程是異步的,所以我們不用擔(dān)心阻塞問(wèn)題,為了實(shí)時(shí)反饋進(jìn)度,我們可以用socket來(lái)將進(jìn)度信息推送到瀏覽器端。

4.http://socket.io實(shí)現(xiàn)消息實(shí)時(shí)推送

在上面介紹的 exec實(shí)現(xiàn)解析并執(zhí)行命令行指令 中還有一些細(xì)節(jié)可以優(yōu)化,比如代碼執(zhí)行進(jìn)程的反饋,執(zhí)行狀態(tài)的反饋。因?yàn)槲覀冇玫氖钱惒骄幊?,所以?qǐng)求不會(huì)一直等待,如果不采取任何優(yōu)化措施,用戶是不可能知道何時(shí)代碼打包編譯完成, 也不知道代碼是否編譯失敗,所以這個(gè)時(shí)候會(huì)采取幾種常用的方案: 客戶端請(qǐng)求長(zhǎng)輪詢 postmessage消息推送 * websocket雙向通信

很明顯使用websocket雙向通信會(huì)更適合本項(xiàng)目。這里我們直接使用社區(qū)比較火的http://socket.io.由于官網(wǎng)上有很多使用介紹,這里筆者就不一一說(shuō)明了。我們直接看業(yè)務(wù)里的代碼使用:

 

  1. // node端 
  2. exec(cmdStr, function(err,stdout,stderr){ 
  3.   if(err) { 
  4.     console.log('api error:'+stderr); 
  5.     io.emit('htmlFail', { result: 'error', message: stderr }) 
  6.   } else { 
  7.     io.emit('htmlSuccess', { result: dest, message: stderr }) 
  8.   } 
  9. }) 
  10.  
  11. // 瀏覽器端 
  12. const socket = io(serverUrl); 
  13. // ...省略其他業(yè)務(wù)代碼 
  14. useEffect(() => { 
  15.   socket.on('connect'function(){ 
  16.     console.log('connect'
  17.   }); 
  18.   socket.on('htmlFail'function(data){ 
  19.     // ... 
  20.   }); 
  21.   socket.on('disconnect'function(e){ 
  22.     console.log('disconnect', e) 
  23.   }); 
  24. }, []) 

 

這樣我們就能實(shí)現(xiàn)服務(wù)器任務(wù)流的狀態(tài)實(shí)時(shí)反饋給瀏覽器端了。

5. 使用jszip實(shí)現(xiàn)服務(wù)端壓縮文件并支持前端下載zip包

實(shí)現(xiàn)前端下載功能其實(shí)也很簡(jiǎn)單,因?yàn)橛脩襞渲玫腍5項(xiàng)目包含了各種資源,比如css,js,html,image,所以為了提高下載性能和便捷性我們需要把整個(gè)網(wǎng)站打包,生成一個(gè)zip文件供用戶下載。原理就是使用jszip將目錄壓縮,然后返回壓縮后的路徑給到前端,前端采用a標(biāo)簽進(jìn)行下載。至于如何實(shí)現(xiàn)目錄遍歷壓縮和遍歷讀取目錄, 這里筆者就不說(shuō)了,感興趣的可以參考筆者其他的nodejs的文章。

6. 總結(jié)

以上教程筆者已經(jīng)集成到H5-Dooring中,對(duì)于一些更復(fù)雜的交互功能,通過(guò)合理的設(shè)計(jì)也是可以實(shí)現(xiàn)的,大家可以自行探索研究。

 

瀏覽器搜索:H5-Dooring

 

責(zé)任編輯:華軒 來(lái)源: 今日頭條
相關(guān)推薦

2023-07-21 15:26:00

數(shù)據(jù)庫(kù)同步數(shù)據(jù)

2022-12-16 21:58:20

NodeJSH5zip

2024-05-17 08:39:11

Node.js前端非阻塞I/O 模型

2021-05-05 11:36:31

Node前端自動(dòng)化熱重載頁(yè)面

2012-09-29 11:13:15

Node.JS前端開(kāi)發(fā)Node.js打包

2022-07-14 08:16:24

Node.js后端自動(dòng)化測(cè)試

2021-04-02 09:00:00

Node.js開(kāi)發(fā)工具

2024-04-15 08:00:00

人工智能DevOps

2022-08-22 07:26:32

Node.js微服務(wù)架構(gòu)

2013-09-03 09:58:51

Web前端

2022-09-12 15:58:50

node.js微服務(wù)Web

2022-07-14 10:06:20

工作流引擎營(yíng)銷自動(dòng)化vivo

2023-01-10 14:11:26

2021-07-09 00:24:10

No.jsNode.js原理

2011-09-09 14:23:13

Node.js

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2015-07-21 16:23:22

Node.js構(gòu)建分布式

2022-03-07 11:09:36

自動(dòng)化企業(yè)技術(shù)

2024-04-25 08:00:00

DevOps架構(gòu)軟件開(kāi)發(fā)

2024-03-27 11:18:02

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)