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

Laravel+Blade项目Vue3迁移:Jest测试ESM语法报错求助

问题:Vue3迁移后Jest测试ESM语法报错

将基于Laravel+Blade的Vue2项目迁移至Vue3,已完成核心组件迁移及适配Vue3的依赖更新/替换,但Jest测试配置无法正常工作。简单测试可通过,但当测试或组件使用外部包、import/export语法时,会抛出以下报错:

"SyntaxError: Unexpected token 'export'"
"SyntaxError: Cannot use import statement outside a module"

已尝试更新vue/test-utils、vue3-jest等依赖并调整配置,但问题仍未解决。

当前相关配置

package.json 片段

{
  "@babel/preset-env": "7.15.6",
  "@vue/test-utils": "^2.4.1",
  "babel-jest": "27.5.1",
  "babel-polyfill": "6.26.0",
  "expect": "27.5.1",
  "html-loader-jest": "0.2.1",
  "jest": "^27.5.1",
  "moxios": "0.4.0",
  "vue3-jest": "^27.0.0-alpha.1",
  "@popperjs/core": "^2.11.8",
  "@vue/compiler-sfc": "3.3.4",
  "@vueuse/core": "^10.3.0",
  "aws-amplify": "4.3.39",
  "axios": "0.21.1",
  "bootstrap": "^5.3.0",
  "cross-env": "3.2.4",
  "cross-spawn": "^7.0.3",
  "dotenv-webpack": "8.0.1",
  "emittery": "^1.0.1",
  "vue": "3.3.4",
  "vue-loader": "17.2.2",
  "webpack": "5.75.0",
}

jest.config.js

module.exports = {
    rootDir: __dirname,
    transform: {
        ".*\\.(vue)$": "vue3-jest",
        "^.+\\.(js|jsx)?$": "babel-jest",
        "^.+\\.html?$": "html-loader-jest"
    },
    collectCoverageFrom: [
        "<rootDir>/resources/assets/cms/js/components/**/*.{js,vue}",
        "<rootDir>/resources/assets/cms/js/vueRoot.js",
        "<rootDir>/resources/assets/cms/js/notification.js",
        "<rootDir>/resources/assets/cms/js/alerter.js",
        "<rootDir>/resources/assets/frontend/js/components/**/*.{js,vue}",
        "<rootDir>/resources/assets/frontend/js/helpers/**/*.{js,vue}",
        "<rootDir>/app/Components/**/*.{js,vue}",
        "!<rootDir>/**/*.spec.js"
    ],
    moduleFileExtensions: [
        "js",
        "json",
        "vue"
    ],
    testMatch: [
        "<rootDir>/**/*.(test|spec).js"
    ],
    setupFiles: ["dotenv/config"],
    setupFilesAfterEnv: [
        "<rootDir>/resources/assets/cms/js/test/index.js"
    ],
    roots: [
        "<rootDir>"
    ],
    testEnvironment: 'jsdom',
    transformIgnorePatterns: ["/node_modules/(?!vue-multiselect|vuetify|laravel-file-manager|swiper|ssr-window|dom7)"],
    moduleNameMapper: {
        "^.+\\.(css|less|sass)$": "<rootDir>/resources/assets/cms/js/test/CSSStub.js",
        "^vue$": "vue/dist/vue.cjs.js",
        "@scripts(.*)$": "<rootDir>/resources/assets/frontend/js/$1",
        "\\$components(.*)$": "<rootDir>/app/Components/$1",
        "\\$scripts(.*)$": "<rootDir>/resources/assets/frontend/js/$1",
        "\\$JsComponents(.*)$": "<rootDir>/resources/assets/frontend/js/components/$1",
        "@cmsScripts(.*)$": "<rootDir>/resources/assets/cms/js/$1",
        "@styles(.*)$": "<rootDir>/resources/assets/frontend/less/$1",
        "@cmsStyles(.*)$": "<rootDir>/resources/assets/cms/less/$1"
    },
    verbose: true,
    moduleDirectories: [
        "node_modules"
    ],
    bail: true,
    coverageDirectory:  "<rootDir>/public/coverage/js",
    collectCoverage: false,
    coverageReporters: ["lcov", "text", "clover", "html"]
};

babel.config.js

module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                targets: {
                    node: 'current',
                    browsers: 'last 3 versions and not dead >0.2%'
                },
            },
        ],
    ],
};

解决方案建议

  • 更新vue3-jest版本:当前使用的是^27.0.0-alpha.1测试版,存在兼容性隐患。替换为对应Jest 27的稳定版^27.0.0,确保和Jest、Vue3版本匹配。
  • 扩展transformIgnorePatterns白名单:将报错的ESM格式外部包(如aws-amplify、@vueuse/core、emittery)加入白名单,让Babel处理这些模块:
    transformIgnorePatterns: [
      "/node_modules/(?!vue-multiselect|vuetify|laravel-file-manager|swiper|ssr-window|dom7|aws-amplify|@vueuse|emittery)"
    ]
    
  • 优化Babel配置:在babel.config.js中明确设置模块处理逻辑并启用自动polyfill:
    module.exports = {
      presets: [
        [
          '@babel/preset-env',
          {
            targets: { node: 'current' },
            modules: 'auto',
            useBuiltIns: 'usage',
            corejs: 3 // 需先安装corejs@3依赖
          },
        ],
      ],
      plugins: ['@babel/plugin-transform-runtime'] // 需安装@babel/plugin-transform-runtime
    };
    
  • 补充moduleFileExtensions:添加mjs扩展名,确保ESM文件能被Jest识别:
    moduleFileExtensions: ["js", "json", "vue", "mjs"]
    
  • 移除废弃依赖:删除babel-polyfill,改用core-js和regenerator-runtime实现polyfill。
  • 验证Vue映射路径:确认moduleNameMapper中^vue$的映射路径为Vue3正确的CommonJS入口,比如vue/dist/vue.cjs.prod.js(生产环境)或vue/dist/vue.cjs.js(开发环境)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:10:55