尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Immich Web 前端项目深度解析:基于 SvelteKit 的构建、开发代理与 SPA 部署机制

Immich Web 前端项目深度解析:基于 SvelteKit 的构建、开发代理与 SPA 部署机制 Immich Web 前端项目深度解析基于 SvelteKit 的构建、开发代理与 SPA 部署机制【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immichImmich 的web/目录承载了整个系统的 Web 界面它基于 SvelteKit 框架开发本地开发时以 SvelteKit 的 Vite Node.js 开发服务器形态运行生产部署时则被构建为 SPA单页应用产物随 server 镜像一起分发并由后端托管静态资源。本文以 web/README.md 为主线结合 svelte.config.js、vite.config.ts、web/package.json 与 server/Dockerfile完整讲清该前端项目的技术栈、开发链路dev server 后端代理、版本注入、生产构建流程以及构建产物如何被 server 容器消费帮助开发者在动手贡献代码前建立对这套前端工程的完整认知。项目定位与技术栈选型web/README.md 开篇即明确了三件核心事实项目使用 SvelteKit Web 框架README 原文如此读者可参见 SvelteKit 官方文档入门理解 SvelteKit 的文件路由file-based routing是读懂本仓库 Web 代码的前提——src/routes/下的目录结构直接对应 URL 路径开发态与生产态形态不同本地开发运行的是 SvelteKit Node.js 开发服务器而生产环境是构建为 SPA 后并入 server 项目一起部署。从 web/package.json 可以看到实际锁定的技术栈版本以当前仓库为准依赖版本作用sveltejs/kit^2.56.1SvelteKit 框架本体svelte5.56.9Svelte 5Runes 时代的响应式语法sveltejs/vite-plugin-svelte7.3.0SvelteKit 依赖的 Vite 插件vite^8.0.0开发服务器与构建工具sveltejs/adapter-static^3.0.8静态站点适配器生产 SPA 的关键tailwindcss/tailwindcss/vite^4.2.4Tailwind CSS v4Vite 插件方式接入vitest/happy-dom/testing-library/svelte—单元测试三件套immich/sdkworkspace:*与 server 共享的类型化 API 客户端pnpm workspace 内部依赖maplibre-gl/pmtiles/svelte-maplibre—地图与瓦片支持hls.js/media-chrome—视频播放svelte-i18n^4.0.1配合仓库根目录i18n/下的 100 语言文件做多语言其中两个值得注意的细节immich/sdk: workspace:*Web 前端并非手写 REST 调用而是消费仓库内 packages/sdk 的本地包接口类型由 OpenAPI 规格生成参见 open-api/immich-openapi-specs.json保证前后端类型一致i18n别名svelte.config.js 中$i18n: ../i18n将翻译文件目录直接映射为$i18n导入而 server/Dockerfile 构建镜像时也显式COPY ./i18n ./i18n/说明国际化资源是 Web 构建的必需输入。目录结构以 SvelteKit 文件路由为骨架理解 SvelteKit 文件路由后web/的代码组织就很直观了。顶层目录web/ ├── bin/immich-web # 开发容器入口脚本等待后端就绪后启动 dev server ├── src/ │ ├── lib/ # 共享库代码别名 $lib约 470 个文件 │ ├── routes/ # SvelteKit 文件路由目录即 URL160 个 .svelte 页面 │ ├── params/ # URL 参数校验器 │ ├── service-worker/ # 离线/Service Worker 相关 │ ├── test-data/ # 测试夹具别名 test-data │ ├── app.css / app.html / app.d.ts │ └── hooks.client.ts / hooks.server.ts # 客户端/服务端生命周期钩子 ├── static/ # 原样拷贝的静态资源favicon、PWA manifest 等 ├── tests/ # 共享测试辅助别名 $tests ├── eslint.config.js ├── svelte.config.js ├── tsconfig.json └── vite.config.ts几个关键别名在 svelte.config.js 中定义alias: { $lib: src/lib, $lib/*: src/lib/*, $tests: src/../tests, test-data: src/test-data, $i18n: ../i18n, }$lib是 SvelteKit 约定俗成的库代码别名而$i18n指到仓库根目录的 i18n/ 文件夹——这也是为什么构建 web 时 i18n 目录必须与 web 目录同处一个构建上下文中。本地开发dev server、后端代理与 mise 任务开发服务器与三个代理前缀生产环境下 Web 界面与 server 同域同端口2283部署因此前端所有请求都以/api、/.well-known/immich等相对路径发出。本地开发时前后端分离Vite 在 3000 端口、server 在 2283 端口vite.config.ts 通过 Vite 的 dev proxy 把这三种前缀转发到后端const upstream { target: process.env.IMMICH_SERVER_URL || http://immich-server:2283/, secure: true, changeOrigin: true, logLevel: info, ws: true, // 支持 WebSocket供 socket.io 实时通知使用 }; const proxy { /api: upstream, // 全部 REST / socket.io API /.well-known/immich: upstream, // 实例发现端点App 配对用 /custom.css: upstream, // 自定义 CSS 注入 };要点IMMICH_SERVER_URL环境变量决定上游地址。默认值http://immich-server:2283/面向 Docker 内部网络本地裸跑时通常指向http://localhost:2283ws: true使 WebSocket 升级请求也走代理这是 Web 端实时推送socket.io-client 在 web/package.json 中依赖能工作的原因该 proxy 配置同时作用于server与preview两个环节vite.config.ts即vite preview静态预览产物时也保持同样的转发行为。vite 配置里还有两处开发体验相关设置server.allowedHosts: true允许通过非 localhost 域名访问适配远程开发场景和optimizeDeps.entries: [src/**/*.{svelte,ts,html}]显式声明预构建扫描入口。开发脚本web/package.json 中的脚本一览dev: vite dev --host 0.0.0.0 --port 3000, // 本地开发服务器 build: vite build, // 生产构建SPA 静态产物 build:stats: BUILD_STATStrue vite build, // 额外产出 bundle 体积分析 stats.html preview: vite preview, // 本地预览构建产物带 proxy check:svelte: svelte-check --no-tsconfig --fail-on-warnings ..., check:typescript: tsc --noEmit, lint: eslint . --max-warnings 0 --concurrency 6, test: vitest, prepare: svelte-kit sync // 安装后自动生成 .svelte-kit 类型/路由信息build:stats背后的机制在 vite.config.ts当环境变量BUILD_STATStrue时动态挂载rollup-plugin-visualizer构建后输出可视化产物stats.html用于分析打包体积构成。用 mise 一条命令拉起开发环境仓库统一用 mise 管理工具链与任务。web/mise.toml 定义的任务链很有代表性[tasks.start] run [ { task :install }, # pnpm install --filter immich-web --frozen-lockfile { task //:sdk:install }, # 安装并 … { task //:sdk:build }, # 先构建 workspace 内的 immich/sdk pnpm run dev, ]也就是说web 单独开发的前置条件是先构建immich/sdk因为它是workspace:*依赖这正是 server/Dockerfile 中sdk构建阶段先于web阶段的镜像原因——Web 构建在FROM sdk AS web阶段之上复用 SDK 产物。另一个实用任务是start-demo注入IMMICH_SERVER_URL https://demo.immich.app后执行start即可跳过本地后端、直接代理到官方演示实例做纯前端开发。Docker 开发模式bin/immich-web 等待后端就绪除了裸跑仓库还提供容器化开发。docker/docker-compose.dev.yml 中定义了immich-web服务镜像immich-web-dev:latest命令immich-web其入口脚本即 web/bin/immich-webcd /usr/src/app || exit pnpm --filter immich/sdk build UPSTREAM${IMMICH_SERVER_URL:-http://immich-server:2283/} # 轮询 GET ${UPSTREAM}/api/server/config 直到后端就绪 until wget --spider --quiet ${UPSTREAM}/api/server/config /dev/null 21; do ... sleep 1 done pnpm --filter immich-web exec vite dev --host 0.0.0.0 --port 3000这个脚本值得注意开发容器里跑的同样是vite dev热更新而非构建产物它先构建 SDK再通过/api/server/config端点探活后端每 10 次轮询打印一次等待日志确保 API 代理不会把请求打到尚未就绪的 server。这也呼应了 vite.config.ts 中那句注释connect to a remote backend during web-only development——该模式既支持代理本地后端也支持通过IMMICH_SERVER_URL指向远端后端。构建产物如何成为 SPAadapter-static 与回退路由web/README.md 最后一句it is built as a SPA其技术实现在 svelte.config.jskit: { version: { name: process.env.IMMICH_BUILD || process.env.npm_package_version || local, }, paths: { relative: false }, adapter: adapter({ fallback: index.html, precompress: true, }), ... }逐项解读sveltejs/adapter-staticfallback: index.htmlSvelteKit 构建出纯静态文件无 Node 运行时所有未被具体页面文件匹配的 URL 一律回退到index.html由前端路由接管——这就是 SPA 的标准落地方式。没有这一项深链deep link直接访问会 404precompress: true构建时预生成 gzip/brotli 压缩版本静态托管时可直接下发压缩内容paths.relative: false资源 URL 使用绝对路径/_app/...与 SPA 从任意路径被静态服务器兜底服务的要求一致version.name构建版本号取自IMMICH_BUILDCI 构建 ID→ 回退到npm_package_version即 package.json 的3.2.0-rc.0→ 本地开发则为local。该版本信息会被 SvelteKit 写入应用运行时供前端展示当前运行的 Immich 版本与 server 侧健康检查/状态页对版本的要求保持一致。server/Dockerfile 中ARG BUILD_ID / ENV IMMICH_BUILD${BUILD_ID}正是这条链路的上游。版本构建产物的目录约定build/→/build/wwwvite build的默认输出目录是web/build。这一点在 server/Dockerfile 中得到了消费侧印证COPY --fromweb /usr/src/app/web/build /build/www而 server 端在 server/src/repositories/config.repository.ts 里定义了静态目录约定const buildFolder dto.IMMICH_BUILD_DATA || /build; const folders { geodata: join(buildFolder, geodata), web: join(buildFolder, www), };并在 config.repository.ts 将其注册为静态资源配置root: folders.web、indexHtml: join(folders.web, index.html)。由此形成完整的部署闭环Dockerfile 把web/build拷到/build/wwwserver 启动时从IMMICH_BUILD_DATA默认/build下的www子目录提供 Web 界面与 docker/docker-compose.prod.yml 中 server 容器2283端口对外同时暴露 API 与页面的行为一致。测试与质量保障Web 项目的质量门禁同样由 web/package.json 与 web/mise.toml 组织单元测试Vitest happy-dom 环境配置内联在 vite.config.tsinclude: src/**/*.{test,spec}.{js,ts}、TZ: UTC固定时区避免日期断言漂移、setup 文件src/test-data/setup.ts类型与编译检查tsc --noEmit与svelte-check --fail-on-warnings双检查check:code还会串联 prettier 与 eslintmise 任务ci-unitSDK 安装构建 → install → format → check →test --run的完整链路checklist任务在其上追加 lint与 docs/developer/pr-checklist.md 描述的提交前检查项对应。针对 Svelte 5 的迁移期svelte.config.js 中留有// TODO pending immich/ui to enable it / runes: true注释onwarn钩子与check:svelte脚本则统一忽略state_referenced_locally告警——说明当前代码库正处于 Runes 模式全面开启前的过渡状态阅读源码时同一组件中混用$state与传统 store 是预期现象。小结回到 web/README.md 的三条主线本文已逐一落到可验证的仓库证据上SvelteKit 文件路由决定了src/routes/的代码组织方式vite dev --host 0.0.0.0 --port 3000配合IMMICH_SERVER_URL代理/api、/.well-known/immich、/custom.css含 WebSocket构成开发态mise 的:start任务负责 SDK 前置构建与拉起生产态则通过adapter-static的fallback: index.html构建出 SPAIMMICH_BUILD注入版本号vite build产物经 server/Dockerfile 落入/build/www由 server 依 config.repository.ts 的约定静态托管。掌握这条从源码到容器的完整链路即可独立启动 Immich Web 前端开发环境并理解其构建与部署行为。【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表