最近學習react,本身作了個大屏展現的小項目,本地開發相對比較順利,可是在進行線上部署的時候卻遇到了問題,費了很多精力,走了很多彎路。謹以此文作記念,若是能幫到遇到相同問題的你,倍感榮幸。html
項目界面以下:
前端
線下開發流程不是本文的重點,在次略過,若是須要能夠參考個人另外一篇文章《react的開發部署》。接下來就說說服務器上的部署。 node
我總結了一下線上部署大概有兩種方式:react
本地開發完成後執行npm run build命令會在項目的根目錄生成一個build目錄,這個目錄中就是開發文件打包後的文件,大概是這個樣子的:nginx
將這個目錄上傳到服務器上,而後用nginx來處理,假設你有一個域名:http://www.reactdemo.com;那麼你須要作的就是找到nginx的中的conf文件(通常安裝在/usr/local/nginx/中,固然也可能不同,也有可能nginx的安裝目錄和conf文件的目錄是分開的,這裏涉及到一些服務器上的操做,你須要自行去肯定),打開nginx.conf.default文件,在其中添加一些代碼(假設個人代碼放在/www/build中):shell
server { listen 80; server\_name www.reactdemo.com; root /www/build; index index.html; }
那麼第一步就執行完了,而後啓動nginx就能夠了:npm
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf.default
json
若是啓動沒有報錯,那麼就能夠直接在瀏覽器中運行了。segmentfault
這種方式與第一種不一樣的是,全部的操做都是在服務器上操做的。build目錄也是在服務器上生成的,具體操做以下:瀏覽器
將本地的整個項目(不包括node_modules目錄)上傳到服務器,至關於在服務器上建立了一個項目。
記得運行npm install來安裝依賴,而後執行npm run build來生成靜態的文件,這一步會執行一些校驗、壓縮等操做,而後在項目的根目錄生成一個build文件,這個build跟第一種方式上傳的build是同樣的。
這裏可能你會想執行其實很簡單,不就是輸入命令npm start嗎?其實這種方式也能夠,pm2也能守護,可是這個命令實際上是開啓了一個本地開發服務器,也比較簡單。
可是若是要大量訪問的時候,是須要生成production環境的文件,因此須要執行npm run build命令,當你執行npm run build命令後,會提示你安裝serve命令以及執行serve命令的方法,這裏忘記保存圖片了,提示你的命令有兩條
npm install -g serve serve -s build
serve命令能夠運行一個靜態站點,npm網站時這樣介紹的
Assuming you would like to serve a static site, single page application or just a static file (no matter if on your device or on the local network), this package is just the right choice for you.
根據提示安裝好serve,而後執行serve -l 5500 -s build命令(因爲端口占用問題,我須要在5500端口運行,因此添加了參數-l 5500),這裏還須要在nginx上加代理(由於是在服務器本地執行的):
location / { proxy http://127.0.0.1:5500 }
而後瀏覽器訪問域名,一切正常,看起來很完美。可是,困擾我半天的問題來了:
當xshell命令窗口關閉或長時間不操做致使網絡斷開的時候,瀏覽器返回了502
看到這個問題,我想你們的第一反映就是添加守護程序,對,我也是這麼想的,因此我用pm2來做爲守護程序
pm2 start serve -l 5500 -s build --name reactApp -- run start
不知道是否是我沒寫正確,最終沒有成功。而後在這個問題上折騰了一上午,後面我反映過來不能在這麼下去,所以我到本地一個前端羣裏請教了一些同行,其中一位建議我使用nohup,但nohup我不是很瞭解;另外一位給了我一段代碼
module.exports = { apps: [{ name: "app", script: "/usr/bin/npm", args: 'run start', cwd: '/home/nuxtapp' }] }
意思就是在根目錄建一個文件包含這段代碼,而後用pm2去啓動這個文件,我嘗試後任然沒有解決。前先後後看了不少網上的文章,你們遇到相似的問題不多,基本都用第一種方式就解決了。可是我仍是想試試第二種,前端的問題就在前端解決。就在我覺得要暫時擱置這個問題的時候,無心間打開了package.json文件,看到了script這裏,不知道是否是靈感忽然來了,看了自帶的命令後,我決定嘗試添加一個新的命令來代替serve執行:
結果,就這麼成功了,也許熟悉的人會笑話這時個很簡單的問題(丟人了)。可是通過個人折騰最終解決了這個問題,很高興,不是嗎?