從零開始用React搭建本身的技術博客,遇到的問題

從零開始用React搭建本身的技術博客,遇到的問題前端

前段時間,我花了些時間跟着教學視頻自學了React,因此也想着本身用所學的技術作一個我的博客網站。node

我也很少廢話,直接列出本身在開發過程當中所用的技術和遇到的一系列問題以及解決辦法。我相對於大多數剛學React,也想作一個練手項目的同窗而言,個人我的經驗可能頗有啓發意義;由於我遇到的問題,你們也極可能遇到。react

首先,這個博客網站包括3個部分:博客前臺、管理後臺、接口中臺。這3個部分也應用了不一樣的技術,前臺博客使用了next.js,經過服務端渲染(ssr:首屏加載更快、利於seo等),後臺管理使用的是React作的SPA,其中UI框架用的是Ant Design;中臺用的是egg.js(基於koa.js的上層框架)。linux

對於不少剛學了React的同窗而言,確定是會用React開發spa的(建議擁抱react hooks,順應趨勢),而對於中臺接口可能你們也會使用express、koa等等去實現,這些我就再也不多說。而next.js,在國內討論的沒有那麼多(我遇到問題不容易查到),這可能存在問題。nginx

因此,我遇到的問題中我以爲值得講的主要包括next.js;而另外一塊就是做爲前端工程師不太懂的項目的部署(我也沒那麼懂,但我會往簡單的講讓你們理解)。在這裏,我就恬不知恥地掛一下本身博客的地址,歡迎你們訪問:immortalboy.cnexpress

你們知道,SSR是的好處是能夠優化SEO、同時能加快首屏加載速度的。由於頁面是在服務端渲染的,頁面上的接口請求也一同在後端完成了。因此我要說的第一點:以往咱們在生命週期裏請求接口的代碼(或者是在useEffect裏請求的代碼),須要寫在別的地方。next..js中提供了一個方法getInitialProps,全部在useEffect裏調用的接口應當拿到這裏面來。 (next.js的最新版本中,更推薦使用getStaticpropsgetServerSideprops來代替getInitialProps;可是使用getInitialProps沒有問題,並且使用後者可能會出現編譯時的ESLint的警告,我建議使用getInitialPropsnpm

第二點,也是初學者容易犯的,不是全部的頁面都須要服務端渲染,真正須要服務端渲染只有一級導航的頁面,因此對於詳情頁一類的二級頁面徹底能夠按照SPA的開發習慣使用UseEffect 。後端

因爲next.js在開發中代碼和SPA的區別不大,像我這種初學者就犯了這個錯,我把全部的頁面都使用了UseEffect而忘了經過getInitialProps來達到服務端渲染。 因此,我上面羅裏吧嗦地說了半天就兩點:api

  1. 使用getInitialProps代替UseEffect運行頁面加載時調用的接口代碼;
  2. 只須要在一級導航頁面實現SSR;
  3. 服務器帶寬也決定了加載速度,因此爲了省錢,我的博客不必定要那麼快(帶寬很貴);

至於代碼層面的,我尚未資格去講,不少人可能用的都比我熟練,我也不必浪費你們的時間。 下面我要將的就是項目部署,我在這裏吃了很多虧,由於沒有經驗。我先說說個人狀況:我不會linux命令,因此服務器買的是window server,網站的文件服務器用的是nginx(nginx我也不熟)。bash

下面到了乾貨階段(但願算是)。現狀是,管理後臺SPA會打包成靜態頁面,前臺博客構建後是一個本地服務(默認端口3000),中臺接口egg.js也是一個本地服務(端口7001)。如今問題來了,服務器上本地訪問能夠,可是一旦經過域名訪問就行不通。 對於這種狀況,不少同窗可能想到了,能夠經過nginx反向代理實現。只要把服務器的端口代理到本地的服務的端口上就能夠了。

server {
        listen 8001;
        server_name immortalboy.cn;
        location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;  
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Nginx-Proxy true;
            proxy_cache_bypass $http_upgrade;
            proxy_pass http://127.0.0.1:7001; #反向代理
        }
    }
複製代碼

對於博客前臺,須要把nginx的80端口代理到前臺服務的3000端口。

server {
        listen 80;
        server_name immortalboy.cn;
        location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;  
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Nginx-Proxy true;
            proxy_cache_bypass $http_upgrade;
            proxy_pass http://127.0.0.1:3000; #反向代理
        }
    }
複製代碼

而管理後臺,我是用了一個二級域名,一樣監聽80端口(默認端口),由於後臺是部署在nginx內部的SPA,不必再代理了。

可是若是須要本身的網站支持https呢(能夠經過服務器廠商申請免費證書)?咱們知道https只監聽443端口,顯然上面的方法行不通了,由於咱們的中臺是監聽的8001端口的。

這時候,由於有兩個服務都須要反向代理,可是咱們只有一個443端口,因此咱們這時候不可以拿端口去區分這2個服務了。只能經過路由去匹配。對於博客前臺,變化不大:

server {
        listen 443 ssl;
        server_name immortalboy.cn;
        // 證書部分省略,避免賦值產生誤導
        location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;  
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Nginx-Proxy true;
            proxy_cache_bypass $http_upgrade;
            proxy_pass http://127.0.0.1:3000; #反向代理
        }
    }
複製代碼

經過路由的話,匹配方式以下:

location /api {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;  
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Nginx-Proxy true;
      proxy_cache_bypass $http_upgrade;
      proxy_pass http://127.0.0.1:7001; #反向代理
    }
複製代碼

你們若是和我你同樣對於nginx不太熟練,能夠參照個人辦法去解決。

除此以外,咱們知道egg.js自己是集成了進程管理功能的,因此咱們不用處理。可是對於next.js咱們須要經過pm2來作進程守護,經過pm2來管理。在這裏,我也遇到了一個坑,可能你們也會遇到,因此我先給你們打下預防針。我先列一下經常使用的pm2命令

pm2 list // 列出全部進程
pm2  delete id/進程名 // 銷燬一個進程
pm2 logs // 打印日誌
pm2 start npm --name  '進程名' --run product // 這裏的product其實是npm中配置的npm script裏的腳本命令
// eg: pm2 start npm --name  'blog' --run product
複製代碼

上面的命令中比較難理解和可能會出現就是最後一行,實際這行命令的意思是讓pm2開啓了一個指定名稱的進程,運行了npm script裏的指定命令。你們多試幾回就能明白它的意思,可是若是實在window server下,即使命令是正確的,也可能會出現問題。由於pm2極可能找不到npm,這個時候咱們須要使用npm腳本的絕對路徑來代替npm,上面的代碼更改後爲:

pm2 start C:\software\Nodejs\node_modules\npm\bin\npm-cli.js --name  'blog' --run product 
複製代碼

上面的路徑是服務器中npm安裝的實際路徑,每一個人都不盡相同,請注意。

在我實際開的過程當中也遇到了其餘的問題,但這些都不具備共性,是代碼層面的,我就再也不多說。