Docker中运行SvelteKit/Vite应用使用lucide-svelte图标时报转换错误
问题:Docker中运行SvelteKit应用时lucide-svelte图标导入失败
我正在开发一个部署在Amazon ECS上的SvelteKit应用,现在在本地Docker环境中运行开发版本。大部分功能正常,但使用lucide-svelte图标时出现导入错误,日志如下:
5:12:14 PM [vite] Pre-transform error: Failed to load url lucide-svelte/icons/home (resolved id: lucide-svelte/icons/home) in /app/src/routes/(logged_in)/+layout.svelte. Does the file exist? 5:12:24 PM [vite] Error when evaluating SSR module /src/routes/(logged_in)/+layout.svelte: failed to import "lucide-svelte/icons/home" |- Error: Cannot find module 'lucide-svelte/icons/home' imported from '/app/src/routes/(logged_in)/+layout.svelte' at nodeImport (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54756:25) at ssrImport (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54663:30) at eval (/app/src/routes/(logged_in)/+layout.svelte:7:37) at async instantiateModule (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54725:9) Error: Cannot find module 'lucide-svelte/icons/home' imported from '/app/src/routes/(logged_in)/+layout.svelte' at nodeImport (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54756:25) at ssrImport (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54663:30) at eval (/app/src/routes/(logged_in)/+layout.svelte:7:37) at async instantiateModule (file:///app/node_modules/.pnpm/vite@5.1.4/node_modules/vite/dist/node/chunks/dep-jDlpJiMN.js:54725:9) { code: 'ERR_MODULE_NOT_FOUND' }
对应的导入语句:
import Home from 'lucide-svelte/icons/home';
我有其他使用lucide-svelte的SvelteKit应用能在Docker中正常运行,因此推测是配置问题,但尚未定位原因。曾怀疑pnpm的符号链接机制,但其他应用同样使用pnpm却无异常。奇怪的是,该问题仅出现在Docker环境中,本地直接运行代码时图标显示正常、无报错。
以下是相关配置文件:
Dockerfile
FROM node:20-slim as base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable COPY . /app WORKDIR /app # 删除从主机复制的node_modules,避免M1架构与容器构建冲突 RUN rm -rf /app/node_modules FROM base as build RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile RUN pnpm run build FROM base AS prod-deps RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile FROM base COPY --from=prod-deps /app/node_modules /app/node_modules COPY --from=prod-deps /app/package.json /app/package.json COPY --from=build /app/build /app/build EXPOSE 5173 ENV PORT=5173 CMD [ "pnpm", "run", "start" ]
svelte.config.js
import sequence from 'svelte-sequential-preprocessor'; import adapter from '@sveltejs/adapter-node'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // 参考官方文档了解预处理器更多信息 preprocess: sequence([vitePreprocess({})]), kit: { adapter: adapter(), paths: { // 匹配nginx反向代理配置 base: '/admin/beta' } } }; export default config;
注:该配置与正常运行的应用唯一区别是base路径,移除后问题仍未解决。
vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [sveltekit()], server: { host: true, port: 5173 }, test: { include: ['src/**/*.{test,spec}.{js,ts}'] } });
tsconfig.json
{ "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true } }
解决思路
1. 检查lucide-svelte的依赖分类
查看package.json,确认lucide-svelte是在dependencies而非devDependencies中。如果是后者,Docker的prod-deps阶段会跳过安装,导致容器内缺失依赖。要么把它移到dependencies,要么修改Dockerfile的prod-deps阶段,去掉--prod参数:
FROM base AS prod-deps RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
2. 更新lucide-svelte至最新版本
旧版本的lucide-svelte可能存在ESM导入路径的兼容性问题,执行更新:
pnpm add lucide-svelte@latest
3. 调整pnpm安装参数
在Docker的pnpm install命令中添加--shamefully-hoist,避免符号链接导致的路径解析问题:
pnpm install --frozen-lockfile --shamefully-hoist
4. 修正导入路径
部分版本的lucide-svelte需要从dist目录导入,修改导入语句:
import Home from 'lucide-svelte/dist/icons/home';
5. 清理Docker缓存
缓存的旧依赖可能引发异常,清理后重新构建:
docker builder prune
内容的提问来源于stack exchange,提问作者Adam Tuttle
相关产品推荐
相关产品推荐

