復盤node項目中遇到的13+常見問題和解決方案

2020-12-21 酷扯兒

本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫

筆者之前陸陸續續接手過幾個

nodejs

項目, 也參與過幾個有點意思的

nodejs

開源項目, 最近把其中遇到的一些問題和解決方案做一個梳理, 避免大家繼續踩坑. 話不多說我們開始吧~

1. window和mac下設置NODE_ENV變量的問題

我們都知道在前端項目中會根據不同的環境變量來處理不同的邏輯, 在

nodejs

中也一樣, 我們需要設置本地開發環境, 測試環境, 線上環境等, 此時有一直設置環境變量的方案是在

package.json

中的

script

屬性中設置, 如下:

"scripts": {"start": "export NODE_ENV=development && nodemon -w src --exec \"babel-node src\"", "build": "babel src --out-dir dist", "run-build": "node dist", "test": "echo \"Error: no test specified\" && exit 1" }

start

指令中我們可以發現我們用

export NODE_ENV=development

來定義開發環境的環境變量,由於筆者採用的是

mac

電腦,所以可以用

export

來定義一個

node

環境變量. 但是在和朋友合作開發項目時發現執行

yarn start

後會報錯, 後面看錯誤信息才發現

window

下不識別

export

, 後面筆者發現

window

定義環境變量可以用

set

, 所以對於

window

用戶, 如果你使用了以上方法設置

NODE_ENV

, 可以採用如下方式:

"scripts": {"start": "set NODE_ENV=development && nodemon -w src --exec \"babel-node src\"" }

2. 執行npm install發生node-gyp報錯的問題

在項目開發過程中有時候拉取新的

node

項目代碼後執行

npm install

, 會報如下錯誤:

node-gyp

就是在

node

環境中使用的生成不同平臺不同編譯器的項目文件, 如果你遇到了相同的問題, 我們可以採用如下方案:

npm install -g node-gyp

或者直接刪除

package-lock.json

或者

yarn.lock

, 然後重新

yarn install

或者

npm install

即可, 筆者親測有效.

3. node + koa2項目中刪除已設置的cookie的解決辦法

由於HTTP是無狀態協議,所以需要cookie來區分用戶之間的身份。我們可以把cookie作為是一個由瀏覽器和伺服器共同協作實現的規範。

cookie

的處理分為以下3步(基礎且重要的知識):

伺服器向客戶端發送cookie瀏覽器將cookie保存(可以在後端設置expires或者maxAge,以session形式存在)每次瀏覽器都會將之前設置好的cookie發向伺服器在開發

node

後臺項目時我們經常涉及用戶管理模塊, 這意味我們需要對用戶進行登錄態管理, 在用戶退出時能及時刪除用戶的

cookie

, 好在

koa2

自帶了處理

cookie

的方法, 我們可以通過如下的方式設置

cookie

:

router.post(api.validVip,async ctx => { ctx.cookies.set('vid', 'xuxiaoxi', { maxAge: 24 * 3600 * 1000 }); });

以上我們隨便設置了一個有效期為1天的

cookie

, 那如果業務有變動, 需要在有效期內清空此

cookie

, 我們該如何處理呢? 解析來給出一個相對可用的解決方案:

ctx.cookies.set('vid', '', { maxAge: 0 });

此時客戶端的

cookie

將在下次請求時自動失效.

4. socket.io如何與koa/egg配合使用

我們都知道完整的

socket.io

通信由兩部分組成:

與NodeJS HTTP 伺服器集成(或安裝在其上)的socket.io在瀏覽器端加載的客戶端庫socket.io-client如果我們直接使用

koa

或者

egg

, 我們需要將它們內部集成的

http

socket.io

做兼容, 此時我們可以這樣處理:

import koa from 'koa';import http from 'http';const app = new koa();const server = http.createServer(app.callback());const io = require('socket.io')(server);// 正常的業務處理// ioio.on('connection', (socket) => {console.log('a user connected'); socket.on('doc load', (msg) => { console.log('doc load', msg) io.emit('getData', users) }) });server.listen(3000, () => { // ...});

通過以上的方式就可以正常的將

koa

socket.io

做兼容. 後面我們就可以正常的開發

IM

應用啦~

5. 由於nodejs第三方模塊依賴特定node版本導致的報錯解決方案

這個情況筆者之前也遇到過, 主要原因是第三方沒有和

node

版本做到很好的向後兼容, 此時解決方案就是更新此第三方包到最新版本(如果還在維護的情況), 或者使用

node

包管理工具(n)切換到適配的

node

版本, 如下:

// 更新最新的包npm i xxx@latest// 使用包管理工具nnpm i -g n

使用n可以很方便的管理

node

版本, 感興趣可以嘗試一下.

6. nodejs如何創建定時任務

定時任務在後端開發中是很常見的功能之一, 其本質是根據時間規則,系統在後臺自動執行相應的任務. 在

java

,

PHP

等後臺語言中有很豐富的定時任務的支持, 對於

nodejs

這個興起之秀來說, 雖然沒有那麼成熟的生態, 但是仍然有定時任務的模塊, 比如

node-schedule

.

Node Schedule 是用於Node.js的靈活的 cron 類和非 cron 類作業調度程序。它允許我們使用可選的重複規則來安排作業(任意函數)在特定日期執行。它在任何給定時間僅使用一個計時器(而不是每秒鐘/分鐘重新評估即將到來的作業)。

一個很實用的場景是我們想在每年的雙十一或者雙十二讓

node

程序自動抓取某電商的「商品羊毛」, 並推送到自己的郵箱, 此時我們就可以用

Node Schedule

來開啟一個定時任務來執行我們的業務操作, 筆者的很多

node

應用都採用了類似的模式.感興趣可以互相交流一下.

那什麼是

cron

風格的Scheduling呢? 其

github

上給出了一個簡單的介紹:

所以我們可以像如下方式這樣來寫一個定時任務:

let schedule = require('node-schedule');let testJob = schedule.scheduleJob('42 * * * *', function(){console.log('將在未來的每個時刻的42分時執行此代碼, 比如22:42, 23:42');});

7. 在nodejs項目中使用import, export和修飾器@decorator語法

我們都知道現在

nodejs

版本已經到14.0+版本了, 對最新的es語法支持的也足夠好, 但是目前仍然有一些語法不支持, 比如es的模塊導入導出(

import

,

export

), 裝飾器(

@decorator

)等, 此時我們要在

node

項目中使用這些新特性, 我們就不得不藉助工具, 這裡筆者採用

babel7

來解決上述問題, 如下:

# .babelrc{"presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } } ] ], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", { "loose" : true }] ]}

我們只需要在項目根目錄裡新建並寫入如上文件, 並安裝

babel

對應的模塊即可, 如下:

yarn add @babel/cli @babel/core @babel/node @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/preset-env

此時就可以想寫前端項目一樣使用這些新語法特性啦~

8. nodejs中優雅的處理json文件以及提高json讀寫性能

對於

nodejs

優化方面其實有很多要聊的, 這裡主要來說說

json

相關的優化方案. 我們需要從2個方面來優化, 一個就是

json

文件的讀寫性能, 此時我們可以採用

fast-json-stringify

來大大提高

json

的讀寫速度, 其本質是提供了一套

json-schema

約束, 讓

json

結構更加有序, 從而提高

json

的讀取查詢速度. 如下使用方式:

const fastJson = require('fast-json-stringify')const stringify = fastJson({title: 'H5 Dooring Schema', type: 'object', properties: { firstName: { type: 'string' }, lastName: { type: 'string' }, age: { description: 'Age in years', type: 'integer' }, reg: { type: 'string' } }})

比如說在H5-Dooring的後臺中, 有很多需要頻繁讀寫

json

數據的接口, 此時使用

fast-json-stringify

對讀寫性能會有很大的提升.

另一方面, 我們在

node

端操作json, 如果用原生的寫法會非常麻煩, 此時我們最好自己對json讀取進行封裝來提高代碼的簡約性, 或者我們直接使用第三方庫

jsonfile

來輕鬆讀寫

json

文件, 如下使用案例:

const json = require('jsonfile')const fileName = 'h5-dooring.json'const jsonData = jsonFile.readFileSync(fileName)

9. nodejs讀取大文件報錯解決方案

nodejs

中 我們可以使用兩種方式來讀寫文件, 如下:

fs.readFile() 一次性將文件讀取進內存中, 如果文件過大會導致node內存不夠而報錯fs.createReadStream() 以文件流的方式讀取, 此時可以不用擔心文件的大小由以上介紹可知如果我們要讀取的文件可能會很大(比如視頻等大文件), 我們一開始就要使用fs.createReadStream(), 其實如果我們需要對文件進行解析, 比如要對簡歷等文件進行逐行解析提取關鍵語料, 我們可以使用

node

readline

模塊, 此時我們就可以對文件進行逐行讀取並解析, 如下案例:

const fs = require("fs");const path = require("path");const readline = require("readline");const readlineTask = readline.createInterface({input: fs.createReadStream(path.join(__dirname, './h5-dooring')),});readlineTask.on('line', function(chunk) { // 讀取每一行數據});readlineTask.on('close', function() { //文件讀取結束的邏輯}

10. nodejs如何開啟gzip優化網站性能

對於

nodejs

開啟

gzip

的操作也屬於node性能優化的一部分, 經過這樣的處理可以讓我們的網站加載更快, 我們可以使用

koa

koa-compress

中間件來實現

gzip

功能. 具體實現如下:

import koa from 'koa';import compress from 'koa-compress';const app = new koa();// 開啟gzipconst options = { threshold: 2048 };app.use(compress(options));

當然

koa-compress

還有很多自定義的配置項, 大家可以感受一下.

11. 解決window和linux系統下路徑分隔符不一致的問題

這個問題也是系統之間的差異導致的, 也是需要考慮的問題, 我們都知道在

linux

系統下路徑的分隔符為

/

, 比如

h5-dooring/src/pages

, 但是在

window

下解析的可能就是

h5-dooring\\src\\pages

這樣的路徑, 此時我們需要做適配, 不然我們部署到不同系統上報錯是必然的, 所以我們需要全局配置路徑通配符, 筆者的解決方案如下:

import os from 'os'const _$ = (os.platform().toLowerCase() === 'win32') ? '\\' : '/';

此時涉及到具體路徑的地方我們用

_$

代替即可, 以上代碼我們用到了

node

os

模塊, 感興趣的可以研究一下, 我們可以用

os

模塊處理很多有意思的因為系統差異導致的問題.

12. nodejs如何實現父子進程通信

由於

nodejs

是單線程的, 但是有時候我們需要支持處理多個進程的業務, 目前

nodejs

可以通過哦父子進程的模式來模擬多進程, 我們可以用到

child_process

, 大致流程如下:

筆者之前分享的很多

node

實戰項目都採用了

child_process

, 大致實現過程如下:

// child.jsfunction computedTotal(arr, cb) {// 耗時計算任務}// 與主進程通信// 監聽主進程信號process.on('message', (msg) => { computedTotal(bigDataArr, (flag) => { // 向主進程發送完成信號 process.send(flag); })});// main.jsconst { fork } = require('child_process');app.use(async (ctx, next) => { if(ctx.url === '/fetch') { const data = ctx.request.body; // 通知子進程開始執行任務,並傳入數據 const res = await createPromisefork('./child.js', data) } // 創建異步線程 function createPromisefork(childUrl, data) { // 加載子進程 const res = fork(childUrl) // 通知子進程開始work data && res.send(data) return new Promise(reslove => { res.on('message', f => { reslove(f) }) }) } await next()})

13. node端實現圖片編輯/壓縮

圖片編輯壓縮在很多場景中用前端的技術實現比較常見, 其實在

node

端也有很多需要處理的圖片需要, 畢竟客戶端處理的質量不好控制, 此時我們可以採用

node-images

, 他是一款

node

端輕量級跨平臺圖像編解碼庫, 其主要特性如下:

輕量級:無需安裝任何圖像處理庫。跨平臺:Windows下發布了編譯好的.node文件,下載就能用。使用簡單:jQuery風格的API,簡單可依賴我們可以使用它來裁剪, 壓縮圖片, 基本使用如下:

const images = require("images");images("input.jpg") //加載圖像文件 .size(400) //等比縮放圖像到400像素寬 .draw(images("logo.png"), 10, 10) //在(10,10)處繪製Logo .save("output.jpg", { //保存圖片到文件,圖片質量為50 quality : 50 });

在H5-Dooring 編輯器中哦你也使用了它來做圖片處理和編輯, 大家也可以更根據實際業務來使用.

14. node端解析「命令行指令字符串」實現線上自動打包部署項目

關於

node

解析

cmd

字符串並執行命令行指令的方式筆者之前在寫自己實現一個自動化工作流的文章中也介紹過, 使用了

child_process

模塊的

exec

, 具體實現可以參考文章:

基於NodeJS從零構建線上自動化打包工作流(H5-Dooring特別版)

這裡寫一個簡單的例子:

const cmdStr = `cd ${outWorkDir} && yarn build ${fid}`// 解析命令行指令, 實現線上自動打包構建項目exec(cmdStr, function(err, stdout, stderr){if(err) { console.log('api error:'+stderr); io.emit('htmlWorked', { result: 'error', message: stderr }) } else { // ... }})

15. 如何解決node應用崩潰, 負載均衡和進程管理

解決此問題最好的方式就是採用

pm2

或者

forever

, 其提供了強大的

node

進程管理, 負載均衡的能力, 並提供了一定程度的應用監控, 建議在線上環境使用

pm2

來管理我們的

node

應用.

相關焦點

  • 8Manage PM:項目管理常見問題及解決方案
    優秀的項目管理者,能在工作中提前規避風險或者制定合理方案應對,就像經驗豐富的司機,懂得如何提前判斷路況和車況,做到平穩駕駛,人車合一。因此,為了給項目管理者提供一定的經驗借鑑,8Manage 篩選出五類項目管理常見問題,並給出每個問題的解決方案,希望帶給各位一點啟發。
  • 沙發八大常見問題及解決方案
    沙發是家具產品中的大宗消費品,量大面廣。實踐經驗中,各大檢測機構總結了沙發常見的幾個問題,有利於沙發品質的保障。常見問題1:沙發泡沫塑料理化性能的取樣方式是怎麼樣的?其中標準要求中海綿的所有項目都必須在同一種海綿上進行,若樣品量不足,則選取足夠的海綿進行檢測。常見問題2:有衡量沙發軟硬度的指標嗎?如何和客戶解釋?解決方案:沙發坐感的指標在標準中可以歸屬到沙發座面的壓縮量要求上。
  • 真絲面料手工臺板印花的常見問題及解決方案
    真絲面料手工臺板印花的常見問題及解決方案 2020-04-13 15:22:29 來源:全球紡織網 真絲面料手工臺板印花的常見問題及解決方案:
  • 真石漆在施工過程中常見的問題以及解決方案!
    解決方案1.選擇優質乳液選擇具有優異耐水性的高分子丙烯酸類聚合物作為成膜材料,從源頭提高真石漆的耐水性。3.調整親水物質的比例為了確保產品的穩定性和結構,必須添加親水性物質,例如纖維素。關鍵是找到一個精確的平衡點,這需要重複進行實驗。2、噴塗飛濺,嚴重浪費一些真石漆噴塗過程中會掉砂,甚至四處飛濺。在嚴重的情況下,大約1/3會被浪費掉。
  • 《膩子施工常見問題與解決方案》——倍得麗首發行業施工指南
    《膩子施工常見問題與解決方案》行業發展迅速,但施工指南缺席已久眾所周知,在家庭裝修中,牆、地面塗 裝這一重要的部分將由油工來完成《膩子施工常見問題與解決方案》應需而生,倍得麗精心彙編在這個情況下,有一份能夠詳細闡述膩子施工標準、施工要點以及遇到的各種問題的產生原因,應當怎樣去解決
  • 一體化設備汙水處理專項方案在使用過程中常見的問題有哪些
    一體化設備汙水處理專項方案在使用過程中常見的問題有哪些 ,「m53lt」   江蘇眾途環保工程有限公司生產一體化設備汙水處理專項方案,運行穩定可靠,使用壽命長,如有需要,歡迎隨時來電諮詢!
  • 最常見八大皮膚問題的成因和解決方案,讓你做個素顏美人!
    皮膚是我們人體最大的器官,而臉部皮膚的健康是我們每個人最關切的。光療美膚方案:毛孔清潔水氧器:利用高壓氣體噴射出水氧氣粒,輕鬆進入毛囊和皮脂腺,即刻講堵塞的毛囊孔衝開改善各種黑頭,暗瘡,毛囊炎,皮膚暗啞深層清潔皮膚,同時給皮膚補充水分和氧氣 成因:黑頭其實是暗瘡早期的重要發展階段,黑頭長到若干大小,就會阻塞毛孔,死細胞的殘骸、
  • 復盤:光伏電站常見問題解答【建議收藏】
    光伏電站常見問題都有哪些,如何確保電站安全穩定運行,保證最大發電量。 本文對這些問題進行集中呈現,供諸君參考。 9、備案過的項目還能夠申請變更麼?怎麼變更? 答:備案過的項目一般情況下不能隨意變更。如果項目實施過程中遇到特殊情況,必須變更原方案,則必須按照當初的申報程序,申請方案變更。 10、裝完光伏發電系統,還需要付什麼錢?
  • 您遇到的排便問題,這裡都能找到解決方案
    不管你是優雅的女士,還是玉樹臨風的男士,一樣都會遇到便便的問題。拉稀、不成形、間隔性拉稀與便秘、便秘,這些常見的便便問題,今天我們一起聊一聊吧。首先,我們應該明確一個理念:如果我們還年輕,卻總是出現各種健康問題,一定是身體長期被我們忽視和虐待的結果。如果這些錯誤的做法不改變,就算這次問題僥倖解決了, 下次還是照樣會出現。
  • 5大健身初期遇到的問題,解決方案都在這裡了
    相信很多小夥伴在最開始運動的時候都遇到過一些這樣或那樣的問題,自己也不知道是不是屬於正常現象。如果沒有教練或健身大神的指導的話,自己也難以摸索出解決辦法。遇到這種情況,我們完全可以直接請教健身房裡的教練和看起來很厲害的大神們。
  • 仿石漆施工常見問題(起皮、開裂)解決方案
    5D潔淨隔熱仿石漆效果做外牆仿石漆最常見的問題有幾個:起皮,開裂,翹邊,而引起這些問題的原因,無非是兩個方面,一個方面是用材料不對,另外一個方面就是施工的工藝有問題。作為一個年施工面積超過五百萬平米仿石漆的品牌,解決這些問題一般都是駕輕就熟,只要材料選對,工藝做到位,做出來的仿石漆一個是美觀大氣,細節處理極為到位,抗汙和耐用性能不低於石材。
  • 中戶型設計解決方案
    通過對優秀中戶型案例的解析,掌握項目設計分析、判斷、定位和設計流程把握中戶型居住空間的性質特點,從而掌握此類居住空間的設計要點能進行設計項目分析,解決客戶實際問題,最終完成方案設計階段相應圖紙>一、中戶型設計案例解析二、中戶型的空間概念與功能布局一、中戶型設計案例解析設計案例A:《華潤二十四城樣板房設計作品》 香港著名設計師 — 高文安
  • 10個英語課堂常見的問題和解決方法老師的秘笈
    很多時候,這意味著要處理教室中的各種問題,其中許多都是太常見的現象。一位出色的英語老師必須能夠識別這些常見問題,並努力尋找解決方案。您的教學方法稍作調整,可以為您的學生創造一個更高效,更休閒的環境。為了解決此問題,英語教師必須嚴格,並在需要時紀律處分。如果這種情況繼續發生,則可以通過學校採取進一步的紀律處分。4.學生「劫持課程」-該課程不會轉到您想要的地方。在英語作為外語教學時,您總是會遇到想要劫持一堂課的學生。在某種程度上,這可能是一件好事。
  • 第二期:「自動避免Namenode的單點故障導致的集群不可用」獲獎公布
    請獲獎的朋友:孔慶濤和張汝坤通過郵件聯繫我們(kangwb@csdn.net),我們將送出價值¥1750元的大會門票!技術問題 孔慶濤 通過郵箱回答關於解決hadoop單點故障問題,在我的博客詳細描述了解決方案。
  • 馬上快年底了,今年跟了很多項目,我們該怎麼做項目復盤工作呢?
    先別忙著悶頭寫復盤總結書,我建議你一定要先開一次復盤會議。項目不管大小,一定有很多細節上的分工,復盤必須要聽具體實施者的反饋,才能看到不同人的能力以及項目存在的問題。請誰來參會?人並不是越多越好,而要選擇有核心價值的重點參與人,如每個部門負責人、業務骨幹,要讓他們呈現一個完整真實的項目過程。
  • 電動觀光車銷售中的常見問題及解決辦法,全部告訴你
    [摘要]你了解電動觀光車銷售中的常見問題及解決辦法嗎?用客戶關心的問題和解決辦公都在這裡,讓我們一起來看看吧! 標準的配置單包括如下項目: 1、產品型號 2、產品尺寸 3、電池容量 4、電機功率 5、控制器品牌 6、方向控制 7、剎車系統 8、最高車速 9、制動距離 10、爬坡度 11、最小轉彎半徑 12、最大載重量 13、續行裡程
  • 項目管理:項目owner的日與夜
    我們大多數的運營人、產品人都曾經是從執行小角色做起,我們都一直期冀著自己終有一日能成為一個獨當一面的項目owner。筆者從業經驗已有6年,現在我從自身的項目經驗和心得出發,來跟大家一起探討項目管理與實施中遇到的問題及其解決的辦法。
  • 快速在你的vue/react應用中實現ssr(服務端渲染)
    所以為了解決SPA應用遇到的這些問題, 我們必須考慮SSR:服務端渲染(ssr),是指由伺服器端完成頁面的HTML結構拼接,並且直接將拼接好的HTML發送到瀏覽器,然後為其綁定狀態與事件而本文要講的技術方案,正是為了解決SPA下的SSR技術困境.接下來我們看看常用的ssr技術實現方案.
  • ANSYS|ansys18.0完整安裝過程及常見問題解決方案「圖文」
    解決方法:重啟電腦,此方法簡單而有效,我安裝過十幾次ansys,只遇到過一次這種情況,重啟後,不打開任何程序,直接開始安裝,沒有任何問題。11、特別強調,請務必留意上一步驟圖片中的提示,「Installation Complete. 」這句話,在我安裝多臺電腦的過程中,遇到兩次特殊情況(忘記截圖),這一步沒有「Installation Complete. 」這句話,而是有一行紅色的英文在這裡,大意是「安裝失敗,ANSYS程序安裝不完整」,這兩次特殊情況正好對應了兩種完全不同的問題,解決思路也完全不一樣
  • 盤點B端產品經理快速提升法之復盤!
    不止是我,很多人都不願意去復盤。覺得功能上線就是終點,其實,這只是個開始。每一次復盤時對自己的批判和肯定,逐漸構建了自己的知識體系。知道哪邊可能會有坑,知道如何最小成本試錯,知道怎麼找到用戶需求和開發成本之間的平衡點,知道怎麼推動項目,知道怎麼和其他團隊協作.....