vue.jsvue-loadervue-sfc

Vue3 build error: At least one <template> or <script> is required in a single file component


I try to migrate a large existing codebase from Vue2 to Vue3 using Webpack. So I upgraded the necessary packages in package.json to looks like this (no problems here):

"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",
...

Now the Webpack build always fails with the error: "At least one template or script is required in a single file component.", no matter which single file component it tries to compile.

So I debugged the source of the error, which is the @vue\compiler-sfc\dist\compiler-sfc.cjs.js), and found out, that the the function parsing the component file gets called twice. First time with the actual code of my component, which works perfectly fine. Then a second time with an already compiled version which looks like this:

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__)
  }

...

Of course it fails to parse <script> and <template> from this and throws the error.

I assume I have some kind of misconfiguration but am not able to find it. Does anyone have clue where to look?


Solution

  • Solved ✓

    The problem was that another webpack plugin also used the vue-loader. That was where the second call to parse the file came from.

    So if you encounter the same error message, try checking your webpack config if there are multiple usages of vue-loader.