我成功部署 qiankun + vite 项目,感觉极棒 👍🏻
可能有人看见了这个标题,会嗤之以鼻,部署项目,有什么得意的。。。我不否认,这确实不是一件得意的事情(但是需要学会理解菜鸡的世界)。但是…第一次成功部署自己的项目,就是 biu 倍爽儿。
背景
在前面的很长一段时间内,利用下班的业余时间,开发了个人项目,前端采用了qiankun + vite + React18 + Vue3
,后端采用了 koa + mysql
。经过时间的累积开发,项目初步雏形。接下来,就是部署到自己购买的服务器上,也是自己第一次真正的想去了解 nginx,然后对自己的项目进行部署。
搭建个人项目的目的:
因为我知道,
实践才是实现真理的唯一标准
。在工作的几年中,项目开发都是在别人的带领下,关于什么技术选型,什么项目架构搭建等一系列步骤,基本上跟自己关系不大,然后自己就只有默默的在开发过程中擦边学习;那么其中的难点,痛点,不经历过,是不知道什么滋味的。就会造成:
会造成一种窘局,我了解过,但是使用可能不熟悉,那这样到底算什么呢?我会使用,但是我还要花时间去学习。 也会造成在寻找下份工作时,你在项目开发中的难点有什么???额豁,默默说一句 CRUD 算吗? 所以只有真正的实践过后,你才能更好的应对上面的局面,展现出更好的自己。
nginx 前置知识
在部署之前,你肯定需要了解一些关于 nginx 的知识。
nginx 介绍就不用多说了吧,网上一大堆,而且我也解释不清楚。只需要知道,nginx 是一台高性能,轻量级的服务器即可。
列述一下我在此过程中学到的 nginx 的知识。
本机安装,查看信息
mac 电脑查看本地安装 nginx 的信息
nginx 的配置结构
├─http
│ ├─server
│ │ ├─location
nginx 配置结构分为三层 http > server > location。
http 包含一到多个 server, server 包含一到多个 location。
配置项的优先级分别是 location、server、 http。
请求 URI
输入的网址叫做请求 URI
,nginx 用请求 URI
与 location 中配置的URI
做匹配。
location 后面带不带 /
请求 URI 分为两种情况(重定向):
-
如果 URI 结构是 https://www.baidu.com/ 的形式,尾部有没有 / 都不会造成重定向。因为浏览器在发起请求的时候,默认加上了 / 。 -
如果 URI 的结构是 https://www.baidu.com/dir/ 。尾部如果缺少 / 将导致重定向。因为根据约定,URL 尾部的 /
表示目录,没有/
表示文件。
针对第二种情况,又可以分为两种情况:
第一种情况,有 /
, 比如访问/dir/
时,服务器会自动去该目录下找对应的默认文件。第二种情况,无 /
, 比如访问/dir
时,服务器会先去找dir
文件,当找不到的话会将dir
当成目录,重定向到/dir/
,去该目录下找默认文件。(先找文件,找不到文件,再当成目录,重新查找)
注意要点:但是如果想这两种请求对应不同的处理,就要明确增加不带 / 结尾的 location 配置
location /xxx {
proxy_pass http://www.xxx123.com
}
location /xxx/ {
proxy_pass http://www.xxx456.com
}
location 中的 root 和 alias 的区别
root 和 alias 的主要区别是:
使用 root,实际的路径就是:root 值 + location 值
。
使用 alias,实际的路径就是:alias 值
。
# 测试路径 xxx/static/a.png
location /static/ {
root /var/www/app/; # /var/www/app + /static/ + a.png (三部分)
}
location /static/ {
alias /var/www/app/static/; # /var/www/app/static/ + a.png (两部分)
}
alias 后面必须要用 “/” 结束,是错误的结论,加不加都是一样。
alias 在使用正则匹配时,必须捕捉要匹配的内容,并在指定的内容处使用。
alias 只能位于 location 块中,root 可以不放在 location 中。
location 的匹配优先级
location 匹配机制是存在优先级的,其顺序如下:
模式 | 含义 | 优先级 |
---|---|---|
location = /uri | = 表示精确匹配,只有完全匹配上才能生效 | 1 |
location ^~ /uri | ^~ 开头对 URL 路径进行前缀匹配,并且在正则之前。 | 2 |
location ~ pattern | 开头表示区分大小写的正则匹配 | 3 |
location ~* pattern | 开头表示不区分大小写的正则匹配 | 4 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 | 5 |
location / | 通用匹配,任何未匹配到其它 location 的请求都会匹配到,相当于 switch 中的 default | 6 |
就是简单看成 js 中的 switch 语句,依次判断下来。 location /
就类似 default 逻辑
二级路由时需要使用别名 alias,不用 root
location /subapp {
alias html/dist/;
index index.html;
}
配置 try_files,解决刷新会 404
location /subapp {
try_files $uri $uri/ /index.html;
}
代理 proxy_pass 是否需要添加 /
在 nginx 中配置 proxy_pass 代理转发时,
-
如果在 proxy_pass 后面的 url 加 /
,表示绝对根路径; -
如果没有 /
,表示相对路径,把匹配的路径部分也给代理走。
存在下面四种情况:
测试路径: http://locahost:3000/proxy/test.html
location /proxy/ {
proxy_pass http://locahost:3000/;
}
# 绝对路径:http://locahost:3000/test.html
location /proxy/ {
proxy_pass http://locahost:3000;
}
# 相对路径:http://locahost:3000/proxy/test.html
location /proxy/ {
proxy_pass http://locahost:3000/abc/;
}
# 绝对路径:http://locahost:3000/abc/test.html
# 特殊情况
location /proxy/ {
proxy_pass http://locahost:3000/abc;
}
# 相对路径:http://locahost:3000/abctest.html
好了,这就是在部署过程中,学习到的一些知识。如其中有误的话,请指出,学习学习。
部署
个人项目,采用的是微前端(qiankun),那么就会存在多个应用。当然该项目只有两个应用:
-
主应用(vue3 + vite) -
子应用(react + vite)
这里就不讲解 qiankun 一步一步的怎么使用了,当有需要的时候,就列出关键的部分代码即可。
因为存在多个应用,那么在部署的时候就会存在多个方案。
在开始之前,先看看个人 nginx 的目录结构
├─root
│ ├─copyer # 前端代码
│ │ ├─main # 主应用
│ │ │ └─build
│ │ └─subppp # 子应用集合(如果存在多个,继续往该文件夹添加)
│ │ └─management
│ └─copyer_server # 后端代码
该项目只涉及到两个应用,目录结构就如上:
-
主应用的打包文件 build
-
子应用的打包文件 management
方案一:多个应用单独部署
就是每个应用单独开端口来部署,也就是所谓的多加一层 server
层。
主应用默认部署在 80 端口上;
子应用部署在 7241 端口上;(前提是,该端口已经被添加在云服务器的安全组中,在这里我找了好久的问题 😂)。
那么就会在 nginx.conf
写出如下配置 :
http {
# 主应用
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.xxx.cn;
location / {
root /root/copyer/main/build; # 指向主应用的打包文件
index index.html;
try_files $uri $uri/ /index.html;
}
}
# 子应用 (端口为:7241 域名为:www.xxx.cn)
server {
listen 7241;
server_name www.xxx.cn;
# 配置跨域信息
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
location / {
root /root/copyer/subapp/management; # 指向子应用的打包文件
index index.html;
try_files $uri $uri/ /index.html;
}
}
}
当访问 http://www.xxx.cn 时就会访问主应用的系统。
当访问 http://www.xxx.cn:7241 时,就会访问子应用的系统。
在上面的一步中,需要配置跨域信息;因为在客户端,端口不一样,就不满足同源策略,就会产生跨域。
前端代码注意事项
在前端代码中,也需要注意两点(就直接展示截图了):
第一点:主应用读取子应用的入口文件。
根据环境区分子应用的入口路径。
import.meta.env
是 vite 项目中读取配置文件信息
第二点:子应用中 vite.config.ts 的 base
的修改。
在 vite.config.ts
中配置开发或生产环境服务的公共基础路径是 base
属性,默认值为 /
。
配置该属性,影响的是读取静态文件的资源路径。
看一下,打包后的 index.html
文件
在读取静态资源的路径都拼接了 base。
为什么需要拼接 base 呢?
前面说过了 base 属性为 /
,那么当不配置时,读取静态资源的路径大致为/asstes/index-xxx.js
。当直接访问子应用(也就是访问 http://www.xxx.cn:7241),是没有影响的,因为访问的就是子应用根目录下的静态资源。但是如果是通过主应用来进行访问该路径(/asstes/index-xxx.js
),那么根目录就是主应用的根目录,那么就会存在找不到文件的错误问题,导致加载子应用不成功。
简单的来说,要明确根目录在哪里。
所以就需要精确的指定文件读取的路径,这也就是为什么需要配置 base。
方案二:一个端口,多个应用
该方案就是把所有应用部署在一个端口,主应用的 location 为 /
,针对子应用采用使用二级目录的方式(即:location 为 /xxx
)。
所以该方案就是一个 server,多加一层 location 的方式,那么就会在 nginx.conf
写出如下配置:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / { # 主应用
root /root/copyer/main/build;
index index.html;
try_files $uri $uri/ /index.html;
}
location /subapp { # 子应用
alias /root/copyer/subapp;
try_files $uri $uri/ /index.html;
}
}
当访问 http://www.xxx.cn 时就会访问主应用的系统。
当访问 http://www.xxx.cn/subapp/management 时,就会访问子应用的系统。
简单解释一下:
location 匹配存在优先级的关系,那么当请求 uri
为 /subapp
时,就会去匹配 location 为 /subapp 信息,然后通过 alias 的方式获取路径,读取文件信息。
# 测试路径:http://www.xxx.cn/subapp/management
location /subapp {
alias /root/copyer/subapp;
try_files $uri $uri/ /index.html;
}
# 最终匹配路径:/root/copyer/subapp/management
所以该方式对 nginx 中的文件目录结构是存在要求的。比如说:这里的 management 子应用就必须放在 subapp 文件夹下。
前端代码注意事项
也是会存在上面两点的问题:
-
主应用的入口文件信息配置。 -
子应用的 base 的属性值配置。
主应用:
qiankun 的入口文件配置:
开发环境:http://localhost:7241
生产环境:http://www.xxx.cn/subapp/management
子应用:
打包出来的 html 文件:
发现子应用的获取静态资源路径都是 /subapp/management
开始的,也就成功匹配了 location 为 /subapp
,那么就会去 /root/copyer/subapp/management
下找文件,显而易见能成功找到。
总结
上面的两种部署方案,个人尝试并都成功了。当然,可能其中还有些细节性的东西或者现象没有处理好,那么就请码友们多多指教,学习学习。
通过上面的两种部署方式都可以主应用访问,也能子应用单独访问;至于具体怎么部署,看个人的习惯或者开发的需求。
第一种,没有文件目录要求,就是每个应用单独部署。(多个 server)
第二种,就是 nginx 里面的文件目录需要按照一定的规范。(多个 location)
nginx 的反向代理
在上面的操作之后,就能通过域名进行对项目进行访问了。但是,当点击之后,可能也会发现一个问题,就是接口调不通。就比如说:
http://www.xxx.cn/api/query
你会发现,该接口,获取的资源是一个 html 文件。为什么呢?
因为在上面 location 中都没有配置 /api,当寻找不成功时,就会进入默认匹配 /
,从而也就解释了为什么返回 html 文件。
所以,为了解决上面的情况,就需要通过代理,代理到写的后台服务器中,获取对应的资源。
location /api/ { # 匹配 api, 转化到后台服务器
add_header Access-Control-Allow-Origin *; # 解决跨域
proxy_pass http://www.xxx.cn:8000/; # 后台服务器地址
}
那么你就会发现可以成功从后台服务器中获取数据,那么这时候一个完整的系统就可以运行了。
该系统就是采用的 koa 技术栈开发的服务器,利用 pm2 部署在 nginx 上的。
总结
通过上面的一系列步骤,就可以把自己的项目完整的运行在自己个域名上面,感觉非常棒👍🏻。
其实,对于大部分前端来说,是基本上不会接触 nginx 的;因为公司一般都是运维人员进行操作,再不济也是后端人员进行操作。所以说,我(前端人员)对 nginx 的看法就是可以了解,但是不必过分的深究,当然也不阻止你深究(不要太卷了)。
类似 nginx 的压缩,缓存等等,等到后面使用的时候,再去研究吧,对 nginx 的了解到此结束。
本篇就到此结束了,如果觉得对你有点帮助的,就点个赞呗~~~。
原文始发于微信公众号(石膏银程序员):我成功部署 qiankun + vite 项目,感觉极棒
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/187211.html