Module parse failed

Webpack 5 Vue: Module parse failed Unexpected token fix

Webpack 5 can't parse Vue single-file components without the right loader. Here's the fix, plus what to do if it still breaks.

Quick Answer

Install vue-loader and @vue/compiler-sfc, add the rule to your webpack config, and include the VueLoaderPlugin. That's it.

Why This Happens

Webpack 5 doesn't know how to read a .vue file out of the box. It sees the <template> tag and chokes on the angle brackets, throwing Module parse failed: Unexpected token. This usually hits when you're setting up a Vue project manually or upgrading from webpack 4, where the config might've been looser. I had a client last month whose build broke exactly like this after they pulled a fresh Vue 3 project and forgot to carry over the vue-loader setup. The error points to the first line of the template block, which confuses people because it looks like valid HTML.

The real fix is telling webpack to hand .vue files to vue-loader, which splits the SFC into separate JavaScript, template, and style parts. Without that loader, webpack tries to parse the whole file as plain JavaScript and fails on the first non-JS token.

Fix Steps

  1. Install the required packages
    Run this in your project root:
    npm install --save-dev vue-loader @vue/compiler-sfc
    If you're on Vue 2, you'd use vue-template-compiler instead of @vue/compiler-sfc. But since you're likely on Vue 3, the compiler-sfc is the right one.
  2. Update your webpack.config.js
    Add the module rule and the plugin. Here's the minimal config that works for webpack 5:
    const { VueLoaderPlugin } = require('vue-loader')

    module.exports = {
    module: {
    rules: [
    {
    test: /\.vue$/,
    loader: 'vue-loader'
    }
    ]
    },
    plugins: [
    new VueLoaderPlugin()
    ]
    }
    The plugin is non-negotiable. It does the heavy lifting of cloning your other rules (like babel or sass) and applying them to the language blocks inside the SFC.
  3. Check your resolve extensions
    Make sure .vue is in the resolve.extensions array, so imports like import App from './App.vue' don't fail because webpack can't find the file. Add it like this:
    resolve: {
    extensions: ['.js', '.vue', '.json']
    }
  4. Rebuild
    Run your build command again. If the error persists, double-check that you didn't accidentally have two Vue copies or a mismatched version of vue-loader and vue. The plugin and loader must be the same major version.

Alternative Fixes

If you've done all that and it's still failing, try these:

  • Clear your node_modules and reinstall
    Sometimes the package manager leaves stale versions. Delete node_modules and package-lock.json, then run npm install again.
  • Check for a rogue babel rule
    If you have a rule that applies to /\.[jt]sx?$/ with a loader like babel-loader, make sure it's not also catching .vue files. Add exclude: /\.vue$/ to that rule to avoid conflicts.
  • For Vue 2 specifically
    Use vue-loader@15 and vue-template-compiler. The newer vue-loader 16+ is built for Vue 3 and won't work with Vue 2's compiler.

Prevention Tip

The best way to avoid this is to start from the official Vue project scaffolding. Run npm create vue@latest and let the tool set up the webpack config for you. If you're manually configuring webpack, always add the vue-loader plugin right after you add the rule, and keep the versions in sync. I've seen this error pop up months later when someone updates vue-loader without updating vue, or vice versa. Check the version compatibility table before upgrading anything.

Also, if you're migrating from webpack 4 to 5, watch out for changes in how loaders are resolved. Webpack 5 is stricter about the loader vs use syntax, but the above config works for both. Save yourself the headache and test your build after every dependency bump.

Related Errors in Programming & Dev Tools
Hydration failed because the initial UI does not match what was rendered on the Fix React hydration error: text mismatch 0XC0000194 0xC0000194 Deadlock: What It Is and How to Fix It Could not find method implementation() for arguments Fix Gradle 'Could not find method implementation()' error 0X000003E9 ERROR_STACK_OVERFLOW (0X000003E9) — Real Fix for Deep Recursion

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.