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'
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, before css-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:
import 'vue-loader/template-loader!pug-loader!vue-loader!source.vue?vue&type=template'
import 'style-loader!css-loader!vue-loader/style-post-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'