1.什麼是vue loader
Vue Loader 是一個 webpack 的 loader,它可以將.vue文件轉換爲webpack能夠處理的有效模塊:
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
2.安裝和webpack配置
安裝
vue-loader
和 vue-template-compiler
應該一起安裝。
每個 vue 包的新版本發佈時,一個相應版本的 vue-template-compiler
也會隨之發佈。編譯器的版本必須和基本的 vue 包保持同步,這樣 vue-loader
就會生成兼容運行時的代碼。這意味着你每次升級項目中的 vue 包時,也應該匹配升級 vue-template-compiler
。
webpack 配置
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module: {
rules: [
// ... 其它規則
{
test: /\.vue$/,
loader: 'vue-loader'
},
// 它會應用到普通的 `.js` 文件
// 以及 `.vue` 文件中的 `<script>` 塊
{
test: /\.js$/,
loader: 'babel-loader'
},
// 它會應用到普通的 `.css` 文件
// 以及 `.vue` 文件中的 `<style>` 塊
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
// 請確保引入這個插件!
//這個插件是必須的! 它的職責是將你定義過的其它規則複製並應用到 .vue 文件裏相應語言的塊。
//例如,如果你有一條匹配 /\.js$/ 的規則,那麼它會應用到 .vue 文件裏的 <script> 塊。
new VueLoaderPlugin()
]
}
3.處理資源路徑
轉換規則
當 Vue Loader 編譯單文件組件中的<template> 塊時,它也會將所有遇到的資源 URL 轉換爲 webpack 模塊請求。
資源 URL 轉換會遵循如下規則:
- 如果路徑是絕對路徑 (例如 /images/foo.png),會原樣保留。
- 如果路徑以 . 開頭,將會被看作相對的模塊依賴,並按照你的本地文件系統上的目錄結構進行解析。
- 如果路徑以 ~ 開頭,其後的部分將會被看作模塊依賴。這意味着你可以用該特性來引用一個 Node 依賴中的資源:
<img src="~some-npm-package/foo.png">
- 如果路徑以 @ 開頭,也會被看作模塊依賴。如果你的 webpack 配置中給 @ 配置了 alias,這就很有用了。所有 vue-cli 創建的項目都默認配置了將 @ 指向 /src。
resolve: {
alias: {
'@': 'C:\\Users\\app\\src',
//因爲運行時版本相比完整版體積要小大約 30%,所以應該儘可能使用這個版本。如果你仍然希望使用完整版,則需要在打包工具裏配置一個別名:vue.runtime.js
vue$: 'vue/dist/vue.runtime.esm.js'// 用 webpack 1 時需用 'vue/dist/vue.common.js'
},
}
file-loader與url-loader
.png 這樣的文件不是一個 JavaScript 模塊,你需要配置 webpack 使用 file-loader 或者 url-loader 去合理地處理它們。通過 Vue CLI 創建的項目已經把這些預配置好了:
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
/* config.module.rule('images').use('url-loader') */
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
}
}
]
},
file-loader 可以指定要複製和放置資源文件的位置,以及如何使用版本哈希命名以獲得更好的緩存。此外,這意味着 你可以就近管理圖片文件,可以使用相對路徑而不用擔心部署時 URL 的問題。使用正確的配置,webpack 將會在打包輸出中自動重寫文件路徑爲正確的 URL。
url-loader 允許你有條件地將文件轉換爲內聯的 base-64 URL (當文件小於給定的閾值),這會減少小文件的 HTTP 請求數。如果文件大於該閾值,會自動的交給 file-loader 處理。
4.使用預處理器
Sass
npm install -D sass-loader node-sass
module.exports = {
module: {
rules: [
// ... 忽略其它規則
// 現在,除了能夠 import 'style.scss',我們還可以在 Vue 組件中使用 SCSS
// 普通的 `.scss` 文件和 `*.vue` 文件中的
// `<style lang="scss">` 塊都應用它
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
},
// 共享全局變量
// sass-loader 也支持一個 data 選項,這個選項允許你在所有被處理的文件之間共享常見的變量,而不需要顯式地導入它們:
// webpack.config.js -> module.rules
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// 你也可以從一個文件讀取,例如 `variables.scss`
data: `$color: red;`
}
}
]
}
]
},
// 插件忽略
}
Less
npm install -D less less-loader
// webpack.config.js -> module.rules
{
test: /\.less$/,
use: [
'vue-style-loader',
'css-loader',
'less-loader'
]
}
Stylus
npm install -D stylus stylus-loader
// webpack.config.js -> module.rules
{
test: /\.styl(us)?$/,
use: [
'vue-style-loader',
'css-loader',
'stylus-loader'
]
}
5.Scoped CSS
當<style> 標籤有 scoped 屬性時,它的 CSS 只作用於當前組件中的元素。因爲scoped會被轉換爲一個唯一的特性,用來表示當前組件。
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
<!-- 轉換結果: -->
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
子組件的根元素
使用 scoped 後,父組件的樣式將不會滲透到子組件中。不過一個子組件的根節點會同時受其父組件的 scoped CSS 和子組件的 scoped CSS 的影響。這樣設計是爲了讓父組件可以從佈局的角度出發,調整其子組件根元素的樣式。能用class還是用class,當 p { color: red } 是 scoped 時 (即與特性選擇器組合使用時) 會慢很多倍。
深度作用選擇器
如果你希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,你可以使用 >>>
操作符:
<style scoped>
.a >>> .b { /* ... */ }
</style>
<style scoped>
.a /deep/ .b { /* ... */ }
</style>
<style scoped>
.a/deep/ .b { /* ... */ }
</style>
<style scoped>
.a ::v-deep .b { /* ... */ }
</style>
上述代碼將會編譯成:
.a[data-v-f3f3eg9] .b { /* ... */ }
有些像 Sass 之類的預處理器無法正確解析 >>>
。這種情況下你可以使用 /deep/
或 ::v-deep
操作符取而代之——兩者都是 >>>
的別名,同樣可以正常工作。
動態生成的內容
通過 v-html 創建的 DOM 內容不受 scoped 樣式影響,但是你仍然可以通過深度作用選擇器來爲他們設置樣式。
6.CSS Modules
CSS Modules 是一個流行的,用於模塊化和組合 CSS 的系統。vue-loader 提供了與 CSS Modules 的一流集成,可以作爲模擬 scoped CSS 的替代方案。
首先,CSS Modules 必須通過向 css-loader 傳入 modules: true 來開啓:
// webpack.config.js
{
module: {
rules: [
//和預處理器配合使用
{
test: /\.scss$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: { modules: true }
},
'sass-loader'
]
}
// ... 其它規則省略
{//如果只有這個css規則的話,css只能是modules模式的,不能匹配普通的 `<style>` 或 `<style scoped>`,遇到普通的編譯會出錯
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// 開啓 CSS Modules
modules: true,
// 自定義生成的類名(這個屬性在css-loader3.0.0版本以上已被刪除)
//localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
然後在你的 <style> 上添加 module 特性:
<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style>
這個 module 特性指引 Vue Loader 作爲名爲 $style
的計算屬性,向組件注入 CSS Modules 局部
(只能獲取當前組件中的calss)對象。然後你就可以在模板中通過一個動態類綁定來使用它了:
<template>
<p :class="$style.red">
This should be red
</p>
<p :class="{ [$style.red]: isRed }">
Am I red?
</p>
<p :class="[$style.red, $style.bold]">
Red and bold
</p>
</template>
你也可以通過 JavaScript 訪問到它:
export default {
created () {
console.log(this.$style.red)//{red:'xxxclass'}
// -> "red_1VyoJ-uZ"
// 一個基於文件名和類名生成的標識符
}
}
js中引入css:
//./style.css
.test {
color: green;
}
:global(.global) {
color: red;
}/* 全局class爲global時顏色爲red */
/* 顯式的局部作用域語法:local(.className),等同於.className */
:local(.local) {
color: orchid;
}
import styles from "./style.css?line";//module.rules中css規則設置resourceQuery: /line/後,必須在css後面加上line參數纔可以匹配到。
//顯式的局部作用域語法:local(.className),等同於.className
document.getElementById('ss').innerHTML = `
<div class="${styles.test}">js中導入的css</div>
<div class="global">global樣式</div>
<div class="${styles.local}">local樣式</div>
`;
自定義的注入名稱
在 .vue 中你可以定義不止一個<style>,爲了避免被覆蓋,你可以通過設置 module 屬性來爲它們定義注入後計算屬性的名稱。
<div :class="a.child1">a自定義module樣式</div>
<div :class="b.child2">b自定義module樣式</div>
<style module="a">
/* 注入標識符 a,可通過this.a在js中調用*/
</style>
<style module="b">
/* 注入標識符 b */
</style>
可選用法
如果你只想在某些 Vue 組件中使用 CSS Modules,你可以使用 oneOf 規則並在 resourceQuery 字符串中檢查 module 字符串:
/js中只有import xxx from 'xxx.css?module’這個能匹配到。否則不生效
// webpack.config.js -> module.rules
{
test: /\.css$/,
oneOf: [
// 這裏匹配 `<style module>`
{
resourceQuery: /module/,//js中只有import xxx from 'xxx.css?module'這個能匹配到。否則不生效
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
//The option importLoaders allows you to configure how many loaders before css-loader should be applied to @imported resources.
importLoaders: 1//https://github.com/webpack-contrib/css-loader#importloaders
//(這個屬性在css-loader3.0.0版本以上已被刪除)
//https://github.com/webpack-contrib/css-loader/commit/c4b7f715a81d06858778e54a4fb78258d48a1426
//localIdentName: '[local]_[hash:base64:5]'
}
},
'postcss-loader'//PostCSS 是一個允許使用 JS 插件轉換樣式的工具。 這些插件可以檢查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 編譯尚未被瀏覽器廣泛支持的先進的 CSS 語法,內聯圖片,以及其它很多優秀的功能。
//比如autoprefixer插件,加css前綴,必須使用browserslistrc來工作
//https://github.com/postcss/postcss/blob/master/README-cn.md
]
},
// 這裏匹配普通的 `<style>` 或 `<style scoped>`
{
use: [
'vue-style-loader',
'css-loader',
'postcss-loader'
]
}
]
}
css modules例子:
<style module>
/* 顯式的局部作用域語法:local(.localxxx),等同於.localxxx */
:local(.localxxx){
color:green
}
全局class,<div class="globalxxx">默認module,global樣式</div>
:global(.globalxxx){
color:skyblue
}
.normal{
color: blueviolet;
}
</style>
<style module="aaa">
.className {
color: green;
background: red;
}
.child1 {
composes: className;
color:yellow;
}
</style>
<style module="bbb">
.child2 {
composes: test from "./style.css";/* test必須和style.css中類名一樣 */
}
</style>
7.熱重載
啓用熱重載後,當你修改 .vue 文件時,該組件的所有實例將在不刷新頁面的情況下被替換
狀態保留規則
-
當編輯一個組件的<template> 時,這個組件實例將就地重新渲染,並保留當前所有的私有狀態。能夠做到這一點是因爲模板被編譯成了新的無副作用的渲染函數。
-
當編輯一個組件的 <script> 時,這個組件實例將就地銷燬並重新創建。(應用中其它組件的狀態將會被保留) 是因爲 <script> 可能包含帶有副作用的生命週期鉤子,所以將重新渲染替換爲重新加載是必須的,這樣做可以確保組件行爲的一致性。這也意味着,如果你的組件帶有全局副作用,則整個頁面將會被重新加載。
-
<style> 會通過 vue-style-loader 自行熱重載,所以它不會影響應用的狀態
webpack中 devServer: {hot:false }的hot選項是一級熱重載開關,vueloader中hotReload選項是二級熱重載開關。
hot 和 hotOnly 的區別是在某些模塊不支持熱更新的情況下,前者會自動刷新頁面,後者不會刷新頁面,而是在控制檯輸出熱更新失敗
hot:true,hostReload:true//熱重載
hot:true,hostReload:false//刷新整個頁面,不是熱重載
hot:false,hostReload:true//刷新整個頁面,不是熱重載
hot:false,hostReload:false//刷新整個頁面,不是熱重載
你可以設置 hotReload: false 選項來顯式地關閉熱重載:
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
hotReload: false // 關閉熱重載
}
}
]
}
8.函數式組件
要聲明一個應該編譯爲函數式組件的模板,請將 functional
特性添加到模板塊中。這樣做以後就可以省略 <script> 塊中的 functional 選項。
模板中的表達式會在函數式渲染上下文中求值。這意味着在模板中,prop 需要以 props.xxx 的形式訪問:
<template functional>
<div>{{ props.foo }}</div>
</template>
你可以在 parent 上訪問 Vue.prototype 全局定義的屬性:
<template functional>
<div>{{ parent.$someProperty }}</div>
</template>
9.自定義塊
在 .vue 文件中,你可以自定義語言塊。應用於一個自定義塊的 loader 是基於這個塊的 lang 特性
、塊的標籤名
以及你的 webpack 配置進行匹配的。
如果指定了一個 lang 特性(lang=“xxx”),則這個自定義塊將會作爲一個帶有該 lang 擴展名
的文件進行匹配。
<xxxx lang="langxxx">
This is langModule。
</xxxx>
<div lang="langxxx">
This is langModule div。
</div>
你也可以使用 resourceQuery 來爲一個沒有 lang 的自定義塊匹配一條規則。例如爲了匹配自定義塊<foo>:
{
module: {
rules: [
{
resourceQuery: /blockType=foo/,
loader: 'loader-to-use'
}
]
}
}
如果找到了一個自定義塊的匹配規則,它將會被處理,否則該自定義塊會被默默忽略。
此外,如果這個自定義塊被所有匹配的 loader 處理之後導出一個函數作爲最終結果,則這個 *.vue 文件的組件會作爲一個參數被這個函數調用。
這裏有一個向組件內注入 自定義塊的示例,且它是在運行時可用的。
爲了注入自定義塊的內容,我們將會撰寫一個自定義 loader:
module.exports = function (source, map) {
this.callback(
null,
`export default function (Component) {
Component.options.__docs = ${
JSON.stringify(source)
}
}`,
map
)
}
現在我們將會配置 webpack 來使用爲 <docs> 自定義塊撰寫的自定義 loader。
// wepback.config.js
module.exports = {
module: {
rules: [
{
//匹配vueloader自定義模塊/ComponentA.vue中標籤名爲docs的塊
resourceQuery: /blockType=docs/,
loader: require.resolve('./docs-loader.js')
},
{
//匹配vueloader自定義模塊/ComponentA.vue中lang 特性爲langxxx的塊
test: /\.langxxx$/,
loader: require.resolve('./docs-loader.js')
},
]
}
}
現在我們可以在運行時訪問被導入組件的 <docs> 塊內容了。
<!-- ComponentB.vue -->
<template>
<div>Hello</div>
</template>
<docs>
This is the documentation for component B.
</docs>
<xxxx lang="langxxx">
This is langModule。
</xxxx>
<div lang="langxxx">
This is langModule div。
</div>
<!-- ComponentA.vue -->
<template>
<div>
<ComponentB/>
<p>{{ docs }}</p><!-- This is langModule div。 -->
</div>
</template>
<script>
import ComponentB from './ComponentB.vue';
export default {
components: { ComponentB },
data () {
return {
docs: ComponentB.__docs
}
}
}
</script>
10.CSS 提取
請只在生產環境
下使用 CSS 提取,這將便於你在開發環境下進行熱重載
。
// webpack 4
// npm install -D mini-css-extract-plugin
// webpack.config.js
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// 其它選項...
module: {
rules: [
// ... 忽略其它規則
{
test: /\.css$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins: [
// ... 忽略 vue-loader 插件
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
}
// webpack 3
// npm install -D extract-text-webpack-plugin
// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
// 其它選項...
module: {
rules: [
// ...其它規則忽略
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
use: 'css-loader',
fallback: 'vue-style-loader'
})
}
]
},
plugins: [
// ...vue-loader 插件忽略
new ExtractTextPlugin("style.css")
]
}
11.代碼校驗 (Linting)
官方的 eslint-plugin-vue 同時支持在 Vue 單文件組件的模板和腳本部分的代碼校驗(就是eslint對vue語法的規則擴展,有了這個可以校驗vue語法規則)。
請確認在你的 ESLint 配置文件中使用該插件要導入的配置:
// .eslintrc.js
module.exports = {
extends: [
"plugin:vue/essential"
]
}
命令行中立即校驗修復文件:
eslint --fix --ext .js,.vue src1 --ext src2,
eslint-loder
請確保它是作爲一個 pre-loader 運用的:
// webpack.config.js
module.exports = {
// ... 其它選項
module: {
rules: [
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/
}
]
}
}
stylelint
yarn add -D stylelint stylelint-webpack-plugin postcss-styl
[email protected] Expected version “^8.10.0 || >=11.10.1”
stylelint 支持在 Vue 單文件組件的樣式部分的代碼校驗。
接下來從命令行運行:
stylelint MyComponent.vue
另一個選項是使用 stylelint-webpack-plugin:
npm install -D stylelint-webpack-plugin
請確保它是作爲一個插件運用的:
//package.json
"stylelint": {
"rules": {
"block-no-empty": null,
"color-no-invalid-hex": true,
"comment-empty-line-before": [
"always",
{
"ignore": [
"stylelint-commands",
"after-comment"
]
}
],
"declaration-colon-space-after": "always",
"indentation": [
"tab",
{
"except": [
"value"
]
}
],
"max-empty-lines": 2,
"rule-empty-line-before": [
"always",
{
"except": [
"first-nested"
],
"ignore": [
"after-comment"
]
}
],
"unit-whitelist": [
"em",
"rem",
"%",
"s"
]
}
}
// webpack.config.js
const StyleLintPlugin = require('stylelint-webpack-plugin');
module.exports = {
// ... 其它選項
plugins: [
new StyleLintPlugin({
files: ['**/*.{vue,htm,html,css,sss,less,scss,sass}'],
})
]
}
12.單文件組件規範
語言塊
模板
每個 .vue 文件最多包含一個 <template> 塊。
內容將被提取並傳遞給 vue-template-compiler 爲字符串,預處理爲 JavaScript 渲染函數,並最終注入到從 <script> 導出的組件中。
腳本
每個 .vue 文件最多包含一個 <script> 塊。
這個腳本會作爲一個 ES Module 來執行。
它的默認導出應該是一個 Vue.js 的組件選項對象。也可以導出由 Vue.extend() 創建的擴展對象,但是普通對象是更好的選擇。
任何匹配 .js 文件 (或通過它的 lang 特性指定的擴展名) 的 webpack 規則都將會運用到這個 <script> 塊的內容中。
樣式
默認匹配:/.css$/。
一個 .vue 文件可以包含多個 <style> 標籤。
<style> 標籤可以有 scoped 或者 module 屬性 (查看 scoped CSS和 CSS Modules) 以幫助你將樣式封裝到當前組件。具有不同封裝模式的多個 <style> 標籤可以在同一個組件中混合使用。
任何匹配 .css 文件 (或通過它的 lang 特性指定的擴展名) 的 webpack 規則都將會運用到這個 <style> 塊的內容中。
Src 導入
如果喜歡把 .vue 文件分隔到多個文件中,你可以通過 src 屬性導入外部文件:
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>
需要注意的是 src 導入遵循和 webpack 模塊請求相同的路徑解析規則,這意味着:
相對路徑需要以 ./ 開始
你可以從 NPM 依賴中導入資源:
<!-- import a file from the installed "todomvc-app-css" npm package -->
<style src="todomvc-app-css/index.css">
在自定義塊上同樣支持 src 導入,例如:
<unit-test src="./unit-test.js">
</unit-test>
13.其他
樣式注入
現在客戶端的樣式注入會在最前面注入所有的樣式以確保開發模式和提取模式下行爲的一致性。
注意它們注入的順序是不能保證的,所以你撰寫的 CSS 應該避免依賴插入的順序。
從依賴中導入單文件組件
exclude: /node_modules/ 在運用於 .js 文件的 JS 轉譯規則 (例如 babel-loader) 中是蠻常見的。如果你導入一個 node_modules 內的 Vue 單文件組件,它的 <script> 部分在轉譯時將會被排除在外。
爲了確保 JS 的轉譯應用到 node_modules 的 Vue 單文件組件,你需要通過使用一個排除函數將它們加入白名單:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
)
}
14.vueloader選項
//webpack
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
xxx
}
},
prettify
類型:boolean
默認值:true
在開發環境下,我們默認使用 prettier 格式化編譯後的模板渲染代碼,以方便調試。
exposeFilename
類型:boolean
默認值:false
在非生產環境下,vue-loader 會爲組件注入一個 __file 屬性以提升調試體驗。如果一個組件沒有 name 屬性,Vue 會通過 __file 字段進行推斷,並用於控制檯警告中的展示。
這個屬性在生產環境構建時會被去掉。但如果你在開發一個組件庫並且煩於爲每個組件設置 name,你可能還會想使用它。這時可以把這個選項打開。
cacheDirectory / cacheIdentifier
類型:string
默認值:undefined
當這兩個選項同時被設置時,開啓基於文件系統的模板編譯緩存 (需要在工程裏安裝 cache-loader)。
注意
在內部,vue-loader 和 cache-loader 之間的交互使用了 loader 的內聯 import 語法,!
將會被認爲是不同 loaders 之間的分隔符,所以請確保你的 cacheDirectory 路徑中不包含 !。
hotReload
類型:boolean
默認值:在開發環境下是 true,在生產環境下或 webpack 配置中有 target: ‘node’ 的時候是 false。
允許的值:false (true 會強制熱重載,即便是生產環境或 target: ‘node’ 時)
是否使用 webpack 的模塊熱替換在瀏覽器中應用變更而不重載整個頁面。 用這個選項 (值設爲 false) 在開發環境下關閉熱重載特性。
productionMode
類型:boolean
默認值:process.env.NODE_ENV === ‘production’
強制指定爲生產環境,即禁止 loader 注入只在開發環境有效的代碼 (例如 hot-reload 相關的代碼)。
compiler
類型:VueTemplateCompiler
默認值:require(‘vue-template-compiler’)
覆寫用來編譯單文件組件中<template> 塊的默認編譯器。
transformAssetUrls
類型:{ [tag: string]: string | Array<string> }
默認值:
{
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href']
}
在模板編譯過程中,編譯器可以將某些特性轉換爲 require 調用,例如 src 中的 URL。因此這些目標資源可以被 webpack 處理。例如 <img src="./foo.png"> 會找到你文件系統中的 ./foo.png 並將其作爲一個依賴包含在你的包裏。