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
相关产品推荐
相关产品推荐

