前端工程化 - 使用 Nginx 管理你的前端资源

前言

在前端项目开发中,我们可以启动 devserver 管理静态资源服务,但是发布线上后要保证稳定,一般会选择一个高效能 + 稳定的静态服务器来管理前端资源。

作为前端工程化的关键一环节,这一篇我们来一起学习一下 Nginx 的常见用法。

Nginx (engine x) 是一个高性能的 HTTP反向代理 web 服务器,同时也提供了IMAP/POP3/SMTP 服务。

常规使用

Nginx 的安装过程就省略了,毕竟是基操,WIndows 都是一键安装的。

先记住几个常用的命令,待会我们会不断的使用到它们:

  • start nginx:启动
  • nginx nginx -s reload:修改配置后重新加载生效
  • nginx -s stop:快速停止
  • nginx nginx -s quit:完整有序的停止 nginx

反向代理静态资源

对于前端来说,最常见的还是代理静态资源的问题,我们挑选 VUE 项目作为测试;

使用 Vue CLI 创建一个 demo 项目,运行 yarn build 输出如下静态资源:

image.png

将上述的生成的静态资源复制到任意目录(路径随意,你开心就行

image.png

修改 nginx.conf 文件后,启动 Nginx。

nginx.conf 文件都在 Nginx 安装目录 config 文件夹下

http {
    include       mime.types;
    default_type  application/octet-stream;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;
        location / {
            root   html; // 切换成你的静态资源目录
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
复制代码

image.png

直接启动报错也很正常,资源的路径不对,这个时候可以选择构建的时候使用相对路径或者修改 root 根路径为 dist 即可,这里由于我们是讲解 Nginx 配置,所以选择将 root 根路径修改为 dist 再重启访问。

image.png

这个时候大家可以注意到,我们的访问路径已经从 http://127.0.0.1/dist 改变成 http://127.0.0.1/。

image.png

如果你是默认 vue-cli 创建的带路由的项目,那么可以点击一下 About,是可以正常访问,但是刷新之后就会变成 404,这个很正常,默认的路由模式是 hitstory,只需要加上 try file 就可以了。


location / {
    root   html/dist/;
    # index  index.html index.htm;
    try_files $uri $uri/ / ;
}
复制代码

同时,我们在正常使用静态资源的时候也并不是根据 ip 来访问,这里我们可以根据 server_name 配置域名访问。

首先本地 host 配置一个域名 dns 解析到本地:

127.0.0.1 fe.cookieboty.com
复制代码

再在 location 里面添加 server_name 配置,重启 nginx 即可。

 server {
    listen       80;
    server_name fe.cookieboty.com; // 配置监听域名
    location / {
        root   html/dist/;
        try_files $uri $uri/ / ;
    }

    error_page   500 502 503 504  /50x.html;

    location = /50x.html {
        root   html;
    }
}
复制代码

image.png

反向代理接口

反向代理接口也比较简单,经常用碰到的还是跨域的问题,所以才需要代理。

接下来,我们来代理一下掘金的接口看看,正常这种接口再我们的项目中使用是会有跨域的问题。

在 demo 项目中使用 axios 来请求掘金的接口 api.juejin.cn/tag_api/v1/… :

import axios from "axios";

export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  setup() {
    axios
      .get("https://api.juejin.cn/tag_api/v1/query_category_briefs")
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
  },
};
复制代码

image.png

虽然没有报跨域的错误,但是直接被 403 拦截了,资源被服务器拦截了。我们用 nginx 的 proxy_pass 来代理这个请求看看。

 server {
    listen       80;
    server_name juejin.cookieboty.com;
    location / {
        proxy_pass  https://api.juejin.cn/;
    }
}
复制代码

浏览器直接访问 juejin.cookieboty.com/tag_api/v1/… 出现如下结果则代表反向代理接口没问题。

image.png

但是在项目中直接运行的时候依然有 403 的错误,如果代理没问题,那就是请求参数有不一致的地方,导致被服务器拒绝,简单对比一下,发现 header 里面的 Orgin 参数有不一致的情况,所以我们修改将转发之后请求头部的 Orgin 设置为 api.juejin.cn 后重启看下效果:

 server {
    listen       80;
    server_name juejin.cookieboty.com;

    location / {
        proxy_set_header Origin https://api.juejin.cn; // 新增 Origin 修改代码
        proxy_pass  https://api.juejin.cn/;
    }
}
复制代码

image.png

完美,demo 项目已经正常代理拿到掘金分类接口的数据了。

似乎没有遇到 cors 跨域的问题,那么后面再说这个好了。

Nginx 参数配置详解

正常根据上述配置,已经可以简单的使用 nginx 的反向代理了,为了后续的更灵活的配置,我们也一起学习一下 Nginx 的参数配置:

nginx.conf 组成

...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}
复制代码

nginx.conf 由以下 5 个模块构成:

  1. 全局块:配置影响 nginx 全局的指令。一般有运行 nginx 服务器的用户组,nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。
  2. events:配置影响 nginx 服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
  3. http:可以嵌套多个 server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type 定义,日志自定义,是否使用 sendfile 传输文件,连接超时时间,单连接请求数等。
  4. server:配置虚拟主机的相关参数,一个 http 中可以有多个 server。
  5. location:配置请求的路由,以及各种页面的处理情况。

对于前端来说一般使用 server + location 两个模块足够了。

变量参数

全部的 nginx 变量还是非常多的,简单列举几个可能会使用到的:

$args                    #请求中的参数值
$uri                     #请求中的当前URI
$host                    #优先级:HTTP请求行的主机名>"HOST"请求头字段>符合请求的服务器名.请求中的主机头字段,如果请求中的主机头不可用,则为服务器处理请求的服务器名称
$hostname                #主机名
$request_method          #HTTP请求方法,通常为"GET"或"POST"
$server_name             #服务器名
$1                       #location 正则匹配的第一个参数,以此类推可以有 $2...
复制代码

history 多项目配置

通常我们会有很多项目都会使用到 history 路由,如果保持同一个域名但是要根据目录来区分不同的项目的话,之前的配置方式是不能自动实现的,需要手动的指定文件目录,这下显然并不是我们想要的结果,可以借助前面列举的参数变量,修改一下匹配规则,根据访问路径来匹配对应的静态资源路径。

location ~ ^(/[^/]+) {  
    root   html/dist/;
    try_files $uri $uri/ $1/;
    index index.html;
}  
复制代码

image.png

image.png

要完成上述的演示,需要 vue 的 demo 项目修改 path 为对应的目录路径才能完成。

参考文档

Nginx配置详解

招贤纳士

体验技术研发中心主要负责用体验技术为行云集团所有端侧产品的提供技术支撑,为用户提供极致体验,让数字化触手可及。技术架构上包含搭建、工程化、微前端、UI 规范、研发效能、CI/CD 、AI 智能等技术体系。体验技术研发中心由前端团队、客户端团队、行云生态业务团队组成,团队规模 60+,成员来自于阿里、腾讯、百度、涂鸦等互联网公司,包含众多技术专家,实力强劲。

以上所有的产品都由体验技术团队同学全栈参与完成,无论是前端&客户端,还是运维、数据库,亦或者是 AI 技术。

如果你想对技术有进一步的追求、对工程化有诸多想法却没有机会与场景、想体验从 0-1 然后从 1-10 完成一件有价值的产品,那么在这里有很多好玩、有趣、有意义的技术产品等着你来

猜你喜欢

转载自juejin.im/post/7083177634338701349