You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit应用本地构建正常 GitLab CI执行build报错失败

问题根因

这个报错本质是构建缓存污染+CI流程配置错误,具体有三个核心问题:

  1. Lint阶段逻辑倒置:format-and-lint任务中先执行prettier --write自动修改源码,再做格式校验,导致CI环境自动篡改、且未经过本地构建验证的文件直接流向下游任务。一旦CI环境的prettier、svelte插件版本和本地存在微小差异,就可能破坏.svelte源文件的模板结构,比如造成插值标签{未闭合,Svelte编译器会把后续内容全部当成JS表达式解析,遇到编译生成的let声明时就会抛出「关键字保留」的错误。
  2. Artifact传递引发缓存污染:将整个frontend目录(包含node_modules、install阶段svelte-kit sync生成的.svelte-kit临时目录、vite预构建缓存)通过artifact在不同job间传递,生产构建时vite和svelte插件读取了上一阶段遗留的dev模式缓存,出现配置冲突(从日志中hmr、dev配置反复被强制切换就能看出异常),把dev模式下编译生成的代码当成源文件做二次编译,直接触发语法错误。
  3. 隐藏的流程bug:当前cypress任务中npm run preview会以前台模式启动预览服务器,直接阻塞后续cypress命令执行,就算构建成功也跑不了测试。

vitest阶段能正常执行,是因为vitest不需要跑完整的SvelteKit生产构建流程,按需转译组件时不会读取被污染的生产构建缓存,也不会触发全量路由编译逻辑,因此没有抛出错误。

修复方案

按以下顺序调整配置即可解决:

1. 修正lint阶段逻辑,禁止CI环境自动修改源码

CI环境只做校验,不要执行文件写操作,格式不符合要求直接终止流水线,让开发者本地格式化后再提交:

format-and-lint:
  stage: lint
  needs: [install]
  script:
    - cd frontend/
    # 提前清理临时缓存,避免install阶段生成的文件影响校验
    - rm -rf node_modules/.cache .svelte-kit
    # 只做格式和代码校验,移除CI环境下的自动格式化逻辑
    - npm run lint
  artifacts:
    # lint阶段不需要向下游传递修改后的文件
    paths: []
  only:
    - merge_requests

对应调整package.json中的lint脚本,将--write的格式化逻辑放到本地开发使用,不要出现在CI校验流程中:

"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",

2. 调整artifact配置,避免跨任务缓存污染

不要把node_modules、临时生成目录、构建缓存通过artifact传递,下游测试任务可以通过GitLab CI的cache机制缓存依赖,或者直接在任务内重新执行npm ci(稳定性更高,无缓存问题)。
修改cypress任务配置,构建前先清理所有临时目录,同时修复preview服务阻塞的问题:

cypress:
  stage: test
  needs: [format-and-lint]
  script:
    - cd frontend/
    # 清理所有可能的旧缓存、历史构建产物
    - rm -rf node_modules/.cache .svelte-kit build
    # 如果不通过artifact传递node_modules,打开下面这行重新安装依赖
    # - npm ci
    - npm run build
    # 将preview服务放到后台运行,等待服务启动后再执行测试
    - npm run preview &
    - sleep 5 # 可根据实际构建速度调整等待时长
    - npx cypress run --spec "cypress/integration/lehrenden-eintragung/*"
    # 测试完成后杀掉后台preview进程
    - kill %1
  artifacts:
    paths:
      # 只保留测试产物、构建产物即可,不要传递整个frontend目录
      - frontend/cypress/screenshots
      - frontend/cypress/videos
      - frontend/build
  only: 
    - merge_requests

vitest任务也同步增加构建前的缓存清理逻辑,避免受缓存影响。

3. (可选)显式固定编译配置,避免开关冲突

如果修改完上述配置后仍存在dev/hmr配置冲突的日志,可以在svelte.config.js中显式区分开发/生产环境的编译选项:

const config = {
  // 保留原有其他配置
  compilerOptions: {
    dev: process.env.NODE_ENV === 'development',
    hmr: process.env.NODE_ENV === 'development'
  },
  kit: {
    // 保留原有kit配置
    vite: {
      server: {
        hmr: process.env.NODE_ENV === 'development'
      }
    }
  }
};

调整后构建流程会在干净的环境下执行,和本地、Docker环境的构建逻辑保持一致,不会再出现二次编译的语法错误。


内容的提问来源于stack exchange,提问作者m0e33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:01:06