Vue2迁移Vue3后Webpack构建报错:单文件组件需含template/script
处理Vue2迁移Vue3时Webpack构建的SFC解析错误
问题背景
已将大型Vue2代码库升级至Vue3,package.json中升级的核心依赖如下:
"vue": "^3.2.45", "@vue/compat": "^3.2.45", "@vue/cli-plugin-babel": "^5.0.8", "@vue/cli-plugin-eslint": "^5.0.8", "@vue/cli-plugin-typescript": "^5.0.8", "@vue/cli-plugin-unit-jest": "^5.0.8", "@vue/cli-service": "^5.0.8", "@vue/compiler-sfc": "^3.2.0", "vue-class-component": "^8.0.0-rc.1", "vue-loader": "^17.0.1", ...
当前Webpack构建时,所有单文件组件均报错:
At least one <template> or <script> is required in a single file component
调试发现错误来自@vue\compiler-sfc\dist\compiler-sfc.cjs.js,组件的解析函数被调用两次:
- 第一次传入组件实际代码,解析正常;
- 第二次传入已编译后的代码(示例如下),因代码中无
<template>或<script>标签导致解析失败:
import { render } from "./deploymentInfos.vue?vue&type=template&id=1ced640a&ts=true" import script from "./deploymentInfos.vue?vue&type=script&lang=ts" export * from "./deploymentInfos.vue?vue&type=script&lang=ts" import exportComponent from "\\node_modules\\vue-loader\\dist\\exportHelper.js" const __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__file',"/deploymentInfos/deploymentInfos.vue"]]) /* hot reload */ if (module.hot) { __exports__.__hmrId = "1ced640a" const api = __VUE_HMR_RUNTIME__ module.hot.accept() if (!api.createRecord('1ced640a', __exports__)) { api.reload('1ced640a', __exports__) } ...
排查方向
- 检查vue-loader配置冲突:Vue3对应的vue-loader@17需配合Vue CLI 5内置配置,确认项目中是否存在自定义webpack配置重复注册vue-loader,或残留了Vue2时期vue-loader@15的旧配置。
- 统一@vue/compiler-sfc版本:当前@vue/compiler-sfc版本为^3.2.0,与vue@3.2.45存在版本差,将其升级至与vue完全一致的3.2.45版本,避免兼容性问题。
- 清理Vue CLI插件残留:确认项目中是否同时存在Vue2和Vue3的CLI插件依赖(如@vue/cli-service@4.x),或配置文件中引入了旧版插件的配置逻辑。
- 检查SFC loader规则:查看webpack配置中针对
.vue文件的loader规则,确认是否错误地将编译后的模块再次交给@vue/compiler-sfc处理——正常情况下vue-loader会拆分SFC的各个部分单独处理,不应让编译后的代码重复走SFC解析流程。 - 清理缓存:删除
node_modules、package-lock.json/yarn.lock后重新安装依赖,同时清理webpack缓存(如node_modules/.cache或Vue CLI的缓存目录),避免旧缓存干扰。 - 排查自定义插件/loader:若项目中有自定义webpack插件或loader,检查其处理
.vue文件的逻辑是否存在错误,导致编译后的代码被重复传入SFC解析器。
内容的提问来源于stack exchange,提问作者Reynicke
相关产品推荐
相关产品推荐

