本地NodeJS應用使用Egg腳手架構建,本地運行測試徹底沒有問題,發佈後App Service後不能運行。經過登陸到kudu後(https://<your web site>.scm.chinacloudsites.cn)後,在日誌中發現找不到一個文件或路徑的錯誤。經過在kudu的CMD窗口執行npm start命令,發現錯誤是一致,懷疑是對Egg中某個框架的不支持。node
Application has thrown an uncaught exception and is terminated:
SystemError [ERR_SYSTEM_ERROR]: A system error occurred: uv_os_get_passwd returned ENOENT (no such file or directory)
at Object.userInfo (os.js:272:11)
at module.exports (D:\home\site\wwwroot\pynode\node_modules\node-homedir\index.js:10:26)
at AppWorkerLoader.getHomedir (D:\home\site\wwwroot\pynode\node_modules\egg-core\lib\loader\egg_loader.js:163:36)
at AppWorkerLoader.getAppInfo (D:\home\site\wwwroot\pynode\node_modules\egg-core\lib\loader\egg_loader.js:174:23)
at new EggLoader (D:\home\site\wwwroot\pynode\node_modules\egg-core\lib\loader\egg_loader.js:87:25)
at new AppWorkerLoader (D:\home\site\wwwroot\pynode\node_modules\egg\lib\loader\app_worker_loader.js:9:1)
at new EggCore (D:\home\site\wwwroot\pynode\node_modules\egg-core\lib\egg.js:118:19)
at new EggApplication (D:\home\site\wwwroot\pynode\node_modules\egg\lib\egg.js:43:5)
at new Application (D:\home\site\wwwroot\pynode\node_modules\egg\lib\application.js:60:5)
at Object.<anonymous> (D:\home\site\wwwroot\pynode\index.js:3:13)
在詳細的log文件中,能夠看見全面的錯誤信息。並指出了報錯的源文件爲:(D:\home\site\wwwroot\pynode\node_modules\node-homedir\index.js:10:26),在源代碼中,找出了問題的根源。git
node_modules\node-homedir\index.js 源碼:github
1 'use strict'; 2 3 const os = require('os'); 4 5 module.exports = () => { 6 if (process.env.MOCK_HOME_DIR) return process.env.MOCK_HOME_DIR; 7 8 if (typeof os.userInfo === 'function') { 9 try { 10 const homedir =os.userInfo().homedir; 11 if (homedir) return homedir; 12 } catch (err) { 13 if (err.code !== 'ENOENT') throw err; 14 } 15 } 16 17 if (typeof os.homedir === 'function') { 18 return os.homedir(); 19 } 20 21 return process.env.HOME; 22 };
在第十行代碼中,使用了os對象,而在App Service中,因爲是sandbox 模式下,因此某些操做被禁止了。關於禁止的說明能夠參考:https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#general-sandbox-restrictionsweb
在查看源代碼後,想解決它就有兩種辦法:npm
1) 在修改node-homedir\index.js中的源代碼,把裏面 os.userInfo().homedir 的部分替換成在App Service中的Homedir路徑,hardcode這一部分。如 const homedir =」D:\home\site\wwwroot\「;//os.userInfo().homedir;架構
2) 最快速且無代碼改動方案。在App Service的應用程序設置中(Applicaiton Settings)添加一個名MOCK_HOME_DIR的設置,並設置其值爲D:\home\site\wwwroot\ (爲應用程序發佈的默認路徑)。 這樣node-homedir的源代碼就不會進入到os部分。直接在第一行就返回須要的homedir.app
PS: 這裏是把NodeJS的應用發佈在Windows的環境中碰見的問題,如發佈在App Service For Linux則能夠避免相似問題。框架