Gin 打包vue或react项目输出文件到程序二进制文件
Gin 打包vue或react项目输出文件到程序二进制文件
- 背景
- 解决方案
- 1. 示例目录结构
- 2. 有如下问题要解决:
- 3. 方案探索
- 效果
背景
前后端分离
已成为行业主流,vue
或react
等项目生成的文件独立在一个单独目录,与后端项目无关。
实际部署中,通常前面套一个nginx,根据请求返回静态资源或者代理到后端go服务上。
安装配置一套环境繁琐,加上有时需要部署在windows上,希望借助go的夸平台编译运行+embed嵌入文件能力,实现单个文件部署即可。
nginx配置样例
server {listen 80;root /usr/share/nginx/html;location / {try_files $uri $uri/index.html /index.html;}location /api {proxy_pass http://localhost/to-go-app-server;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-Real-IP $remote_addr;}
}
解决方案
1. 示例目录结构
app.go
为代码文件,同dist
一个目录app-server
为编译后的单个exe
.
├── app.go
├── app-server
└── dist├── assets│ ├── index-43d6e8d0.css│ └── index-f5e49ae2.js├── CNAME├── element-plus-logo-small.svg├── favicon.svg├── index.html└── vite.svg
2. 有如下问题要解决:
http://exmpale.com/
跟路由如何定向到dist/index.html
http://exmpale.com/xx.svg
以及http://exmpale.com/assets/xxxxx.js
这些动态路由如何生成http://exmpale.com/正常业务路由
与上面静态文件路由冲突如何处理
3. 方案探索
经过参考gin官方
github.com/gin-contrib/static
的插件,找出以下简单有效的解决方案
- 使用
embed
将整个文件夹嵌入- 所有请求增加一个中间件, 判断
embed.FS
总是否存在url中路径的文件- 存在使用http.fileserver处理,并中断处理链
- 不存在处理正常的逻辑
package mainimport ("embed""io/fs""net/http""github.com/gin-gonic/gin"
)//go:embed dist
var dist embed.FSfunc main() {r := gin.Default()r.Use(ServerStatic("dist", dist))r.GET("/ping", func(ctx *gin.Context) {ctx.String(http.StatusOK, "pong")})r.Run("localhost:81")
}/*
假设vue/react项目输出文件夹名字为dist,拷贝到该go文件所在目录下
注意"dist"前后不能有 /
r.Use(ServerStatic("dist", dist))
*/
func ServerStatic(prefix string, embedFs embed.FS) gin.HandlerFunc {return func(ctx *gin.Context) {// 去掉前缀fsys, err := fs.Sub(embedFs, prefix)if err != nil {panic(err)}fs2 := http.FS(fsys)f, err := fs2.Open(ctx.Request.URL.Path)if err != nil {// 判断文件不存在,退出交给其他路由函数ctx.Next()return}defer f.Close()http.FileServer(fs2).ServeHTTP(ctx.Writer, ctx.Request)ctx.Abort()}
}
效果
- 访问
http://localhost:81/
返回的是vue页面- 访问
http://localhost:81/ping
返回的是逻辑处理结果pong
相关文章:
Gin 打包vue或react项目输出文件到程序二进制文件
Gin 打包vue或react项目输出文件到程序二进制文件 背景解决方案1. 示例目录结构2. 有如下问题要解决:3. 方案探索 效果 背景 前后端分离已成为行业主流,vue或react等项目生成的文件独立在一个单独目录,与后端项目无关。 实际部署中,通常前面套…...
深度解析shell脚本的命令的原理之pwd
pwd是Print Working Directory的缩写,是一个Unix和Linux shell命令,用于打印当前工作目录的绝对路径。以下是对这个命令的深度解析: 获取当前工作目录:pwd命令通过调用操作系统提供的getcwd(或相应的)系统调…...
Kafka3.0.0版本——消费者(分区的分配以及再平衡)
目录 一、分区的分配以及再平衡1.1、消费者分区及消费者组的概述1.2、如何确定哪个consumer来消费哪个partition的数据1.3、消费者分区分配策略 一、分区的分配以及再平衡 1.1、消费者分区及消费者组的概述 一个consumer group中有多个consumer组成,一个 topic有多…...
Kotlin文件遍历FileTreeWalk filter
Kotlin文件遍历FileTreeWalk filter import java.io.Filefun main(args: Array<String>) {val filePath "."val file File(filePath)val fileTree: FileTreeWalk file.walk()fileTree//.maxDepth(1) //遍历层级1,不检查子目录.filter {it.isFile…...
Activiti兼容达梦数据库
1. 自定义类继承SpringProcessEngineConfiguration类,重写initDatabaseType方法。 package com.ydtf.cbda.module.cbdacim.improcess.config;import org.activiti.engine.ActivitiException; import org.activiti.spring.SpringProcessEngineConfiguration; import…...
shell 流程控制
流程控制 if条件判断 可以使用if来实现多路跳转,条件通常使用test命令 #if语句的语法if condition1then command1elif condition2 then command2else commandNfi 如果then需要和if放在同一行的话,使用;分隔 fi用来结束if语句,相当于…...
【C++】红黑树插入操作实现以及验证红黑树是否正确
文章目录 前言一、红黑树的插入操作1.红黑树结点的定义2.红黑树的插入1.uncle存在且为红2.uncle不存在3.uncle存在且为黑 3.完整代码 二、是否为红黑树的验证1.IsBlance函数2.CheckColor函数 三、红黑树与AVL树的比较 前言 红黑树,是一种二叉搜索树,但在…...
学信息系统项目管理师第4版系列07_项目管理知识体系
1. 项目管理原则 1.1. 勤勉、尊重和关心他人 1.1.1. 关键点 1.1.1.1. 关注组织内部和外部的职责 1.1.1.2. 坚持诚信、关心、可信、合规原则 1.1.1.3. 秉持整体观 1.1.2. 职责 1.1.2.1. 诚信 1.1.2.2. 关心 1.1.2.3. 可信 1.1.2.4. 合规 1.2. 营造协作的项目管理团队…...
Leetcode 2851. String Transformation
Leetcode 2851. String Transformation 0. 吐槽1. 算法思路 1. 整体思路2. 字符串匹配优化 2. 代码实现 题目链接:2851. String Transformation 0. 吐槽 这道题多少有点坑爹,题目本身挺有意思的,是一道数组题目,其实用数学方法…...
在PHP8中对数组进行计算-PHP8知识详解
在php8中,提供了丰富的计算函数,可以对数组进行计算操作。常见的计算函数如下几个:array_sum()函数、array_merge()函数、array_diff()函数、array_diff_assoc()函数、array_intersect()函数、array_intersect_assoc()函数。 1、array_sum()函…...
Android BottomSheetDialog最大展开高度问题
修改界面的时候遇到了这个问题,这个问题比较简单,网上解决方案也很多,这是 peekHeight 半展开高度,毕竟只是 dialog,全铺满就我们不必考虑 dialog 了 方法是在DialogFragment初始化dialog时处理 companion object {/*** 设置弹窗高度 默认展开无折叠情况 */ const val …...
记录Linux部署人脸修复GFPGAN项目Docker Python 使用
记录Linux 服务器使用人脸修复GFPGAN 项目 1:阿里云安装docker,用docker 是隔离环境,Python环境还真是麻烦… https://help.aliyun.com/zh/ecs/use-cases/deploy-and-use-docker-on-alibaba-cloud-linux-2-instances 2:关于docker 镜像,想找个好的镜像也是很难,百度吧,很多Li…...
如何编写可重入的函数?
编写可重入(reentrant)的函数是在多线程环境或并发编程中非常重要的任务。可重入函数是一种可以安全地被多个线程同时调用的函数,而不会导致数据竞争或不一致性的函数。在C语言中,编写可重入函数需要遵循一些特定的规则和技巧。本…...
使用纯C语言定义通用型数据结构的方法和示例
文章目录 前言以实现优先队列来描述实现思想基本类型的包装类型比较函数演示总结 前言 最近一段时间在复习数据结构和算法,用的C语言,不得不说,不学个高级语言再回头看C语言根本不知道C语言的强大和完美,不过相比之下也有许多不便…...
数据结构基础8:二叉树oj+层序遍历。
二叉树oj层序遍历 题目一:二叉树的销毁:方法一:前序遍历:方法二:后序遍历: 题目二:二叉树查找值为x的节点方法一:方法二:方法三: 题目三:层序遍历…...
Spring注解家族介绍:@RestController
前言: Spring Boot可以说是当前JAVA最为重要的一个框架,而Spring Boot的基石Spring中有着丰富的注解,因此我们会利用几篇文章来讲解我目前学到的各种注解,因此本类型文章的篇幅会比较短,主要着重于介绍各个注解。 目录…...
rocketmq
🍓代码仓库 https://gitee.com/xuhx615/rocket-mqdemo.git 🍓基本概念 ⭐生产者(Producer):消息发布者⭐主题(Topic):topic用于标识同一类业务类型的消息⭐消息队列(MessageQueue)…...
JAVA成员变量首字母小写,第二个字母大写报错问题(原因:Lombok与Spring冲突)
1、问题现象: JAVA类里定义成员变量使用首字母小写,第二个字母大写 Getter Setter public class BrandQueryObject extends QueryObject{private String pName; }结果页面报错,无法找到类型为 cn.wolfcode.ssm.query.BrandQueryObject 的对象…...
Python入门教程 |Python 错误和异常
Python3 错误和异常 作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。 Python 有两种错误很容易辨认:语法错误和异常。 Python assert(断…...
API商品接口对接使用:从理论到实践
随着电子商务的飞速发展,API商品接口已成为现代电子商务应用程序不可或缺的一部分。通过API商品接口,开发者可以轻松地从其他应用程序或服务中获取商品信息,实现快速、高效的电子商务功能。本文将探讨API商品接口的概念、对接使用的方法以及一…...
解决stable diffusion webui1.6 wd1.4 tagger加载失败的问题
由于webui源码的变化,需要修改两个地方的import 1.tagger/ui.py # 第十行 # from webui import wrap_gradio_gpu_call # 原代码 from modules.call_queue import wrap_gradio_gpu_call1.preload.py # 第4行开始 # from modules.shared import models_path # 原…...
Python学习-实现简单的http服务
基于Python实现一个简单的HttpServer,当用户在浏览器中输入IP地址:8000时,则会返回index.html页面内容,访问其它信息,则会返回错误信息(404) """ httpserver v1.0 1.获取来自浏览器的请求, 2.判断如果请求内容是 …...
#循循渐进学51单片机#变量进阶与点阵LED#not.6
1、掌握变量的作用域及存储类别。 局部变量 函数内部声明的变量,只在函数内部有效,在本函数以外是不能使用的,叫局部变量。 全局变量 在函数外部声明的变量就是全局变量,一个源程序可以包含一个或多个函数,全局变量…...
访问者模式
图片转载自 #include<iostream> using namespace std; #include<list> /*模板工厂单例化,所有的商品被注册进工厂中*/ /*访问者模式(行为型模式) 访问者,被访问者 visit accept 让访问变成一种操作,不同…...
epoll 的实现
epoll 这么好,为什么迟至 2.6 版本的 kernel 才支持(epoll manual: The epoll API was introduced in Linux kernel 2.5.44.)?2.4 版本的 kernel 不支持 epoll? 原因很简单,epoll 没什么神奇的。在早期没有太多的并发连接要处理&…...
怎么用excel管理固定资产
在当今的数字时代,我们已经习惯了使用各种电子工具来提高我们的生产力。其中,Excel无疑是一个强大的工具,它不仅可以帮助我们处理数据,还可以用来进行复杂的计算和分析。然而,你可能不知道的是,Excel也可以…...
记录crack某IDE插件过程
声明:本文仅记录学习过程,已对关键位置脱敏处理,未提供任何工具,请支持正版。 反编译jar包 使用cfr进行对插件核心jar包MyBxxxxxx-obfuss.jar进行反编译,在本地生成a.txt。 java -jar cfr-0.152.jar MyBxxxx-obfuss.…...
Android DEX相关,ART加载OAT文件
android .dex文件,对于Android DEX文件详细说明 Android dex、odex、oat、vdex、art区别 Android下的DEX文件和SO文件梳理总结 Android[art]-Android dex,odex,oat,vdex,art文件结构学习总结 第四章 常见的 Android 文件格式&…...
laravel框架 - 安装初步使用学习 composer安装
一、什么是laravel框架 Laravel框架可以开发各种不同类型的项目,内容管理系统(Content Management System,CMS)是一种比较典型的项目,常见的网站类型(如门户、新闻、博客、文章等)都可以利用CM…...
API实战教程:使用身份证OCR识别API构建一个应用
1. 引言 你是否曾经想过,只需拍一张身份证的照片,就能自动读取上面的所有信息?今天,我们要介绍的就是这样一个神奇的工具:身份证OCR识别API。不管你是技术小白还是初学者,跟着我们的步骤,你都可…...
wordpress去除相册样式/关键词搜索热度查询
Linux软RAID的实现方式前提软RAID说明软RAID实现mdadm配置示例软RAID测试和修复软RAID管理练习示例创建一个10G可用空间的RAID5。第1步:准备3块 5G 的硬盘。并对其进行分区创建,分区格式为 fd ,大小 5G第2步:再增加一块空闲盘第3步…...
search everything wordpress/长尾关键词挖掘
将企业软件中进行数据交换的业务对象,例如客户、订单或产品等常规模型进行标准化,让它们包含所有属性与关联信息,这种做法看上去似乎是一种吸引人的目标,但在Stefan Tilkov看来,这种方式将产生标准数据模型(…...
wordpress 密码访问/长沙关键词优化费用
目录 VI/VIM编辑器常用操作介绍: 1.VI和VIM是什么 2.一般模式 2.1常用语法 3.编辑模式 3.1常用语法 4.指令模式 4.1基本语法 5.模式转换 6.VI/VIM键盘图 1.VI和VIM是什么 VI 是 Unix 操作系统和类 Unix 操作系统中最通用的文本编辑器。VIM 编辑器是从 VI…...
做网站都需要什么资料/怎么找平台推广自己的产品
1 http://www.cnblogs.com/franksunny/archive/2011/11/17/2252926.html 2 http://www.cnblogs.com/vir56k/archive/2012/10/24/2737119.html 3 http://blog.30c.org/2798.html...
平谷区住房城乡建设委官方网站/餐饮营销引流都有什么方法
一、准备工作 Eureka通过运行多个实例,使其更具有高可用性。事实上,这是它默认的熟性,你需要做的就是给对等的实例一个合法的关联serviceurl 二、改造工作 在eureka-server工程中resources文件夹下,创建配置文件application-pe…...
cms模板/百度app优化
按变量的生存周期来划分,Linux变量可分为两类,它们的修改方法如下:(1)永久的:需要修改配置文件,变量永久生效。 常见的配置文件包括: (1-1)/etc/profil…...