Docker执行ng test时PhantomJS无法启动的问题求助
Docker环境下ng test启动PhantomJS失败的解决方案
问题背景
在Docker环境中执行ng test命令时,PhantomJS无法启动,报错如下:
17:09:57 12 05 2023 11:39:57.559:INFO [karma]: Karma v1.7.1 server started at http://localhost:9876/ 17:09:57 12 05 2023 11:39:57.560:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency 17:09:57 12 05 2023 11:39:57.568:INFO [launcher]: Starting browser PhantomJS 17:09:58 12 05 2023 11:39:57.997:ERROR [phantomjs.launcher]: Error executing phantom at /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs 17:09:58 Error: spawn /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs ENOENT 17:09:58 at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19) 17:09:58 at onErrorNT (internal/child_process.js:465:16) 17:09:58 at processTicksAndRejections (internal/process/task_queues.js:80:21) 17:09:58 12 05 2023 11:39:57.999:ERROR [launcher]: Cannot start PhantomJS 17:09:58 Error executing phantom at /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs 17:09:58 Error: spawn /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs ENOENT 17:09:58 at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19) 17:09:58 at onErrorNT (internal/child_process.js:465:16) 17:09:58 at processTicksAndRejections (internal/process/task_queues.js:80:21)
已尝试在Dockerfile中设置环境变量:
ENV PHANTOMJS_BIN=./node_modules/phantomjs-prebuilt/bin/phantomjs ENV PHANTOMJS_HOME=./node_modules/phantomjs-prebuilt
当前karma.conf.js配置及测试命令如下:
module.exports = function (config) { config.set({ basePath: '', frameworks: ['jasmine', '@angular/cli'], plugins: [ require('karma-jasmine'), require('karma-phantomjs-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('@angular/cli/plugins/karma') ], client:{ clearContext: false // leave Jasmine Spec Runner output visible in browser }, files: [ { pattern: './src/test.ts', watched: false }, { pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: true }, ], preprocessors: { './src/test.ts': ['@angular/cli'] }, mime:{ 'text/x-typescript':['ts','tsx'] }, coverageIstanbulReporter: { reports: [ 'html', 'lcovonly' ], fixWebpackSourcePaths: true }, angularCli: { environment: 'dev' }, reporters: ['progress', 'kjhtml'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: ['PhantomJS'], singleRun: false }); };
测试命令:
ng test --single-run=true --browsers PhantomJS --watch=false --code-coverage=true --reporters=coverage-istanbul
解决方案
1. 检查PhantomJS二进制文件的存在性与权限
- 进入运行中的Docker容器,执行以下命令确认文件是否存在:
ls -l /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs - 如果文件存在但无执行权限,添加执行权限:
chmod +x /app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs - 如果文件不存在,删除本地依赖缓存后重新安装:
注意Docker构建时要避免依赖缓存问题,可在Dockerfile中添加rm -rf node_modules package-lock.json npm installRUN rm -rf node_modules package-lock.json && npm install确保依赖完整安装。
2. 修正环境变量与Karma配置的路径
- Dockerfile中使用绝对路径设置环境变量:
ENV PHANTOMJS_BIN=/app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs ENV PHANTOMJS_HOME=/app/node_modules/phantomjs-prebuilt - 直接在Karma配置中指定PhantomJS路径:
修改karma.conf.js,添加自定义启动器并替换默认的PhantomJS配置:
对应的测试命令改为:module.exports = function (config) { config.set({ // ... 其他配置 browsers: ['PhantomJS_custom'], customLaunchers: { PhantomJS_custom: { base: 'PhantomJS', options: { executablePath: '/app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs' } } }, // ... 其他配置 }); };ng test --single-run=true --browsers PhantomJS_custom --watch=false --code-coverage=true --reporters=coverage-istanbul
3. 安装PhantomJS所需的系统依赖
PhantomJS依赖系统字体库,需在Dockerfile中添加安装命令:
- 基于Debian/Ubuntu的镜像:
RUN apt-get update && apt-get install -y --no-install-recommends \ libfontconfig1 \ libfreetype6 \ && rm -rf /var/lib/apt/lists/* - 基于Alpine的镜像:
RUN apk add --no-cache \ fontconfig \ freetype \ && rm -rf /var/cache/apk/*
4. 替换PhantomJS为ChromeHeadless(推荐)
PhantomJS已停止维护,建议使用更稳定的ChromeHeadless替代:
- 安装依赖:
npm install karma-chrome-launcher --save-dev - 修改
karma.conf.js:module.exports = function (config) { config.set({ frameworks: ['jasmine', '@angular/cli'], plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), // 替换原phantomjs-launcher require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('@angular/cli/plugins/karma') ], // ... 其他配置 browsers: ['ChromeHeadless'], customLaunchers: { ChromeHeadless: { base: 'Chrome', flags: [ '--headless', '--disable-gpu', '--no-sandbox', // Docker环境必须添加 '--remote-debugging-port=9222' ] } }, // ... 其他配置 }); }; - 测试命令改为:
ng test --single-run=true --browsers ChromeHeadless --watch=false --code-coverage=true --reporters=coverage-istanbul - Dockerfile中安装Chrome依赖(Debian/Ubuntu):
RUN apt-get update && apt-get install -y --no-install-recommends \ chromium \ chromium-driver \ && rm -rf /var/lib/apt/lists/*
内容的提问来源于stack exchange,提问作者Sagar Sitap
相关产品推荐
相关产品推荐

