vue-loader
webpack loader for Vue Single-File Components
Attention
Non-official publishment, just for private learning, resource comes from official vue-loader's next branch, release is v16.0.0-beta.5.
vue-loader-v16
For Vue 3?
Why I Use My The npm version made it. But now the reason has gone.
The command to upgrade NPM is:
npm i -g npm
Yes, now you just need to upgrade npm version,and then run npm run serve
will be ok.
In vue official README.md, it syas:
As of v4.5.0, use @vue/cli
built-in option to choose Vue 3 preset when creating a vue 3 project, like this:
vue create <your vue 3 project name>
So when you start a vue 3 project by cli command, you need it, upgrade npm at first.
My experience is:
When I start a vue 3 project vuenext-vuecli-vite
, but it failed. The reason told me it depend on a module: vue-loader-v16
, then I publish it on npm
from official resource vue-loader
's branch next
, lastest release tag
is v16.0.0-beta.5. But now I realize that the error caused by npm low version. Older npm cannot understand the config:
{"vue-loader-v16": "npm:vue-loader@^16.0.0-beta.3}
,
so the folder vue-loader-v16
dependency module cannot be created, but new npm provides the function. Now my npm is v6.14.8
.
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:
-
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 the <script> block// import <style> blocksscriptrender = renderNotice how the code is importing
source.vue
itself, but with different request queries for each block. -
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 likesource.vue?vue&type=script
. This is whatVueLoaderPlugin
(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 likeWill expand to:
Notice the
vue-loader
is also matched becausevue-loader
are applied to.vue
files.Similarly, if you have configured
style-loader
+css-loader
+sass-loader
for*.scss
files:Will be returned by
vue-loader
as:And webpack will expand it to:
-
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. -
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, aftercss-loader
but beforestyle-loader
.
Technically, these are additional loaders (
src/templateLoader.ts
andsrc/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, soVueLoaderPlugin
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">// <style scoped lang="scss">
Maybe Issues
As running npm install --production
to install production dependency modules, the ./src
files throw none import syntax. But if I use @vue/cli
4.5+ to create a vue app, after installed, it works well without errors.