从零开始用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安装的实际路径,每一个人都不尽相同,请注意。

在我实际开的过程当中也遇到了其余的问题,但这些都不具备共性,是代码层面的,我就再也不多说。