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

基于NodeJS從零構(gòu)建線上自動化打包工作流

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

前言

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

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

你將收獲

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

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

圖片

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

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

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

圖片

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

圖片

圖片

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

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

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

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

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

圖片

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

// child.js
function computedTotal(arr, cb) {
// 耗時計算任務(wù)
}

// 與主進(jìn)程通信
// 監(jiān)聽主進(jìn)程信號
process.on('message', (msg) => {
computedTotal(bigDataArr, (flag) => {
// 向主進(jìn)程發(fā)送完成信號
process.send(flag);
})
});

// main.js
const { fork } = require('child_process');

app.use(async (ctx, next) => {
if(ctx.url === '/fetch') {
const data = ctx.request.body;
// 通知子進(jìn)程開始執(zhí)行任務(wù),并傳入數(shù)據(jù)
const res = await createPromisefork('./child.js', data)
}
// 創(chuàng)建異步線程
function createPromisefork(childUrl, data) {
// 加載子進(jìn)程
const res = fork(childUrl)
// 通知子進(jìn)程開始work
data && res.send(data)
return new Promise(reslove => {
res.on('message', f => {
reslove(f)
})
})
}

await next()
})復(fù)制代碼

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

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

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

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

圖片

為了實現(xiàn)以上過程,我們需要兩個關(guān)鍵環(huán)節(jié):

  • 將用戶配置的數(shù)據(jù)進(jìn)行處理并生成json文件,然后移動到H5 Template母版中
  • 在母版中自動執(zhí)行打包編譯腳本

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

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

import { exec } from 'child_process'
const outWorkDir = resolve(__dirname, '../h5_landing')
const fid = uuid(8, 16)
const cmdStr = `cd ${outWorkDir} && yarn build ${fid}`

// ...exec相關(guān)代碼
const filePath = resolve(__dirname, '../h5_landing/src/assets/config.json')
const res = WF(filePath, data)

exec(cmdStr, function(err,stdout,stderr){
if(err) {
// 錯誤處理
} else {
// 成功處理
}
})復(fù)制代碼

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

4. socket.io實現(xiàn)消息實時推送

在上面介紹的 exec實現(xiàn)解析并執(zhí)行命令行指令

  • 客戶端請求長輪詢
  • postmessage消息推送
  • websocket雙向通信

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

// node端
exec(cmdStr, function(err,stdout,stderr){
if(err) {
console.log('api error:'+stderr);
io.emit('htmlFail', { result: 'error', message: stderr })
} else {
io.emit('htmlSuccess', { result: dest, message: stderr })
}
})

// 瀏覽器端
const socket = io(serverUrl);
// ...省略其他業(yè)務(wù)代碼
useEffect(() => {
socket.on('connect', function(){
console.log('connect')
});
socket.on('htmlFail', function(data){
// ...
});
socket.on('disconnect', function(e){
console.log('disconnect', e)
});
}, [])復(fù)制代碼

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

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

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

6. 總結(jié)

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

責(zé)任編輯:武曉燕 來源: 趣談前端
相關(guān)推薦

2023-07-21 15:26:00

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

2021-08-13 14:00:14

Node.js開發(fā)前端

2024-05-17 08:39:11

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

2024-04-15 08:00:00

人工智能DevOps

2022-07-14 10:06:20

工作流引擎營銷自動化vivo

2022-03-07 11:09:36

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

2025-04-29 08:00:00

Rowboat多智能體人工智能

2012-09-04 10:20:31

IBMdw

2024-09-29 16:31:23

2009-03-27 09:48:56

SnapFlowWaaS工作流

2022-10-26 08:00:43

Activiti工作流BPM

2020-11-06 08:43:21

AIOps運(yùn)維DevOps

2021-10-14 11:34:05

技術(shù)工作流引擎

2025-04-28 09:10:00

智能體Agent工作流

2019-03-10 21:13:03

UbuntuLinuxAlfred

2017-09-07 16:43:36

互聯(lián)網(wǎng)

2022-07-10 21:17:01

GitTigLinux

2017-04-05 10:06:59

工作流界面抽象組件

2018-12-10 08:10:39

2018-05-10 15:54:39

點(diǎn)贊
收藏

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