1591 字
4 分钟
为 Sonic Topography 注入新活力 —— 从本地应用到可定制代理
2026-06-21

原项目是什么#

yin-yizhen/sonic-topography 是一个基于 Web Audio API 的音频可视化播放器,但它的本质是一个本地应用,而不是网站。

它的架构是这样的:

  • 前端:React + Vite,npm run dev 启动开发服务器。
  • 后端:通过 Vite 插件嵌入了一个 Node.js 脚本(local-server.mjs),提供网易云音乐的搜索、歌词、播放地址接口。
  • 播放列表:存储在项目根目录的 data/playlists.json 文件中,本地持久化。
  • 启动方式:一个命令 npm run dev 即可,前后端合在一起。

关键点:它只有“本地”这一个模式。Vite 启动后,前端请求 localhost:7200(Node 服务)来获取网易云数据。没有远程代理的概念,也不支持切换到其他后端。

为什么我想改它#

原项目很好用,但有几个地方让我觉得可以更灵活:

  1. 无法纯静态部署:如果我只有静态托管服务(比如 Vercel、Netlify),我就没法用这个应用,因为它依赖后端的 Node 服务。
  2. 端口写死:本地代理固定用 7200 端口,如果端口被占用或者我想换一个,就得改代码。
  3. 只能本地玩:我想把它部署到服务器上供朋友使用,但原项目的设计是面向单机的。

于是,我决定基于它做一个“增强版”:让这个应用既能在本地运行,也能纯静态部署(依赖远程代理),还能作为一个独立服务跑在服务器上。

我做了什么#

1. 增加在线模式(远程代理)#

我引入了“在线/本地”模式切换的概念:

  • 本地模式:和原项目一样,请求 http://localhost:7200 的 Node/Go 服务。
  • 在线模式:请求一个可自定义的远程 Worker(如 Cloudflare Workers),实现纯静态部署。

这样,前端可以完全脱离本地后端运行,只要有一个远程代理地址即可。用户只需要把前端 dist/ 部署到任何静态托管服务,然后配置一个 Worker 地址,就能正常使用。

2. 自定义端口#

在本地模式下,我添加了“端口”修改功能。用户可以直接在界面侧边栏点击“Port”按钮,输入新的端口号,无需修改代码或重启服务。端口号会保存在 localStorage 中,下次打开自动沿用。

3. 用 Go 重写后端(并保留 Node 作为备选)#

原项目的 Node 后端和 Vite 深度绑定,无法独立运行。我新增了一个 Go 版本的后端:

  • 可独立部署:编译为二进制,跑在任意服务器上。
  • 可内嵌前端:通过 embed 将前端 dist/ 打包进去,实现“一个文件即完整应用”。
  • 也可纯 API:只提供接口,前端单独部署。

这样,用户就有了多种选择:用原来的 Node 后端、用新的 Go 后端、或者纯前端 + 远程 Worker。

4. 播放列表从文件改为 localStorage#

原项目的播放列表存在 data/playlists.json,这是本地文件,在多设备或纯静态部署场景下并不适用。我将其改为前端 localStorage 存储,这样无论部署在哪里,用户自己的浏览器数据都在。

我的设计思考#

为什么要保留“本地模式”?#

因为我希望开发者依然可以像原项目一样,一条命令跑起完整应用进行开发调试。本地模式提供了最快的反馈循环。

为什么还要“在线模式”?#

因为我想让应用真正“可部署”。只要有一个远程代理(一个简单的 Cloudflare Worker),前端就可以被托管到任何 CDN,变成一个真正的网站应用。

为什么播放列表不用后端?#

因为我希望后端尽可能“轻”和“纯”。它只做代理,不做持久化。播放列表是用户个人的数据,保存在浏览器里最自然。如果有跨设备同步的需求,那是另一个话题了。

为什么提供 Go 版本,而不只是改进 Node?#

因为 Go 的部署更简单,编译后是单文件,无需安装 Node 环境。加上 embed 功能,连前端文件都能打包进去,部署流程变得极其简单。这对服务器部署场景非常友好。

最终成果#

我发布了 Sonic Proxy v1.0.0,相比原项目,新增了:

  • ✅ 在线/本地模式切换(支持远程 Worker)
  • ✅ 本地端口自定义(界面直接修改)
  • ✅ Go 版本后端(纯 API / 内嵌静态双版本)
  • ✅ 播放列表迁移到 localStorage
  • ✅ 完全兼容原项目的前端体验

而原项目的核心功能——音频可视化、歌词同步、频率触发、播放控制——全部保留,一丝未动

感受#

这次改造让我体会到,好代码不只在于写得好,更在于“好改”。Sonic Topography 的代码结构清晰,让我可以顺利地在它上面做扩展,而不是重写。

我也更深刻地理解了“部署”的多样性:本地应用、网站应用、自托管服务、纯静态应用…… 它们各有各的适用场景。让一个应用能适配多种场景,比只做一个单一形态的应用更有价值。

最后,这个项目也让我更熟练地掌握了 Go 的 embed、React 的优化技巧,以及如何在不破坏原有体验的前提下进行功能增强。


如果你也喜欢这个项目anagasyat/Sonic-Topography,或者有类似的需求,欢迎来我的 GitHub 看看。音乐继续,代码不止。🎵

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

为 Sonic Topography 注入新活力 —— 从本地应用到可定制代理
https://blog.ioll.top/posts/sonic/
作者
Yann
发布于
2026-06-21
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录