【你应该了解的】详尽&全面的前端部署(从零起步,前端上线不用愁)
遇到前端部署问题怎么办?nginx、端口、https域名怎么配置,跨域问题咋整,react/vue项目怎么部署,什么是反向代理,请您耐心往下看。本文通俗易懂,可操作,旨在抛砖引玉。要是帮到了您,还请顺便点个赞。
前言
前端部署,是让前端代码在服务器环境正常运行。而前端日常工作,主要还是业务代码开发,资源引用,前端路由配置等。至于部署,更多的是运维人员操作接触不多。但现实项目中,往往一部署到这些环境就出现各种各样的问题,如果我们有部署相关的理论、实践经验,面对问题就能更容易定位到问题,提高上线效率。
背景
当你兴致勃勃买了台服务器,然后规划着美好的未来,规划搭建平台。问题来了,前端项目如何部署(demo来自于Internet项目版权归各自所有)…
预期的几个目标:
1.web站点(SEO)
基于nextjs前端web服务,port 18001(可修改)。通过nextjs官方example创建
https://github.com/zeit/next.js/2.api服务
基于koa的前端nodejs服务,port 18000(可修改)。通过koa脚手架 https://github.com/17koa/koa2-startkit 创建3.静态web项目1-基于vue的前端单页面静态资源项目 /vue-app。通过vue-cli创建 https://cli.vuejs.org/zh/
4.静态web项目2-基于react/typescript等前端静态资源项目 /react-app。通过create-react-app-antd创建 https://github.com/ant-design/create-react-app-antd
5.公共静态资源图片、css、js等。 /static
目录
按照从零起步的原则,按照以下目录来循序渐进
- 1.服务器分类
- 2.轻量强大的nginx
- 3.前端服务管理工具-pm2
- 4.解决跨域“问题”
- 5.☆部署react/vue单页面静态项目
- 6.实现https
- 7.持续集成CI-自动化部署
1.服务器分类
1.1 应用服务器
专注于动态资源、解析高级开发语言编写的代码。前端服务一般基于解析JavaScript语言的nodejs搭建
- JAVA:Tomcat、resin、jboss、weblogic 等
- PHP:Apache等
- .NET:IIS等
- Nodejs:express、 koa、eggjs等
1.2 网关服务器
专注于静态资源、代理转发、负载均衡等
- Nginx、Tengine等
2.轻量强大的Nginx
Nginx特性很多,前端常用一些特性,其他特性各大互联网公司经过大量实践已证明。关于nginx配置,主要就是配置nginx.conf以及修改后reload使配置生效。具体nginx下载与教程可以参照官网等。Nginx主要是修改配置文件以及生效。
2.1 简介
2.1.1 前端常用特性
- 域名绑定
- 静态资源
- 反向代理
- 支持https
- 跨平台
2.1.2 其他特性
- 负载均衡、高并发
- …
2.1.5 nginx下载和目录说明
nginx官方网站:http://nginx.org/
nginx主要通过修改conf/nginx.conf配置文件,重启nginx程序生效实现服务器功能。
1 | // 重启使配置文件生效 |
2.2 实战配置
2.2.1 环境准备
- nginx.org下载最新的nginx压缩包直接解压,windows/linux/mac下载对应的版本
- 创建文件夹,windows下为如C盘根目录创建 c:/server;linux/mac可以在某个目录创建如根目录创建 /server
2.2.2 静态资源
首先,我们来实现js、png图片、css资源的静态资源配置。server文件夹下创建static文件夹,里面分别创建js、img、css文件夹并在对应文件夹放置对应格式的测试文件内容随意。最终访问路径和效果如下:
1 | /static/js/js.js |
2.2.3 nginx配置静态资源
找到nginx文件夹中的 conf/nginx.conf配置文件对应如下配置,配置完成后需要重启nginx,上面有如何重启,结束进程再次打开进程或者reload。
1 | # nginx.conf文件找到server区域 |
2.2.4 目录索引
以上配置有个 autoindex on,如果配置了如果访问的是目录,则展示目录索引,如果关闭则展示403 Forbidden。一般为了服务器安全不被探测,都是关闭索引目录。
开启索引效果
关闭索引效果
2.2.5 附:nginx静态站点
配置三个静态web站点备用。配置方法很简单,C:/server创建两个文件夹,立马分别有个index.html文件。nginx.conf增加以下配置后重启nginx生效。
1 | server { |
至此,任务5静态资源任务达成。恭喜您已经具备使用nginx搭建静态web站点和静态文件服务的能力了,具体相关其他配置可以自行深入研究。
3 部署前端服务-pm2
前端服务-即前端使用如基于nodejs平台下能够有独立运行访问的web服务等。如nextjs、express、koa、eggjs等前端应用服务器。
pm2是什么
众所周知,我们一般启动前端服务,开启一个bash,然后执行如npm start服务器愉快的跑起来,但如果有多个服务,就必须要打开多个,一般在服务器环境你只有一个bash端口必须得后台运行,如何后台运行nodejs服务,以及方便的管理各个nodejs服务的暂停、重启、销毁,我们得需要一个能够管理他们的软件。pm2应运而生。
pm2工具:把nodejs服务变为后台服务,统一管理(常用于服务器环境、控制台命令环境)
详见pm2官方文档 https://www.npmjs.com/package/pm2, https://pm2.keymetrics.io/docs/usage/application-declaration/
安装
1 | npm install pm2 –g |
常用命令
- pm2 start pm2.json #根据pm2.json配置方式启动进程
- pm2 list, pm2 status #列出当前所有pm2管理列表
- pm2 stop 0 #停用指定id的服务
- pm2 delete 0 #删除指定id的服务
- pm2 restart 0 #重启指定id的服务
实战
我们根据上述最开始官方项目启动nextjs、koa2的nodejs服务,(以前我们是执行npm run start,本地模拟可以直接先启动),现在如果需要pm2改造
先看运行效果:
1.基于nextjs的nodejs服务:127.0.0.1:12111
2.基于koa2的nodejs服务:127.0.0.1:18000
3.pm2 list列出所有pm2托管的node服务
配置
最终我们是直接通过目录下的start.bat/start.sh执行pm2命令。最终为了间接执行到npm start的命令,给予pm2进行托管
windows下的pm2存在一些问题,需要通过间接方式执行npm命令
1 | // 1.koa/nextjs项目根目录增加start.bat / start.sh,内容为pm2的命令 |
至此,您已经本地运行了两个前端node服务。任务1、2完成50%.
4.解决跨域”问题”
4.1跨域——“正常”的安全策略
我们两个node都启了,你一定会立马就想让nextjs的fetch请求来请求koa的api服务,结果跨域了。。
场景一、XMLHttpRequest、fetch等同源限制
浏览器出于安全当访问不同端口、域名默认情况下是不允许的,也是出于安全。如果谁都能互相随便调用岂不是没有了安全可言。
场景二、iframe跨域引用问题
一般出于安全,页面的HTTP请求的Response头部设置了X-Frame-Options:sameorigin,防止页面被其他站点内嵌。
4.2nginx解决方案-反向代理
4.2.1 什么是反向代理
一句话解释:客户端请求服务器,服务器接收转发给其他服务器获得内容,再传给客户端。
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
正向代理:意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
4.2.2 先看nginx的预期效果
当localhost访问 /api/test/list成功转发到koa服务(127.0.0.1:12111)返回数据
4.2.3 nginx配置反向代理
1 | # 1.首页为nextjs的web server,便于SEO优化。访问所有优先转发给nextjs服务 |
4.3 iframe跨域解决
iframe跨域一般还是通过服务器设置response header头。分为旧版本浏览器和新版本浏览器。旧版本:X-Frame-Options,新版本:Content-Security-Policy。可参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
nginx下具体设置如下,可以指定对应可跨域iframe访问的域名
1 | # 被内嵌iframe web设置 |
4.4 http报头跨域
一般为开发阶段的mock server,或者设置允许跨域的域名.这样,我们可以直接访问mock数据
☆5.部署react/vue单页面静态项目
本章节作为react/vue开发者必备部署知识,因为你的代码始终是要发布的,出了啥问题你就能很快定位(甩锅)问题所在。
5.1 单页面应用核心问题
部署单页面应用项目我们核心思考的问题:服务器端路由与静态单页面应用路由的转换过程
5.2 nginx配置单页面应用
我们进行分析:当访问url时,先访问nginx服务器,nginx路由判定后给前端路由托管。我们得出以下的配置:访问静态资源子路径下的所有路由均转发给静态资源的index.html文件。实现后端路由转换为前端路由。
1 | # 1.create-react-app静态项目 |
问题一:原始项目直接配置完成无法访问,资源报错
vue-cli项目配置
首先,如果直接从vue官网的命令安装依赖,执行npm run build,配置完是会报错的。
问题原因:css/js资源引用路径没有引用到,解决方法1改成相对路径访问
修改后重新编译,成功访问
react项目配置
默认create-react-app-antd项目npm run build后配置完会出现资源无法访问的问题。原因,项目都是绝对路径访问资源。
react项目里面由于脚手架配置读取package.json的homepage项为根路径
重新打包编译后正常访问。这里稍作修改,项目内容增加了路由跳转,这样好测试静态资源路由功能。
问题二:我上线出现了点击上面react项目首页 http://localhost/react-app/点击链接跳转 http://localhost/react-app/test能打开,但我刷新页面报nginx404了。(很多小伙伴都出现了发布后出现这个情况明明默认都能点,刷新页面后就打不开了报404)
子路由刷新页面后404
why刷新报错?
冷静思考,根源还是来自于前后端路由的转换问题,还记得上面配置行(3行)中重要的一句话:try_files 尝试文件,也就是说服务器找不到文件你得告诉怎么处理跳转到哪儿。也就定位到问题:try_files $uri $uri/ /react-app/index.html;这句异常处理如果不加就会导致刷新访问不到文件的问题。
回味一下配置:访问不到的时候转发给下面的index.html页面,index.html无缝对接前端的路由。问题解决。
1 | location /react-app { |
至此,您已具备单页面应用项目的能力,判定资源访问路径,而且还能够排查出部署刷新页面报404这样的经典问题。任务3,4react/vue的静态子项目成功部署。
6 https访问
至此,上述的几个应用系统已经完全贯通运作。但http不是不安全吗,我需要用https让网站能够安全访问。
6.1 https基于ssl证书访问关键要素
- 申请证书、秘钥(openssl工具)
- 配置nginx
其实本地环境是可以通过命令行工具生成秘钥和证书,用来测试https
nginx 本地https秘钥可参考文档:https://www.cnblogs.com/isylar/p/10002117.html
先看效果:https访问后端口号变为了443
nginx配置如下:最关键的就是pem证书和key的生成。按照上面文档本地就可以生成,网上也有很多关于https证书秘钥生成教程。
1 | server { |
问题:本地刚配置https访问后浏览器提示不安全的连接
解答:由于浏览器https是需要经过合法CA办法的证书,我们自己配置的并非经过证书颁发机构。点击继续前往还是能够本地访问到。
如何强制http请求转为https请求
nginx配置为:80端口访问后rewrite所有请求为https
1 | server { |
7.持续集成CI-自动化部署
7.1核心思想
- 具有执行服务器端脚本能力
- 通过web等UI界面方便操作
- 支持通过如git web hook等触发式构建
7.2常用软件
- Jenkins https://jenkins.io/zh/
7.3本地写个自动更新代码自动打包的脚本
我们在刚刚 C:/server/create-react-app-antd下新建build.sh和build.bat,用来执行后自动拉取代码以及自动执行编译打包
build.bat
1 | echo start build... |
build.sh
1 | #!/usr/bin/env bash |
收尾
能看到这里,真心感谢您的耐心,是不是有种醍醐灌顶,原来前端部署一篇就够了。有了这些,我们在以后的前端上线部署不再是盲区,又能够快速定位问题。
结尾还是那句话:要是帮到了您,还请顺便点个赞,谢谢(90度鞠躬)。