­

【Vuejs】509- vue-loader工作原理

  • 2020 年 2 月 26 日
  • 筆記

github.com/vuejs/vue-loader#how-it-works

什麼vue-loader

vue-loader是用於webpack的載入器,允許你用叫做Single-File Components單文件組件的格式來寫Vue組件

<template>  <div class="example">{{ msg }}</div></template>  <script>export default {  data () {    return {      msg: 'Hello world!'    }  }}</script>  <style>.example {  color: red;}</style>

這裡有vue-loader提供許多炫酷的功能

  • 允許Vue組件的每個部分使用其它的webpack載入器,比如Sass載入<style>Pug載入<template>
  • 允許.vue文件中的自定義塊,這些(自定義塊)能夠運用於訂製的載入程式鏈
  • 將靜態的<style><template>assets引用視為模組依賴,並且用webpack載入程式去處理他們
  • 模擬每個組件的CSS作用域
  • 在開發的過程中使用熱載入保持狀態

簡而言之,vue-loaderwebpack的組合能夠使你在寫Vue.js應用時,提供現代化、靈活的和功能非常強大的前端工作流

vue-loader是怎麼工作

vue-loader不是簡單的源轉換器。它用自己專用的載入鏈(你可以認為每個塊是虛擬的模組)處理SFC(Single-file Component 單文件組件)內部的每個語言塊,最後將這些塊組成最終的模組。這是整個過程的簡要概述

  1. vue-loader使用@vue/component-compiler-utilsSFC源碼解析成SFC描述符,然後為每個語言塊生成一個導入,實際返回的模組程式碼看起來像這樣
// 從主載入程式返回的程式碼source.vue的程式碼  // import the <template> blockimport render from 'source.vue?vue&type=template'  // import the <script> blockimport script from 'source.vue?vue&type=script'export * from 'source.vue?vue&type=script'  // import <style> blocksimport 'source.vue?vue&type=style&index=1'  script.render = renderexport default script

注意這些程式碼是從source.vue導入的,每個塊都有不同的請求查詢

  1. 我們想要script的內容被視為.js文件(如果是<script lang="ts",我們想要被視為.ts文件)。其他的語言塊也是同樣的。所以我們想要webpack 申請任何已配置模組的規則去匹配.js,也看起來像source.vue?vue&type=script的請求。這就是VueLoaderPlugin(src/plugin.ts)作用:對於webpack的每個模組規則,它創建一個相對於Vue語言塊請求的修改後的克隆

假設我們為所有的*.js配置過babel-loader.這些規則也一樣會複製和應用於到Vue SFC的<script>塊中,內部到webpack,一個像這樣的請求

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

將擴展為

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

注意是vue-loader 也會匹配,因為vue-loader是應用於.vue的文件。同樣地,如果你為*.scss文件配置了style-loader+css-loader+sass-loader

<style scoped lang="scss">

將通過vue-loader返回

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

webpack將會擴展成

import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
  1. 在擴展請求的過程中,主vue-loader將再次被調用。但是這次,載入器注意到這些請求有查詢並且只針對於特定塊。所以選擇(src/select.ts)目標塊的內容將傳遞與載入器匹配的內容
  2. 對於這些<script>塊,這就差不多了。但是對於<template><style>,一些額外的任務需要被執行:
  • 我們需要使用Vue模板編譯器編譯模板
  • 我們需要在css-loader之後但是在style-loader之前,為<style scoped>塊進行CSS處理。

從技術上來看,這裡有額外的載入器(src/templateLoader.tssrc/stylePostLoader.ts)需要注入到擴展的載入程式鏈。如果終端用戶不去配置(項目),這將會很複雜,所以VueLoaderPlugin也可以注入到一個全局Pitching Loader(src/pitcher.ts)並且監聽Vue<template><style>請求,注入必要的載入器中。最終的請求像下面這樣:

// <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'