首页
/ frp frpc 仪表盘:Vue 3 + Vite 管理面板的搭建、构建与二进制集成全解

frp frpc 仪表盘:Vue 3 + Vite 管理面板的搭建、构建与二进制集成全解

2026-09-04 20:50:51作者:蔡怀权

frp 项目为客户端提供了一套内置的 Web 管理面板 frpc-dashboard,用于可视化查看和管理 frpc 的代理(Proxy)与访问者(Visitor)配置。本文基于仓库中的 web/frpc/README.md 展开,完整覆盖该文档给出的依赖安装、开发热重载、生产构建与 ESLint 检查四步工作流,并结合 Makefilevite.config.mtsembed.go 等仓库文件,深入到前端如何与 frpc 二进制内的 HTTP API 对接、构建产物又如何通过 go:embed 打包进最终可执行文件的实现细节。读完后,你可以独立完成该面板的本地开发调试,并理解其从源码到 frpc 单文件的完整集成链路。

面板定位:frpc 客户端的管理界面

frp 的 Web 前端位于 web/ 目录下,采用 npm workspaces 组织为三个子工程:

  • web/frpc/ —— frpc 客户端仪表盘(即本文主角,package.json 中名为 frpc-dashboard);
  • web/frps/ —— frps 服务端仪表盘;
  • web/shared/ —— 两侧共用的组件与样式库。

这一结构在根级 web/package.json 中声明:"workspaces": ["shared", "frpc", "frps"],并提供了统一的单元测试入口 test:unit(vitest)。

frpc 面板的运行时数据来自 frpc 二进制自带的 HTTP API。以 conf/frpc_full_example.toml 为例,webServer.port = 7400 配置后,frpc 会在 7400 端口对外提供 API 与页面,路由定义见 client/api_router.go。前端源码 web/frpc/src/api/frpc.tsweb/frpc/src/api/http.ts 则封装了对这套 API 的调用。

安装依赖:workspaces 下的依赖管理

原始文档给出的第一步是:

yarn install

这里需要结合仓库现状补充一个关键事实:仓库根级提供的是 package-lock.json 而非 yarn.lock,且所有 Makefile 目标实际都走 npm。查看 web/frpc/Makefile

install:
	@cd .. && npm install

也就是说,文档中的 yarn install 在实际仓库中应当替换为在 web/ 目录下执行 npm install(或直接执行 make install,它会自动 cd ..web/ 再安装)。这样做的原因是 frpc、frps、shared 三个工程共用一套 workspaces 依赖,必须在 web/ 根目录统一安装,子目录单独安装会破坏 @shared 别名解析(见下文 Vite 配置部分)。

开发模式:make dev 启动 Vite 热重载

文档第二步是开发用热重载:

make dev

对应 Makefile 目标:

dev:
	@npm run dev

package.jsondev 脚本就是 vite 本体,即启动 Vite 7 开发服务器。web/frpc/vite.config.mts 中与开发体验强相关的配置有两处,值得展开:

1. API 代理(第 50~60 行)

server: {
  allowedHosts: process.env.ALLOWED_HOSTS ? process.env.ALLOWED_HOSTS.split(',') : [],
  proxy: {
    '/api': {
      target: process.env.VITE_API_URL || 'http://127.0.0.1:7400',
      changeOrigin: true,
    },
  },
},

前端所有 /api 前缀的请求会被代理到本地 frpc 实例的 HTTP API 服务,默认地址 http://127.0.0.1:7400,与 frpc 默认 webServer.port 一致。如果你把 frpc 的 webServer 配在其他地址,可通过环境变量 VITE_API_URL 覆盖代理目标——这是联调本地 frpc 二进制时最重要的开关。

2. 路径别名(第 25~31 行)

resolve: {
  alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url)),
    '@shared': fileURLToPath(new URL('../shared', import.meta.url)),
  },
  dedupe: ['vue', 'element-plus', '@element-plus/icons-vue'],
},

@shared 别名指向 web/shared,这正是 frpc 与 frps 共享 UI 组件(如 web/shared/components/ 下的 ActionButton、BaseDialog 等)的机制;dedupe 则保证 Vue/Element Plus 在 monorepo 中只有一份实例。

此外,vite.config.mts 还启用了 unplugin-auto-importunplugin-vue-components(均带 ElementPlusResolver),即 Element Plus 组件按需自动导入,生成物见仓库中的 auto-imports.d.tscomponents.d.ts;SCSS 全局注入 @use "@shared/css/_index.scss" as *;,使共享变量与 mixin 在每个样式文件中直接可用。

生产构建:make build 的类型检查 + 压缩

文档第三步:

make build

对应 build: install 依赖 npm run build,而 package.json 中:

"build": "run-p type-check build-only",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit"

即构建是两阶段并行执行:vue-tsc --noEmit 做 TypeScript 类型检查,vite build 产出 dist/。构建阶段 vite.config.mts(第 39~49 行)还做了体积优化:

build: {
  assetsDir: '',
  chunkSizeWarningLimit: 1000,
  minify: 'terser',
  terserOptions: { compress: { drop_console: true, drop_debugger: true } },
},

terser 压缩并移除 console/debugger 调用,assetsDir: '' 让资源与 index.html 平铺在 dist/ 根下——这一点与后文的 go:embed dist 直接相关。

需要特别注意的是根目录 Makefile 第 4 行的构建标签联动逻辑:

NOWEB_TAG = $(shell [ ! -d web/frps/dist ] || [ ! -d web/frpc/dist ] && echo ',noweb')

web/frpc/dist 不存在,编译 frpc 时会自动追加 noweb 构建标签,产出不含面板的二进制;反之则正常嵌入前端。因此完整的可带面板二进制应执行 make all(等价于 env fmt web build),先经 frpc-web 目标($(MAKE) -C web/frpc build)产出 dist/,再执行 go build -tags frpc ./cmd/frpc

代码质量:make lint

文档第四步:

make lint

对应 npm run lint,即 eslint . --fix。ESLint 基于 Vue 3 + TypeScript 栈配置(eslint-plugin-vue@vue/eslint-config-typescript、Prettier,见 web/frpc/eslint.config.jspackage.json 的 devDependencies)。另有一个不带 --fixlint:check 脚本,专供 CI 使用——根目录 Makefileweb-ci 目标即演示了完整 CI 链路:

web-ci:
	cd web && npm ci && npm run lint:check --workspace frps && npm run lint:check --workspace frpc && npm run test:unit && npm run build --workspace frps && npm run build --workspace frpc

单元测试同样可以本地运行:web/ 根目录下 npm run test:unit(vitest),frpc 侧的用例如 web/frpc/test/proxy-converters.test.ts,覆盖代理配置的表单转换逻辑。

从 dist 到二进制:embed 集成机制

frpc 面板最终不是独立部署的 Web 服务,而是打进 frpc 可执行文件。核心在 web/frpc/embed.go

//go:build !noweb

//go:embed dist
var EmbedFS embed.FS

func init() {
	assets.Register(EmbedFS)
}

init() 在包加载时把 embed.FS 注册到公共的 assets/assets.goRegister(第 52~56 行)通过 fs.Sub(fileSystem, "dist") 取到 dist 子树,使上层无需感知打包前缀;Load(第 40~50 行)则决定运行时的文件系统来源——若传入磁盘路径则优先从磁盘读文件(便于调试),否则用内存中的嵌入内容,两者皆无时退化为 emptyFS(所有路径 404)。

与之配合的 web/frpc/embed_stub.go 是一个空实现:

//go:build noweb

package frpc

当编译带 noweb 标签时,embed 文件被排除、stub 生效,二进制即不含前端资源——这正与根 Makefile 中 NOWEB_TAG 的自动探测形成闭环。frps 侧存在完全对称的 web/frps/embed.go 结构。

小结:一条可复现的本地工作流

综合文档与仓库源码,frpc 仪表盘的完整本地工作流为:

  1. web/npm install(等价 cd web/frpc && make install,README 中的 yarn install 以 npm 为准);
  2. cd web/frpc && make dev 启动热重载,配合本地运行的 frpc(webServer 默认 7400)或设置 VITE_API_URL 指向目标实例;
  3. make build 执行类型检查并产出 web/frpc/dist
  4. 回到仓库根目录 make frpc(或 make all)生成带面板的 bin/frpc
  5. 任何时刻用 make lint(本地自修复)或 npm run lint:check(CI 严格模式)保持代码风格,npm run test:unit 运行前端单测。

整个体系的关键设计在于:前端以 monorepo workspace 形式与 frps 面板共享组件层,构建产物通过 go:embed + 构建标签(noweb)无缝收进单一 Go 二进制,开发者体验(Vite 代理 7400 端口)与最终交付形态(无独立 Web 服务)保持一致。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384