遇到前端部署问题怎么办?nginx、端口、https域名怎么配置,跨域问题咋整,react/vue项目怎么部署,什么是反向代理,请您耐心往下看。本文通俗易懂,可操作,旨在抛砖引玉。要是帮到了您,还请顺便点个赞。
前言
前端部署,是让前端代码在服务器环境正常运行。而前端日常工作,主要还是业务代码开发,资源引用,前端路由配
置等。至于部署,更多的是运维人员操作接触不多。但现实项目中,往往一部署到这些环境就出现各种各样的问题,如果我们有部署相关的理论、实践经验,面对问题就能更容易定位到问题,提高上线效率。
背景
当你兴致勃勃买了台服务器,然后规划着美好的未来,规划搭建平台。问题来了,前端项目如何部署(demo来自于Internet项目版权归各自所有)...
预期的几个目标:
1.web站点(SEO) 基于nextjs前端web服务,port 18001(可修改)。通过nextjs官方example创建 github.com/zeit/next.j…
2.api服务 基于koa的前端nodejs服务,port 18000(可修改)。通过koa脚手架 github.com/17koa/koa2-… 创建
3.静态web项目1-基于vue的前端单页面静态资源项目 /vue-app。通过vue-cli创建 cli.vuejs.org/zh/
4.静态web项目2-基于react/typescript等前端静态资源项目 /react-app。通过create-react-app-antd创建 github.com/ant-design/…
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官方网站:nginx.org/
nginx主要通过修改conf/nginx.conf配置文件,重启nginx程序生效实现服务器功能。
// 重启使配置文件生效
// windows
.\nginx.exe -s reload
// linux/mac
nginx -s reload
// ps windows下强制结束nginx.exe进程命令
taskkill /f /t /im nginx.exe复制代码
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文件夹并在对应文件夹放置对应格式的测试文件内容随意。最终访问路径和效果如下:
/static/js/js.js
/static/img/img.png
/static/css/css.css复制代码
2.2.3 nginx配置静态资源
找到nginx文件夹中的 conf/nginx.conf配置文件对应如下配置,配置完成后需要重启nginx,上面有如何重启,结束进程再次打开进程或者reload。
# nginx.conf文件找到server区域
server {
# nginx监听端口号,不能被其他应用占用
listen 80;
# nginx绑定的域名,本文用localhost
server_name localhost;
# 公共静态资源
location /static/ {
#root C:/server/;
alias C:/server/static/;
autoindex on;
# 是否启用目录索引
#autoindex on;
}
}复制代码
2.2.4 目录索引
以上配置有个 autoindex on,如果配置了如果访问的是目录,则展示目录索引,如果关闭则展示403 Forbidden。一般为了服务器安全不被探测,都是关闭索引目录。
开启索引效果
关闭索引效果
2.2.5 附:nginx静态站点
配置三个静态web站点备用。配置方法很简单,C:/server创建两个文件夹,立马分别有个index.html文件。nginx.conf增加以下配置后重启nginx生效。
server {
listen 10001;
server_name localhost;
root C:/server/siteA;
index index.html index.htm;
}
server {
listen 10002;
server_name localhost;
root C:/server/siteB;
index index.html index.htm;
}
server {
listen 10003;
server_name localhost;
root C:/server/siteB;
index index.html index.htm;
location / {
add_header X-Frame-Options SAMEORIGIN;
}
}复制代码
至此,任务5静态资源任务达成。恭喜您已经具备使用nginx搭建静态web站点和静态文件服务的能力了,具体相关其他配置可以自行深入研究。
3 部署前端服务-pm2
前端服务-即前端使用如基于nodejs平台下能够有独立运行访问的web服务等。如nextjs、express、koa、eggjs等前端应用服务器。
pm2是什么
众所周知,我们一般启动前端服务,开启一个bash,然后执行如npm start服务器愉快的跑起来,但如果有多个服务,就必须要打开多个,一般在服务器环境你只有一个bash端口必须得后台运行,如何后台运行nodejs服务,以及方便的管理各个nodejs服务的暂停、重启、销毁,我们得需要一个能够管理他们的软件。pm2应运而生。
pm2工具:把nodejs服务变为后台服务,统一管理(常用于服务器环境、控制台命令环境)
详见pm2官方文档
www.npmjs.com/package/pm2, pm2.keymetrics.io/docs/usage/…
安装
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
部署前端服务-nextjs
2.基于koa2的nodejs服务:127.0.0.1:18000
部署前端服务-koa
3.pm2 list列出所有pm2托管的node服务
.部署前端服务-pm2
配置
最终我们是直接通过目录下的start.bat/start.sh执行pm2命令。最终为了间接执行到npm start的命令,给予pm2进行托管
windows下的pm2存在一些问题,需要通过间接方式执行npm命令
// 1.koa/nextjs项目根目录增加start.bat / start.sh,内容为pm2的命令
pm2 start ecosystem.config.js
// 2.创建ecosystem.config.js配置文件,以下已沟通。详细其他参数可参照pm2官网查看具体配置. https://pm2.keymetrics.io/docs/usage/application-declaration/
module.exports = {
apps: [{
name: 'MyKoa',
script: 'start.js',
args: 'one two',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};
// 3.创建start.js
const cmd = require('node-cmd');
cmd.run('npm run start');
// 4.package.json配置,需要项目安装node-cmd的包,具体npm run start就是项目中如何启动nodejs服务根据具体项目来
{
"start": "node bin/development.js",
}
至此,您已经本地运行了两个前端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.首页为nextjs的web server,便于SEO优化。访问所有优先转发给nextjs服务
location / {
proxy_pass http://127.0.0.1:12111/;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via "nginx";
}
# 2.转发/api请求给前端koa服务器
location /api {
proxy_pass http://127.0.0.1:18000/api;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via "nginx";
}复制代码
4.3 iframe跨域解决
iframe跨域一般还是通过服务器设置response header头。分为旧版本浏览器和新版本浏览器。旧版本:X-Frame-Options,新版本:Content-Security-Policy。可参考:developer.mozilla.org/en-US/docs/…
nginx下具体设置如下,可以指定对应可跨域iframe访问的域名
# 被内嵌iframe web设置server {
listen 10004;
server_name localhost;
root C:/server/siteB;
index index.html index.htm;
location / { # 旧版本
add_header X-Frame-Options "ALLOW-FROM http://localhost"; # 新版本使用csp
# add_header Content-Security-Policy "frame-ancestors 'self’ http://localhost";
}
}复制代码
4.4 http报头跨域
一般为开发阶段的mock server,或者设置允许跨域的域名.这样,我们可以直接访问mock数据
☆5.部署react/vue单页面静态项目
本章节作为react/vue开发者必备部署知识,因为你的代码始终是要发布的,出了啥问题你就能很快定位(甩锅)问题所在。
5.1 单页面应用核心问题
部署单页面应用项目我们核心思考的问题:服务器端路由与静态单页面应用路由的转换过程
5.2 nginx配置单页面应用
我们进行分析:当访问url时,先访问nginx服务器,nginx路由判定后给前端路由托管。我们得出以下的配置:访问静态资源子路径下的所有路由均转发给静态资源的index.html文件。实现后端路由转换为前端路由。
# 1.create-react-app静态项目
location /react-app {
# 路径
alias C:/server/create-react-app-antd/build;
# 默认首页
index index.html;
# 访问不到资源后的处理
try_files $uri $uri/ /react-app/index.html;
}
# 2.vue静态项目
location /vue-app {
alias C:/server/vueapp/build;
index index.html;
try_files $uri $uri/ /vue-app/index.html;
}复制代码
问题一:原始项目直接配置完成无法访问,资源报错
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 uriuri/ /react-app/index.html;这句异常处理如果不加就会导致刷新访问不到文件的问题。回味一下配置:访问不到的时候转发给下面的index.html页面,index.html无缝对接前端的路由。问题解决。
location /react-app {
alias C:/server/create-react-app-antd/build;
index index.html;
# 下面这句话就起作用了很关键
try_files $uri $uri/ /react-app/index.html;
}复制代码
至此,您已具备单页面应用项目的能力,判定资源访问路径,而且还能够排查出部署刷新页面报404这样的经典问题。任务3,4react/vue的静态子项目成功部署。
6 https访问
至此,上述的几个应用系统已经完全贯通运作。但http不是不安全吗,我需要用https让网站能够安全访问。
6.1 https基于ssl证书访问关键要素
申请证书、秘钥(openssl工具)
配置nginx
其实本地环境是可以通过命令行工具生成秘钥和证书,用来测试https
nginx 本地https秘钥可参考文档:www.cnblogs.com/isylar/p/10…
先看效果:https访问后端口号变为了443
nginx配置如下:最关键的就是pem证书和key的生成。按照上面文档本地就可以生成,网上也有很多关于https证书秘钥生成教程。
server {
listen 443 ssl;
server_name localhost;
index index.html index.htm index.php;
root C:/lc/server; # pem证书路径
ssl_certificate C:/lc/work/proj/https/server/server.pem; # pem证书路径
ssl_certificate_key C:/lc/work/proj/https/server/server.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
…
}
}复制代码
问题:本地刚配置https访问后浏览器提示不安全的连接
解答:由于浏览器https是需要经过合法CA办法的证书,我们自己配置的并非经过证书颁发机构。点击继续前往还是能够本地访问到。
如何强制http请求转为https请求
nginx配置为:80端口访问后rewrite所有请求为https
server {
listen 80;
server_name localhost; # 强制使用https
rewrite ^(.*)$ https://$host$1 permanent;
}复制代码
7.持续集成CI-自动化部署
7.1核心思想
具有执行服务器端脚本能力
通过web等UI界面方便操作
支持通过如git web hook等触发式构建
7.2常用软件
Jenkins jenkins.io/zh/
7.3本地写个自动更新代码自动打包的脚本
我们在刚刚 C:/server/create-react-app-antd下新建build.sh和build.bat,用来执行后自动拉取代码以及自动执行编译打包
build.bat
echo start build...
echo running step 1.git pull
git pull
echo running step 2.npm run build
npm run build复制代码
build.sh
#!/usr/bin/env bash
echo start build...
echo running step 1.git pull
git pull
echo running step 2.npm run build
npm run build复制代码
收尾
能看到这里,真心感谢您的耐心,是不是有种醍醐灌顶,原来前端部署一篇就够了。有了这些,我们在以后的前端上线部署不再是盲区,又能够快速定位问题。结尾还是那句话:要是帮到了您,还请顺便点个赞,谢谢(90度鞠躬)。