专栏首页Node.js开发nginx部署React项目

nginx部署React项目

nignx是一款非常优秀的服务器软件,前端工程师在开发完项目后,通常要将项目部署到服务器,我在部署项目时用的就是nginx。

今天跟大家分享一下用nginx部署前端项目的一些经验。

React项目开发完成后,需要运行 build指令进行打包,打包完成后得到打包的文件,然后将这些文件部署到服务器。

关于打包这里通常有两种操作,一种是在本地打包,然后将打包文件利用scp指令或者其它一些软件将文件上传到服务器。

另一种方式是直接在服务器clone一下项目,每次更新项目后服务器进行同步并打包。

文中示例以本地服务器为例,不存在文件传输,这里不做赘述。

用nginx部署前端应用,最主要的工作是写配置文件,我在网上找到一份比较合适的配置文件,这里只展示了server模块的配置,代码如下:

server {
        listen   8888;#默认端口是80,如果端口没被占用可以不用修改
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        #vue或者React项目的打包后的dist
        root   E:/vue/my_project/dist;
        location / {
            #需要指向下面的@router
            try_files $uri $uri/ @router;
            index  index.html index.htm;
        }
        #对应上面的@router,
        #主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
        #因此需要rewrite到index.html中,然后交给前端路由再处理请求资源
        location @router {
            rewrite ^.*$ /index.html last;
        }
        #.......其他部分省略
  }

为什么只展示server模块的代码呢?因为我们部署项目的所有配置全部在server模块里面。

nginx的配置分为三个层级第一层为http模块,在这层模块配置http的一些功能,如http响应头。

在http模块内部是server模块,在这层模块主要配置服务器的一些功能,如路由匹配,网站根目录,监听端口。

在server模块内部是location模块,location模块主要负责理由匹配后的处理,如代理服务器,重定向等等。

在第七行的root配置里,root指定了服务器的根目录,前端项目的文件就放在这个目录中。

第八行的location通过指令模式与客户端请求的URI相匹配,这里匹配了任何以 “/” 开始的查询。关于location指令的匹配规则,我会另写文章说明,这里略过,在这里大家只需知道,以/开头的路径都会匹配到这个location。

接下来,location指令里面使用了一个try_files指令,try_files指令的功能是按顺序检测文件的存在性,并且返回第一个找到的文件的内容,如果第一个找不到就会自动找第二个,依次查找。

举个简单的例子:

    location /abc {
       try_files /4.html /5.html @qwe;      
       --检测文件4.html和5.html,如果存在正常显示,不存在就去查找@qwe值
  }

上面的location模块中使用了try_files指令,该指令会依次按顺序检测根目录中的4.html文件和5.html文件,如果存在就正常显示,不存在就去执行@xxx指令。

比如请求http://localhost/abc,服务器匹配到“/”后进入location,执行try_files指令,去root指定的根目录下查找4.html,如果查到则返回4.html内容,如果没有查找到,则继续去root根目录下查找5.html,如果有的话,返回5.html的内容,如果没有就执行@xxx指令。

那@xxx是什么意思呢?@关键字指定一个location段。通常和location一起使用。

用“location @xxx”定义一个location段,这个location段不能被外部请求所访问,只能用于nginx内部配置指令使用,比如 try_files、error_page。需要特别注意的是用@定义的location段只能在nginx内部所使用。

回过头来再看配置文件的第十行:

try_files $uri $uri/ @router;

路由匹配到“/"后会执行try_files指令,$uri是nginx的一个内部变量,指的是当前请求的路径。当用户请求 http://localhost/example 时,这里的 $uri 就是 /example。

try_files 会到root根目录里尝试找这个文件。如果存在就直接把这个文件的内容发送给用户。

如果目录中没有叫 example 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 example/ 的目录,又找不到就会 fall back 到 try_files 的最后一个选项,@router。@router指令发起一个内部 “子请求”,这个请求会匹配到location @router中,那么在location @router中又做了哪些操作呢?

location @router {
    rewrite ^.*$ /index.html last;
}

这里执行了rewrite操作,那么rewrite指令有哪些功能呢?其主要功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

这里需要注意rewrite对url进行重写指的是重写真实请求路径,如果是同域内,浏览器不会发生跳转,如果是非同域浏览器会发生跳转。

还有就是,rewrite只能放在server{},location{},if{}中,本文只讨论其放在location中的情形。

rewrite指令只能对域名后边的除去传递的参数外的字符串起作用,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。

rewrite的使用语法为rewrite regex replacement [flag]。

regex是正则表达式,用于匹配URL,replacement是替换内容,flag是命令执行模式。

这个语法啥意思呢,在nginx程序触发rewrite指令,程序会去匹配正则regex,匹配成功后,将请求的url中的regex部分换成replacement,然后发送请求,将请求结果返回给客户端,然后根据flag执行下一步动作。

首先我们先验证一下,rewrite在同域内的使用情况。举个简单的例子,代码如下:

        location / {
            rewrite ^/test1 /test2 ;
        }

        location = /test2 {
            return 200 "/test2";
        }

我们访问:http://localhost/test1,结果如图:

虽然我们访问的是/test1但是结果返回的确实/test2,这说明nginx内部对我们的请求进行了重定向,但是浏览器不会感知到,其url不会发生变化。

再验证一下rewrite在处理非同域的情况,看代码:

        location / {
            rewrite ^/test1 "http://www.baidu.com" ;
        }

这次我们在请求http://localhost/test1,页面会直接跳转到百度首页,network我们只观察前三行:

第一行如图:

第二行如图:

第三行如图:

浏览器内部进行了重定向,地址栏也发生了变化。

所以说rewrite进行同域重定向,浏览器地址不会发生变化,而进行非同域重定向,浏览器会发生跳转。

最后再看一下flag的作用,flag参数常用的值有两个,break和last,那这两个值有什么区别呢?看案例:

location /test/break {  
  # break测试 location1
  rewrite ^.*/test(.*)$ "/here" break;
}

location /test/last {   
  # last测试 location2
  rewrite ^.*/test(.*)$ "/here" last;
}

location /here {    
  # 正常地址 location3
  default_type text/html;
  return 200 "<h1>ok</h1>";
}

代码中我们定义了三个location块,下面是测试记录:

1.首先测试下break, 请求/test/break,结果如下图:

请求/test/break 匹配到location1,然后地址重写为/here,返回404,表示没有再次匹配location。

2.测试last, 请求/test/last,结果如下图:

请求/test/break 匹配到location2,然后地址重写为/here,正常返回ok页面,表示重写后又再次匹配所有location。

由此我们得出break与last的区别:break表示重写后停止不再匹配,last表示重写后跳到server块再次用重写后的地址匹配。

再有就是,如果一个location块内有多个rewrite操作,last和break都会中断后续的rewrite操作。并且如果存在一个或多个rewrite指令,最后一句默认带有last标志,这个就不带大家验证了,大家可以自己去测试下。

那这俩玩意一般用在哪里呢?

break一般用于接口重定向,例如将http://127.0.0.1/down/123.xls冲重定向到http://192.168.0.1:8080/file/123.xls(解决跨域下载)

location /down {
  rewrite ^/down(.*)$ "http://192.168.0.1:8080/file$1" break;
}

last用于请求路径发生改变的常规需求,例如将http://127.0.0.1/request/getlist 的请求代理到 http://127.0.0.1/api/getlist 上:

location /request {
  rewrite ^/request(.*)$ "/api" last;
}

location /api {
  default_type Application/json;
  return 200 '{"code":0,data:[1,2,3]}';
}

使用rewrite进行跨域操作(这里不推荐使用rewrite处理跨域,跨域一般推荐使用proxy_pass处理),浏览器地址会发生变化,而如果是同域内的重写,浏览器的地址是不会发生变化的,这里需要特别注意。

从上面我们可以看出来,在location块内使用的rewrite和proxy_pass功能有点类似,都能实现请求代理,主要区别在于rewrite是在同一域名内更改获取资源的路径,而proxy_pass与location结合使用,是对一类路径做控制访问或反向代理。

rewrite主要用在同域内,proxy_pass主要用在非同域内,两种使用方式都不会更改浏览器中的路径,只有使用rewrite处理非同域的情况,浏览器的路径才会发生跳转。

终于写完了,给大家总结一下:

1、在项目部署前,前端打包好的项目必须上传到服务器,文中介绍了两种方式,一种直接上传打包好的数据,一种在服务器将整个项目克隆,在服务器打包。

2、设置nginx配置文件,nginx配置文件有三层基础模块,http模块,server模块,location模块,三层模块是如何嵌套的,以及每层模块的作用。

3、在server模块中配置root根目录,此目录放置前端打包好的文件。

4、在location模块中配置try_files指令,以及try_files指令的运行规则。

5、location @xxx指令的作用,location@xxx其实是定义了一个location段,这个location段比较特殊,只能在nginx内部使用。

6、rewrite指令的用法,以及break和last参数的作用和区别,rewrite应用在同域中时,浏览器URL不会变化,如果用在非同域中时,浏览器会发生跳转。

7、rewrite与proxy-pass的区别,前者主要应用在同域内进行重定向,后者主要应用在非同域内做代理。

以上便是用nginx部署React项目涉及到的知识点,如果你有什么疑问或者建议欢迎留言。

引用资料 https://segmentfault.com/a/1190000020753046?utm_source=tag-newest

本文分享自微信公众号 - nodejs全栈开发(geekclass),作者:挥刀北上

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • nginx部署react项目

    build注意要配置webpack的webpack.config.prod.js文件,生产环境的配置(我是使用的less,所以加了个less的loader)

    治电小白菜
  • React 项目部署在 Nginx

    期望网址是:http://192.168.135.89/bbs_system_h5_dev

    zhangyunfeiVir
  • nginx部署h5项目

    部署h5项目还是很简单的,不过对小白来讲一开始可能也是一脸懵逼,这个简单教程针对的是从未部署过前后端分离前端项目的小白

    老梁
  • uwsgi+nginx项目部署

    网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。...

    py3study
  • ubuntu18.04部署python3、nginx项目

    昨天服务器开了一个新管理员账号,用的弱口令,导致被黑了,ssh也不能登录,没办法,只能重装系统,还好没重要资料,服务器上只跑了一个公交的api和博客,早上重装了...

    青年码农
  • flask+uwsgi+nginx项目部署

    ubuntu下找到/etc/nginx/sites-available下的default文件

    会呼吸的Coder
  • uwsgi+nginx部署django项目

    正常我们写完一个 django 项目是需要放到服务器上运行,在本地开发你可以使用django自带的测试服务器 runserver 启动就行,这个 runserv...

    用户4945346
  • Nginx部署简单Vue项目

    HLee
  • linux 部署golang 项目(直接部署和基于nginx部署)

    linux 上安装golang 项目的方式按照官网的 https://golang.org/doc/install#install(要梯子)的方式,安装go运行...

    地球流浪猫
  • docker-compose部署django+nginx+mysql项目

    一、项目结构 [root@mail docker-feiyu]# tree `-- dokcer-feiyu |-- docker-compos...

    菲宇
  • 69. Django项目部署 nginx + uwsgi + dwebsocket

    但是,直接使用python manage.py runserver启动是没问题的。

    Devops海洋的渔夫
  • 29. Flask 部署项目 nginx + gunicorn + flask

    当我们执行下面的hello.py时,使用的flask自带的服务器,完成了web服务的启动。在生产环境中,flask自带的服务器,无法满足性能要求。

    Devops海洋的渔夫
  • 使用Nginx+Gunicorn部署Flask项目

    Flask Web 项目开发完成后,开发人员只是在开发环境运行,只有本地可以访问到项目。如果要让用户访问到项目,需要将项目部署到生产环境上,在服务器运行项目。

    Python碎片公众号
  • Flask 项目部署(Docker + Flask + uwsgi + Nginx)

    近期参加比赛,原本 windows server 部署的 Flask 后端项目所用的服务器快要过期了,开始改用 Linux 服务器部署。

    Gorit
  • ubuntu上web项目的部署,:uwsgi, uwsgi + nginx, uwsgi+nginx分布式部署

    Ubuntu中pip和pip3区别: pip默认给python2用,pip3默认给Python3使用

    武军超
  • 腾讯云部署nginx静态项目

    部署静态页面归纳为2点:①:项目相关的文件上传到云服务上;②:可以通过IP或者域名打开页面

    tengxunyun8点com活动整理
  • 使用CentOS,Nginx部署前端项目

    此时云服务器中运行了 webpack-dev-server 的服务器,默认访问 http://公网ip:8080 可查看浏览 器中的效果。注意, 8080 端口...

    用户6833524
  • 使用 gunicorn + nginx + supervisor 部署 flask 项目

    gunicorn “绿色独角兽”是一个被广泛使用的高性能的 Python WSGI UNIX HTTP 服务器,移植自Ruby 的独角兽(Unicorn )项目...

    andrew_a
  • 如何在云开发部署React项目

    React是目前比较火的前端框架之一,除了可以在自有服务器、Github Pages 部署以外,现在你有了一个新的选择,那就是使用云开发静态网站功能来进行部署。

    腾讯云开发TCB

扫码关注云+社区

领取腾讯云代金券