Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

vue-loader

vuejs8.1mMIT17.4.2TypeScript support: included

webpack loader for Vue Single-File Components

readme

vue-loader ci

webpack loader for Vue Single-File Components

v17.2.1+ Only Options

  • experimentalInlineMatchResource: boolean: enable Inline matchResource for rule matching for vue-loader.

v16+ Only Options

  • reactivityTransform: boolean: enable Vue Reactivity Transform (SFCs only).

  • refSugar: boolean: removed. use reactivityTransform instead.

  • customElement: boolean | RegExp: enable custom elements mode. An SFC loaded in custom elements mode inlines its <style> tags as strings under the component's styles option. When used with defineCustomElement from Vue core, the styles will be injected into the custom element's shadow root.

    • Default is /\.ce\.vue$/
    • Setting to true will process all .vue files in custom element mode.
  • enableTsInTemplate: boolean (16.8+): allow TS expressions in templates when <script> has lang="ts". Defaults to true.

    • When used with ts-loader, due to ts-loader's cache invalidation behavior, it sometimes prevents the template from being hot-reloaded in isolation, causing the component to reload despite only the template being edited. If this is annoying, you can set this option to false (and avoid using TS expressions in templates).

    • Alternatively, leave this option on (by default) and use esbuild-loader to transpile TS instead, which doesn't suffer from this problem (it's also a lot faster). However, do note you will need to rely on TS type checking from other sources (e.g. IDE or vue-tsc).

What is Vue Loader?

vue-loader is a loader for webpack that allows you to author Vue components in a format called Single-File Components (SFCs):

<template>
  <div class="example">{{ msg }}</div>
</template>

<script>
export default {
  data() {
    return {
      msg: 'Hello world!',
    }
  },
}
</script>

<style>
.example {
  color: red;
}
</style>

There are many cool features provided by vue-loader:

  • Allows using other webpack loaders for each part of a Vue component, for example Sass for <style> and Pug for <template>;
  • Allows custom blocks in a .vue file that can have custom loader chains applied to them;
  • Treat static assets referenced in <style> and <template> as module dependencies and handle them with webpack loaders;
  • Simulate scoped CSS for each component;
  • State-preserving hot-reloading during development.

In a nutshell, the combination of webpack and vue-loader gives you a modern, flexible and extremely powerful front-end workflow for authoring Vue.js applications.

How It Works

The following section is for maintainers and contributors who are interested in the internal implementation details of vue-loader, and is not required knowledge for end users.

vue-loader is not a simple source transform loader. It handles each language blocks inside an SFC with its own dedicated loader chain (you can think of each block as a "virtual module"), and finally assembles the blocks together into the final module. Here's a brief overview of how the whole thing works:

  1. vue-loader parses the SFC source code into an SFC Descriptor using @vue/compiler-sfc. It then generates an import for each language block so the actual returned module code looks like this:

    // code returned from the main loader for 'source.vue'
    
    // import the <template> block
    import render from 'source.vue?vue&type=template'
    // import the <script> block
    import script from 'source.vue?vue&type=script'
    export * from 'source.vue?vue&type=script'
    // import <style> blocks
    import 'source.vue?vue&type=style&index=1'
    
    script.render = render
    export default script

    Notice how the code is importing source.vue itself, but with different request queries for each block.

  2. We want the content in script block to be treated like .js files (and if it's <script lang="ts">, we want to to be treated like .ts files). Same for other language blocks. So we want webpack to apply any configured module rules that matches .js also to requests that look like source.vue?vue&type=script. This is what VueLoaderPlugin (src/plugins.ts) does: for each module rule in the webpack config, it creates a modified clone that targets corresponding Vue language block requests.

    Suppose we have configured babel-loader for all *.js files. That rule will be cloned and applied to Vue SFC <script> blocks as well. Internally to webpack, a request like

    import script from 'source.vue?vue&type=script'

    Will expand to:

    import script from 'babel-loader!vue-loader!source.vue?vue&type=script'

    Notice the vue-loader is also matched because vue-loader are applied to .vue files.

    Similarly, if you have configured style-loader + css-loader + sass-loader for *.scss files:

    <style scoped lang="scss">

    Will be returned by vue-loader as:

    import 'source.vue?vue&type=style&index=1&scoped&lang=scss'

    And webpack will expand it to:

    import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
  3. When processing the expanded requests, the main vue-loader will get invoked again. This time though, the loader notices that the request has queries and is targeting a specific block only. So it selects (src/select.ts) the inner content of the target block and passes it on to the loaders matched after it.

  4. For the <script> block, this is pretty much it. For <template> and <style> blocks though, a few extra tasks need to be performed:

    • We need to compile the template using the Vue template compiler;
    • We need to post-process the CSS in <style scoped> blocks, after css-loader but before style-loader.

    Technically, these are additional loaders (src/templateLoader.ts and src/stylePostLoader.ts) that need to be injected into the expanded loader chain. It would be very complicated if the end users have to configure this themselves, so VueLoaderPlugin also injects a global Pitching Loader (src/pitcher.ts) that intercepts Vue <template> and <style> requests and injects the necessary loaders. The final requests look like the following:

    // <template lang="pug">
    import 'vue-loader/template-loader!pug-loader!source.vue?vue&type=template'
    
    // <style scoped lang="scss">
    import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'

changelog

17.4.1 (2023-12-30)

Bug Fixes

  • (temporarily) disable template ast reuse (31b03af)

17.4.0 (2023-12-25)

Features

  • leverage ast reuse in 3.4 (479835f)

17.3.1 (2023-10-31)

Bug Fixes

  • do not skip style post loader for v-bind() in CSS (d7071bb), closes #2061

17.3.0 (2023-10-07)

Bug Fixes

Features

  • skip normal css files without scoped flag in stylePostLoader (#2053) (98782e7)

17.2.2 (2023-06-02)

Bug Fixes

17.2.1 (2023-06-01)

Features

  • A new experimentalInlineMatchResource option (webpack 5 only), which leverages webpack 5's inline match resource feature and works well with the experiments.css feature (#2046) (3149f6d)

Note: v17.2.0 was released by accident, it has the same content as v17.1.2, therefore not included in the changelog.

17.1.2 (2023-05-29)

Bug Fixes

  • keep build stable when run in a different path (#2040) (a81dc0f)
  • properly close the watcher after tests (40b93b9)

17.1.1 (2023-05-11)

Bug Fixes

  • support propsDestructure and defineModel options (6269698)

17.1.0 (2023-04-26)

Bug Fixes

17.1.0-beta.0 (2023-04-19)

Bug Fixes

Features

  • support 3.3 imported types hmr (bbd98fc)

17.0.1 (2022-10-28)

Bug Fixes

  • add vue and @vue/compiler-sfc to optional peerDependencies (df0ded5), closes #1944
  • merge custom queries rather than appending (#1911) (9e4249a)

17.0.1 (2022-10-28)

Bug Fixes

  • add vue and @vue/compiler-sfc to optional peerDependencies (df0ded5), closes #1944
  • merge custom queries rather than appending (#1911) (9e4249a)

17.0.0 (2021-12-12)

Features

  • support reactivityTransform option (e07490e)

BREAKING CHANGES

  • remove refSugar option, require vue@^3.2.13

16.8.3 (2021-11-04)

Bug Fixes

  • HMR not working correctly with vue-class-component components (#1897) (76b1448)

16.8.3 (2021-11-04)

Bug Fixes

  • HMR not working correctly with vue-class-component components (#1897) (76b1448)

16.8.2 (2021-10-26)

Bug Fixes

16.8.1 (2021-09-22)

Bug Fixes

  • fix template options resolving for ts (91f581b)

16.8.0 (2021-09-22)

Bug Fixes

  • hmr: fix hmr regression (bacc6a9)

Features

  • enableTsInTemplate option (7613534)

    • When used with ts-loader, due to ts-loader's cache invalidation behavior, it sometimes prevents the template from being hot-reloaded in isolation, causing the component to reload despite only the template being edited. If this is annoying, you can set this option to false (and avoid using TS expressions in templates).

    • Alternatively, leave this option on (by default) and use esbuild-loader to transpile TS instead, which doesn't suffer from this problem (it's also a lot faster). However, do note you will need to rely on TS type checking from other sources (e.g. IDE or vue-tsc).

16.7.1 (2021-09-22)

Bug Fixes

  • remove pure annotation for custom blocks (cd891e5)

16.7.0 (2021-09-21)

Features

  • support optional @vue/compiler-sfc peer dep (21725a4)

16.6.0 (2021-09-20)

Bug Fixes

  • generate treeshaking friendly code (11e3cb8)

Features

  • support ts in template expressions (573fbd2)

16.5.0 (2021-08-07)

  • Custom Elements mode behavior changed: now only inlines the CSS and no longer exports the custom element constructor (exports the component as in normal mode). Users now need to explicitly call defineCustomElement on the component. This allows the custom element to be defined using an async version of the source component.

16.4.1 (2021-08-02)

Bug Fixes

16.4.0 (2021-07-30)

Features

  • customElement option support for Vue 3.2 (e19fcda)

16.3.3 (2021-07-21)

Bug Fixes

  • mark @vue/compiler-sfc as an optional peer dependency (089473a)

16.3.2 (2021-07-20)

Bug Fixes

  • add undeclared peer dependency webpack and @vue/compiler-sfc (#1853) (330d672)

16.3.1 (2021-07-16)

Bug Fixes

16.3.0 (2021-06-29)

Features

  • pass on compilerOptions and refSugar when using <script setup> (7137294)

16.3.0 (2021-06-29)

Features

  • pass on compilerOptions and refSugar when using <script setup> (7137294)

16.2.0 (2021-03-26)

Features

  • enable :slotted usage detection (66a3759)

16.1.2 (2020-12-17)

Bug Fixes

  • resourceQuery could be undefined in webpack 5 (6a1ee76), closes #1771

16.1.1 (2020-12-04)

Bug Fixes

  • ensure consistent component id across blocks (214b3f1)

16.1.0 (2020-11-30)

Features

  • allow manually specifying whether server-rendering is targeted (#1764) (9bbb82b), closes #1734

16.0.0 (2020-11-25)

Bug Fixes

Features

  • support for experimental sfc features (b85244b), closes #1723
  • support for new script setup and css var injection (fd33cad)

Performance Improvements

  • avoid resolveScript call in main loader (e922648)

16.0.0-rc.2 (2020-11-18)

Bug Fixes

  • disable esModuleInterop & allowSyntheticDefaultImports for TS (c76f5e5)

16.0.0-rc.1 (2020-11-07)

Bug Fixes

  • add back generator support (3db9ab8)

16.0.0-rc.0 (2020-11-06)

Bug Fixes

  • should apply cloned rules to custom blocks too (b2d7ffb)
  • should check for type query for render function imports (41af4b6)

16.0.0-beta.10 (2020-11-03)

Bug Fixes

16.0.0-beta.9 (2020-10-27)

Bug Fixes

  • avoid id inconsitency caused by CRLF (4b9b26c), closes #1706
  • fix mini-css-extract-plugin missing default export error (#1749) (55c6b12)
  • should not pass undefined to bindingsQuery (#1735) (859a45d), closes #1740

16.0.0-beta.8 (2020-09-23)

Bug Fixes

Features

  • output ssr render function when target is node (e691f6b)

16.0.0-beta.7 (2020-09-09)

Bug Fixes

  • do not throw when there's no script block in the SFC (a2262ce)
  • temporary fix for #1723 (9f6dd23)

16.0.0-beta.6 (2020-09-09)

Features

  • support <script setup> (fb09c8b)
  • support <style vars scoped> (1692287)

16.0.0-beta.5 (2020-08-11)

Features

  • allow compiler option to be a path to the compiler module (#1711) (064abd4)

16.0.0-beta.4 (2020-06-23)

Bug Fixes

16.0.0-beta.3 (2020-05-25)

Bug Fixes

16.0.0-beta.2 (2020-05-12)

Bug Fixes

  • do not require vue extension for template loader (#1673) (8c6eb5d)

16.0.0-beta.1 (2020-05-06)

Bug Fixes

  • fix css modules code gen (a81c432)

Features

16.0.0-alpha.3 (2020-02-04)

Bug Fixes

  • should not overwrite render when no <template> is present (04903b6)

16.0.0-alpha.2 (2020-01-10)

Bug Fixes

  • only inject hmrId when HMR is enabled (162a21f)

16.0.0-alpha.1 (2020-01-02)

Features

  • handle SFC parse error (aa5530d)
  • update to support named render function export (625b9bb)

16.0.0-alpha.0 (2019-12-20)

Bug Fixes

  • should use normalized resource for template code rule clone (a9944ff)
  • support Rule.rules + fix rule for render fn (d4072c4)

Features

  • apply loaders matching .js to compiled template code (20dbbfc)
  • basic hmr (108c1c1)
  • basic style support (4dad151)
  • css modules (627c826)
  • emit template compile error (61c0f8c)
  • handle line offset in errors (201cc62)
  • more accurate template source map (66d2ab8)
  • properly map template position (ee26c3a)
  • scopeId support (d9f932e)
  • support custom blocks (f238f59)