{"id":12519,"library":"vue-loader","title":"webpack loader for Vue Single-File Components","description":"vue-loader is the essential webpack loader for building Vue.js applications using Single-File Components (SFCs). It enables webpack to parse `.vue` files, allowing developers to structure their components with separate `<template>`, `<script>`, and `<style>` blocks, each of which can leverage other webpack loaders (e.g., Sass for styles, Pug for templates, TypeScript for scripts). The current stable version is 17.4.2, which primarily targets Vue 3 and webpack 5, though it retains some compatibility with webpack 4. The project maintains an active release cadence, frequently publishing bug fixes and feature enhancements. Key differentiators include its deep integration with the Vue SFC specification, providing features like scoped CSS, custom blocks, efficient asset handling, and state-preserving hot-reloading for an optimized development experience, making it an indispensable part of most Vue CLI and custom webpack setups.","status":"active","version":"17.4.2","language":"javascript","source_language":"en","source_url":"https://github.com/vuejs/vue-loader","tags":["javascript","typescript"],"install":[{"cmd":"npm install vue-loader","lang":"bash","label":"npm"},{"cmd":"yarn add vue-loader","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-loader","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required peer dependency as vue-loader is a webpack loader.","package":"webpack","optional":false}],"imports":[{"note":"The VueLoaderPlugin is essential for processing SFCs; it must be instantiated in your webpack config's plugins array. CommonJS `require` works, but ESM `import` is preferred for modern webpack setups.","wrong":"const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin;","symbol":"VueLoaderPlugin","correct":"import { VueLoaderPlugin } from 'vue-loader';"},{"note":"While 'use' array technically works, 'loader' property is a direct shorthand when only one loader is applied. Ensure this rule comes before other loaders that might process specific language blocks within the SFC (e.g., ts-loader, sass-loader).","wrong":"{ test: /\\.vue$/, use: ['vue-loader'] }","symbol":"Rule for .vue files","correct":"{ test: /\\.vue$/, loader: 'vue-loader' }"},{"note":"When using TypeScript within `<script lang=\"ts\">` blocks in SFCs, ensure ts-loader (or esbuild-loader) is configured to process these files. The `appendTsSuffixTo: [/\\.vue$/]` option in `ts-loader` is crucial for it to recognize and compile TypeScript inside .vue files.","wrong":"No specific `wrong` for this, but omitting `appendTsSuffixTo` can lead to issues.","symbol":"TypeScript support","correct":"{ test: /\\.ts$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\\.vue$/] } }"}],"quickstart":{"code":"/* webpack.config.js */\nimport { VueLoaderPlugin } from 'vue-loader';\nimport path from 'path';\n\nexport default {\n  mode: 'development',\n  entry: './src/main.ts',\n  output: {\n    path: path.resolve(__dirname, 'dist'),\n    filename: 'bundle.js',\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.vue$/,\n        loader: 'vue-loader',\n      },\n      {\n        test: /\\.ts$/,\n        loader: 'ts-loader',\n        options: {\n          appendTsSuffixTo: [require.resolve('./src/App.vue')], // Path to main vue component or [/\\.vue$/]\n        },\n        exclude: /node_modules/,\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          'vue-style-loader',\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  plugins: [\n    new VueLoaderPlugin(),\n  ],\n  resolve: {\n    extensions: ['.vue', '.js', '.ts'],\n  },\n  devServer: {\n    static: {\n      directory: path.join(__dirname, 'public'),\n    },\n    compress: true,\n    port: 8080,\n    hot: true,\n  },\n};\n\n/* src/main.ts */\nimport { createApp } from 'vue';\nimport App from './App.vue';\nimport './assets/main.css';\n\nconst app = createApp(App);\napp.mount('#app');\n\n<!-- src/App.vue -->\n<template>\n  <div class=\"container\">\n    <h1>{{ greeting }}</h1>\n    <p>This is a Vue Single-File Component processed by vue-loader.</p>\n    <button @click=\"increment\">Count: {{ count }}</button>\n  </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, ref } from 'vue';\n\nexport default defineComponent({\n  name: 'App',\n  setup() {\n    const greeting = ref('Hello, vue-loader!');\n    const count = ref(0);\n\n    const increment = () => {\n      count.value++;\n    };\n\n    return {\n      greeting,\n      count,\n      increment,\n    };\n  },\n});\n</script>\n\n<style scoped>\n.container {\n  font-family: Avenir, Helvetica, Arial, sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  text-align: center;\n  color: #2c3e50;\n  margin-top: 60px;\n  border: 1px solid #ddd;\n  padding: 20px;\n  border-radius: 8px;\n  max-width: 600px;\n  margin-left: auto;\n  margin-right: auto;\n}\n\nh1 {\n  color: #42b983;\n}\n\nbutton {\n  background-color: #42b983;\n  color: white;\n  border: none;\n  padding: 10px 20px;\n  border-radius: 5px;\n  cursor: pointer;\n  font-size: 16px;\n  margin-top: 15px;\n}\n\nbutton:hover {\n  background-color: #368a6f;\n}\n</style>\n\n/* src/assets/main.css */\nbody {\n  margin: 0;\n  padding: 0;\n  background-color: #f4f4f4;\n}\n\n<!-- public/index.html -->\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Vue Loader Quickstart</title>\n</head>\n<body>\n  <div id=\"app\"></div>\n  <script src=\"bundle.js\"></script>\n</body>\n</html>\n","lang":"typescript","description":"This quickstart demonstrates a basic webpack setup with vue-loader for a Vue 3 application using TypeScript. It includes a `webpack.config.js` with rules for .vue, .ts, and .css files, the required `VueLoaderPlugin`, a simple `App.vue` Single-File Component with `<script lang=\"ts\">`, a `main.ts` entry point, global CSS, and an `index.html` to load the bundled output, showcasing how to compile and run a minimal Vue project."},"warnings":[{"fix":"Remove `refSugar: true` from your vue-loader options and enable `reactivityTransform` in your `vue-loader` configuration or globally if using Vue CLI/Vite.","message":"The `refSugar` option was removed in vue-loader v16+ (which supports Vue 3). Projects using this option will break and must migrate to Vue's built-in `reactivityTransform` feature instead.","severity":"breaking","affected_versions":">=16.0.0"},{"fix":"For Vue 2 projects, pin `vue-loader` to a v15 version (e.g., `^15.9.0`). For Vue 3 projects, ensure you are using `vue-loader` v16 or newer.","message":"vue-loader v16+ (including the current v17 series) is primarily designed for Vue 3. Using vue-loader v17 with Vue 2 projects will lead to compilation errors and incompatibility. For Vue 2 projects, `vue-loader` v15 (e.g., v15.11.1) is required.","severity":"breaking","affected_versions":">=16.0.0"},{"fix":"Ensure you are using `vue-loader@^17.2.1` and `webpack@^5.0.0` before enabling `experimentalInlineMatchResource`.","message":"The `experimentalInlineMatchResource` option is only available in `vue-loader` v17.2.1+ and requires webpack 5. Using it with earlier versions of `vue-loader` or with webpack 4 will not have any effect or may cause configuration errors.","severity":"gotcha","affected_versions":"<17.2.1"},{"fix":"Consider using `esbuild-loader` for transpiling TypeScript instead of `ts-loader` for better HMR performance. Alternatively, set `enableTsInTemplate: false` in `vue-loader` options if you don't use TypeScript expressions directly in your templates.","message":"When using TypeScript with `<script lang=\"ts\">` in SFCs and `enableTsInTemplate: true` (the default since v16.8+), `ts-loader` can cause template hot-reloading issues due to its cache invalidation. This can result in full component reloads even for minor template edits.","severity":"gotcha","affected_versions":">=16.8.0"},{"fix":"Add `new VueLoaderPlugin()` to the `plugins` array in your `webpack.config.js`.","message":"The `VueLoaderPlugin` must always be included in your webpack configuration's `plugins` array. Forgetting to add `new VueLoaderPlugin()` will prevent `vue-loader` from correctly processing custom blocks and other essential features of Vue Single-File Components, leading to parsing errors or unexpected behavior.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add a rule to your `webpack.config.js` `module.rules` array: `{ test: /\\.vue$/, loader: 'vue-loader' }`.","cause":"Webpack encountered a `.vue` file but does not have a rule configured to use `vue-loader` for it.","error":"Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file."},{"fix":"Ensure you `import { VueLoaderPlugin } from 'vue-loader';` and use `new VueLoaderPlugin()` in your `webpack.config.js` plugins array.","cause":"The `VueLoaderPlugin` was either imported incorrectly (e.g., as a default import when it's a named export) or instantiated without the `new` keyword.","error":"TypeError: VueLoaderPlugin is not a constructor"},{"fix":"Upgrade `vue-loader` to version 16 or newer (e.g., `npm install vue-loader@latest --save-dev`).","cause":"You are attempting to use an older version of `vue-loader` (v15 or earlier) with a Vue 3 project.","error":"Error: [vue-loader] vue-loader currently only supports Vue 2. If you are using Vue 3, you should use vue-loader@^16.0.0 instead."},{"fix":"Install `@vue/compiler-sfc`: `npm install @vue/compiler-sfc --save-dev`.","cause":"Your `vue-loader` version (v16+) requires the `@vue/compiler-sfc` package, which is missing from your project dependencies.","error":"[vue-loader] vue-loader requires @vue/compiler-sfc (since v16) to be installed."}],"ecosystem":"npm"}