【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-loader
和webpack
的組合能夠使你在寫Vue.js
應用時,提供現代化、靈活的和功能非常強大的前端工作流
vue-loader是怎麼工作
vue-loader
不是簡單的源轉換器。它用自己專用的載入鏈(你可以認為每個塊是虛擬的模組)處理SFC(Single-file Component 單文件組件)內部的每個語言塊,最後將這些塊組成最終的模組。這是整個過程的簡要概述
vue-loader
使用@vue/component-compiler-utils
將SFC
源碼解析成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
導入的,每個塊都有不同的請求查詢
- 我們想要
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'
- 在擴展請求的過程中,主
vue-loader
將再次被調用。但是這次,載入器注意到這些請求有查詢並且只針對於特定塊。所以選擇(src/select.ts
)目標塊的內容將傳遞與載入器匹配的內容 - 對於這些
<script>
塊,這就差不多了。但是對於<template>
和<style>
,一些額外的任務需要被執行:
- 我們需要使用Vue模板編譯器編譯模板
- 我們需要在
css-loader
之後但是在style-loader
之前,為<style scoped>
塊進行CSS處理。
從技術上來看,這裡有額外的載入器(src/templateLoader.ts
和 src/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'