{"id":13423834,"url":"https://github.com/vuejs/vue-loader","last_synced_at":"2025-05-14T11:08:23.119Z","repository":{"id":21382564,"uuid":"24700171","full_name":"vuejs/vue-loader","owner":"vuejs","description":"📦 Webpack loader for Vue.js components","archived":false,"fork":false,"pushed_at":"2024-08-07T07:28:11.000Z","size":6336,"stargazers_count":4995,"open_issues_count":231,"forks_count":919,"subscribers_count":113,"default_branch":"main","last_synced_at":"2025-05-07T10:52:36.365Z","etag":null,"topics":["hot-reload","single-file-component","vue","webpack"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vuejs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-10-02T00:05:07.000Z","updated_at":"2025-04-30T08:54:34.000Z","dependencies_parsed_at":"2024-01-02T23:39:24.780Z","dependency_job_id":"269979df-ce23-497b-b238-550c7b6338c0","html_url":"https://github.com/vuejs/vue-loader","commit_stats":{"total_commits":253,"total_committers":24,"mean_commits":"10.541666666666666","dds":0.4782608695652174,"last_synced_commit":"698636508e08f5379a57eaf086b5ff533af8e051"},"previous_names":[],"tags_count":161,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fvue-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fvue-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fvue-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vuejs%2Fvue-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vuejs","download_url":"https://codeload.github.com/vuejs/vue-loader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253736106,"owners_count":21955786,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hot-reload","single-file-component","vue","webpack"],"created_at":"2024-07-31T00:00:43.510Z","updated_at":"2025-05-14T11:08:23.079Z","avatar_url":"https://github.com/vuejs.png","language":"TypeScript","readme":"# vue-loader [![ci](https://github.com/vuejs/vue-loader/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/vuejs/vue-loader/actions/workflows/ci.yml)\n\n\u003e webpack loader for Vue Single-File Components\n\n- [Documentation](https://vue-loader.vuejs.org)\n\n## v17.2.1+ Only Options\n\n- `experimentalInlineMatchResource: boolean`: enable [Inline matchResource](https://webpack.js.org/api/loaders/#inline-matchresource) for rule matching for vue-loader.\n\n## v16+ Only Options\n\n- `reactivityTransform: boolean`: enable [Vue Reactivity Transform](https://github.com/vuejs/rfcs/discussions/369) (SFCs only).\n\n- ~~`refSugar: boolean`: **removed.** use `reactivityTransform` instead.~~\n\n- `customElement: boolean | RegExp`: enable custom elements mode. An SFC loaded in custom elements mode inlines its `\u003cstyle\u003e` 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.\n\n  - Default is `/\\.ce\\.vue$/`\n  - Setting to `true` will process all `.vue` files in custom element mode.\n\n- `enableTsInTemplate: boolean` (16.8+): allow TS expressions in templates when `\u003cscript\u003e` has `lang=\"ts\"`. Defaults to `true`.\n\n  - 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).\n\n  - Alternatively, leave this option on (by default) and use [`esbuild-loader`](https://github.com/privatenumber/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`).\n\n## What is Vue Loader?\n\n`vue-loader` is a loader for [webpack](https://webpack.js.org/) that allows you to author Vue components in a format called [Single-File Components (SFCs)](./docs/spec.md):\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv class=\"example\"\u003e{{ msg }}\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n  data() {\n    return {\n      msg: 'Hello world!',\n    }\n  },\n}\n\u003c/script\u003e\n\n\u003cstyle\u003e\n.example {\n  color: red;\n}\n\u003c/style\u003e\n```\n\nThere are many cool features provided by `vue-loader`:\n\n- Allows using other webpack loaders for each part of a Vue component, for example Sass for `\u003cstyle\u003e` and Pug for `\u003ctemplate\u003e`;\n- Allows custom blocks in a `.vue` file that can have custom loader chains applied to them;\n- Treat static assets referenced in `\u003cstyle\u003e` and `\u003ctemplate\u003e` as module dependencies and handle them with webpack loaders;\n- Simulate scoped CSS for each component;\n- State-preserving hot-reloading during development.\n\nIn 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.\n\n## How It Works\n\n\u003e 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.\n\n`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:\n\n1. `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:\n\n   ```js\n   // code returned from the main loader for 'source.vue'\n\n   // import the \u003ctemplate\u003e block\n   import render from 'source.vue?vue\u0026type=template'\n   // import the \u003cscript\u003e block\n   import script from 'source.vue?vue\u0026type=script'\n   export * from 'source.vue?vue\u0026type=script'\n   // import \u003cstyle\u003e blocks\n   import 'source.vue?vue\u0026type=style\u0026index=1'\n\n   script.render = render\n   export default script\n   ```\n\n   Notice how the code is importing `source.vue` itself, but with different request queries for each block.\n\n2. We want the content in `script` block to be treated like `.js` files (and if it's `\u003cscript lang=\"ts\"\u003e`, 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\u0026type=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.\n\n   Suppose we have configured `babel-loader` for all `*.js` files. That rule will be cloned and applied to Vue SFC `\u003cscript\u003e` blocks as well. Internally to webpack, a request like\n\n   ```js\n   import script from 'source.vue?vue\u0026type=script'\n   ```\n\n   Will expand to:\n\n   ```js\n   import script from 'babel-loader!vue-loader!source.vue?vue\u0026type=script'\n   ```\n\n   Notice the `vue-loader` is also matched because `vue-loader` are applied to `.vue` files.\n\n   Similarly, if you have configured `style-loader` + `css-loader` + `sass-loader` for `*.scss` files:\n\n   ```html\n   \u003cstyle scoped lang=\"scss\"\u003e\n   ```\n\n   Will be returned by `vue-loader` as:\n\n   ```js\n   import 'source.vue?vue\u0026type=style\u0026index=1\u0026scoped\u0026lang=scss'\n   ```\n\n   And webpack will expand it to:\n\n   ```js\n   import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue\u0026type=style\u0026index=1\u0026scoped\u0026lang=scss'\n   ```\n\n3. 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.\n\n4. For the `\u003cscript\u003e` block, this is pretty much it. For `\u003ctemplate\u003e` and `\u003cstyle\u003e` blocks though, a few extra tasks need to be performed:\n\n   - We need to compile the template using the Vue template compiler;\n   - We need to post-process the CSS in `\u003cstyle scoped\u003e` blocks, **after** `css-loader` but **before** `style-loader`.\n\n   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](https://webpack.js.org/api/loaders/#pitching-loader) (`src/pitcher.ts`) that intercepts Vue `\u003ctemplate\u003e` and `\u003cstyle\u003e` requests and injects the necessary loaders. The final requests look like the following:\n\n   ```js\n   // \u003ctemplate lang=\"pug\"\u003e\n   import 'vue-loader/template-loader!pug-loader!source.vue?vue\u0026type=template'\n\n   // \u003cstyle scoped lang=\"scss\"\u003e\n   import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue\u0026type=style\u0026index=1\u0026scoped\u0026lang=scss'\n   ```\n","funding_links":[],"categories":["Awesome Vue.js [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)","Awesome Vue.js","JavaScript","TypeScript","Plugins","Utilities [🔝](#readme)","Tools","实用库","公用事业","Components \u0026 Libraries","Utilities"],"sub_categories":["Development Tools","Rspack Loaders","Github","资产管理","Utilities","Asset Management"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvuejs%2Fvue-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvuejs%2Fvue-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvuejs%2Fvue-loader/lists"}