用node開發後端會存在那些問題呢? 在我們用node做後端開發遇到的三個問題。一安全問題,代碼並沒有編譯就直接傳遞了,只要進去服務器代碼可以看得一清二楚。二是文件體積問題,隨便一個項目node_modules件包就是一百兆左右。第三個是部署問題,每次部署新項目都要下載安裝插件導致部署非常緩慢。
我們又有哪些解決方案呢? 首先我們來看一下最重要的安全問題,node沒有像java做好之後可以打包編譯為一個很小的jar包。但前端我們也有了編譯混淆工具,如webpack或vite等。做個vue、angular、react項目的同學,我想應該對這個工具不陌生吧!webpack在前端領域用的確實比較多,特別是之前的vue2項目。其實它還可以用於node環境下的後端項目,比如express框架,koa框架等。只是配置信息需要研究。我本着將所有代碼(包含node_modules)全部打包為一個文件。結果啓動時發現存在不少問題。這時我換了另一套方案,只打包自己寫的代碼。而node_modules插件包裏的代碼不再進行打包。結果也確實很滿意,我們可以看到整個文件大小不到兩百kb。
而混淆之後的代碼雖然能看到源碼,但就算破解了,也得自己手寫一遍才能還原。因為裏面的變量命名都變為了abcd,代碼閲讀難度極大。也不可能會百分百還原源代碼。
附上webpack的配置代碼如下
const path = require('path');
const nodeExternals = require('webpack-node-externals');
console.log(path.resolve(__dirname, "dist"))
module.exports = {
entry:'./index.js',
mode: 'production',
target:"node",
output:{
path: path.resolve(__dirname, "dist_server"),
filename:'index.js',
publicPath: path.resolve(__dirname, "statics")
},
node: {
},
externals: [
nodeExternals()
],
module: {
},
plugins:[
],
resolve:{
}
}
雖然我們解決了安全問題,但node_modules這個插件包體積實在太大。同樣給我們的服務器資源照成了不必要的浪費。而且安裝起來也很慢。我們之前的第一個方案是提取node_modules用到的核心文件然後打包到一個文件裏,這顯然是不行,問題也特別多。我們的項目用到的框架一樣,技術一樣,為什麼不能多個項目用同一個插件包呢?於是經過反覆嘗試,發現當前項目package.json如果不存在,它們不斷的去往上級文件夾找。也就是你只需要把多個項目放到一個文件夾裏,然後再添加package.json 然後安裝一下。所有的子文件夾裏的項目都能使用這個公共的插件包了。這樣我們就很完美的解決了以上幾個問題。
最後打包的速度也提升了不少,兩秒左右就打包好了,服務器的部署也簡單很多,只需上傳200kb左右的打包文件然後啓動文件即可。(安裝都省去了)
node服務端打包編譯之後又會出現那些新的問題? 當然這還遠遠沒有結束,因為我們發現打包之後靜態文件無法訪問,移動文件夾位置之後反覆測試,結果發現數據庫備份的位置也有所偏差。總之對文件的讀寫這塊存在諸多問題。反覆閲讀代碼發現我們在開發過程中用到了一個__dirname這麼一個變量,而這個變量就是根據當前的文件來獲取絕對位置。比如文章控制器這塊用到了這個變量,則它的絕對路徑為D:\gitwork\guiplan-study-game-admin\servers\app\controller\articleController.js
如果不是在控制器裏用這個變量,而是更目錄如app.js,這時的絕對路徑則為D:\gitwork\guiplan-study-game-admin\servers\app\app.js。所以這個變量的值它是變化的。
而我們打包之後的文件只有一個index.js文件,所有的文件都打包成了一個文件,所以這個時候你再去用__dirname這個變量,它所指的位置則是根目錄。並且不會改變。所以就導致靜態目錄存儲的位置與數據庫存儲的位置都不同的原因。 好!我們找到的問題的原因,那我們如何去解決這個問題呢?其實用過webpack的同學應該對環境判斷不陌生吧?是的,同樣的後端打包編譯我們一樣的可以添加一個環境判斷。我們只需將所有用到__dirname這個變量的地方都添加一個判斷,然後重新拼接一個絕對路徑。比如app.js裏的渲染器代碼
render(app, {
root: path.join(__dirname,'../', config.static.path,'view'),
extname: '.html',
debug: process.env.NODE_ENV !== 'production',
dateFormat:dateFormat=(value)=>{
return moment(value).format('YYYY-MM-DD HH:mm');
}
});
可以修改為
let rootPaht = ''
if(process.env.NODE_ENV == 'production'){
rootPaht = path.join(__dirname,'/', config.static.path,'view')
}else{
rootPaht = path.join(__dirname,'../', config.static.path,'view')
}
render(app, {
root: rootPaht,
extname: '.html',
debug: process.env.NODE_ENV !== 'production',
dateFormat:dateFormat=(value)=>{
return moment(value).format('YYYY-MM-DD HH:mm');
}
});
這樣哪怕編譯打包之後也不會再存在靜態文件目錄不正確的問題了全名記單詞遊戲案例展示。 最後我們來看看我這邊用guiplan低代碼開發工具做好的全名記單詞遊戲項目。小程序端與後台以及後端接口配置都是可視化開發。
(uniapp小程序)
(遊戲後台管理) 最後數據庫進行備份,靜態文件備份。靜態文件包括這些單詞的圖片,音頻以及後台管理系統源代碼,後端的源代碼以及前台頁面等。所有的文件加起來也就12兆。後續靜態文件放其他流媒體服務器,數據庫備份文件不算的話。一個前後端項目總大小約6兆左右。原本一個項目需要一百多兆,優化完之後只需6兆左右。空間節省20倍左右。
原文轉載 http://www.guiplan.com/articl...