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

运行第二次Lighthouse CI测试时遭遇EPERM权限拒绝错误求助

解决Lighthouse CI连续运行时的EPERM权限错误

你遇到的EPERM错误确实是因为Chrome进程未完全退出,导致Node无法删除被占用的临时文件。以下是几个可行的解决方案:

方案1:添加延迟清理的钩子

通过LHCI的postRun钩子延迟清理临时文件,给Chrome足够时间释放文件锁。同时指定自定义临时目录并手动清理:

const fs = require('fs').promises;
const path = require('path');
const { promisify } = require('util');
const setTimeoutAsync = promisify(setTimeout);

module.exports = {
  ci: {
    collect: {
      url: [
        "https://www.thissite.com/",
        "https://www.thissite.com/page-1/",
      ],
      numberOfRuns: 1,
      settings: {
        onlyCategories: ["performance"],
        // 指定自定义临时目录,禁用Chrome首次运行提示
        chromeFlags: "--user-data-dir=./lighthouse-tmp --no-first-run --no-default-browser-check"
      },
      hooks: {
        async postRun() {
          // 延迟3秒等待Chrome完全退出
          await setTimeoutAsync(3000);
          const tmpDir = path.resolve('./lighthouse-tmp');
          try {
            await fs.rm(tmpDir, { recursive: true, force: true });
          } catch (err) {
            console.warn('临时目录清理失败:', err.message);
          }
        }
      }
    },
    upload: {
      target: 'filesystem',
      outputDir: './reports'
    },
  },
};

方案2:强制杀死Chrome进程

在每次扫描完成后,强制关闭所有Chrome相关进程(仅适用于Windows环境,CI环境使用更安全,本地使用需注意会关闭自己正在用的Chrome):

const { execSync } = require('child_process');

module.exports = {
  ci: {
    collect: {
      url: [
        "https://www.thissite.com/",
        "https://www.thissite.com/page-1/",
      ],
      numberOfRuns: 1,
      settings: {
        onlyCategories: ["performance"]
      },
      hooks: {
        postRun() {
          try {
            // 强制关闭所有Chrome进程及子进程
            execSync('taskkill /F /IM chrome.exe /T', { stdio: 'ignore' });
          } catch (err) {
            // 无Chrome进程时忽略错误
          }
        }
      }
    },
    upload: {
      target: 'filesystem',
      outputDir: './reports'
    },
  },
};

方案3:使用唯一临时目录避免冲突

每次运行生成唯一的临时目录,避免因复用目录导致的文件锁定问题:

const fs = require('fs').promises;
const path = require('path');
const { promisify } = require('util');
const setTimeoutAsync = promisify(setTimeout);
const uniqueDir = `./lighthouse-tmp-${Date.now()}`;

module.exports = {
  ci: {
    collect: {
      url: [
        "https://www.thissite.com/",
        "https://www.thissite.com/page-1/",
      ],
      numberOfRuns: 1,
      settings: {
        onlyCategories: ["performance"],
        chromeFlags: `--user-data-dir=${path.resolve(uniqueDir)}`
      },
      hooks: {
        async postRun() {
          await setTimeoutAsync(2000);
          try {
            await fs.rm(path.resolve(uniqueDir), { recursive: true, force: true });
          } catch (err) {
            console.warn('临时目录清理失败:', err.message);
          }
        }
      }
    },
    upload: {
      target: 'filesystem',
      outputDir: './reports'
    },
  },
};

另外,你之前指定chromeFlags: "--user-data-dir=./tmp"未生效,可能是因为目录未提前创建、使用相对路径导致识别问题,或者Chrome仍在使用系统临时目录的其他缓存文件。建议使用绝对路径,并添加--no-first-run等参数避免Chrome的默认行为干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 03:07:30