VUE-LOADER配置簡述
前注:
文件全文請檢視 根目錄的文件說明。
如果可以,請給本專案加【Star】和【Fork】持續關注。
有疑義請點選這裡,發【Issues】。
DEMO地址
0、使用說明
首先你得會用 Vue.js,不然可能對本文部分內容無法理解
安裝:
npm install
複製程式碼
執行:
// 開發模式(推薦使用這個)
npm run dev
// 普通模式(需要執行後手動重新整理頁面)
npm run test
複製程式碼
單獨安裝 Vue-loader:
- 首先要有 Vue;
- 其次解析 vue 檔案還要
vue-template-compiler
; - 解析 css 內容當然還要
css-loader
,以及配套的style-loader
。
npm i --save vue
npm i --save vue-loader
npm i --save vue-template-compiler
npm i --save css-loader
npm i --save style-loader
複製程式碼
通過以上安裝,至少可以開始使用了
1、概述
簡單來說,vue-loader
就是處理 .vue
檔案的。
本文除了涉及到 webpack 中 vue-loader 的使用方法外,還包括 .vue
檔案的一些獨有使用方法。
但單獨一個 vue-loader
並不能解決問題,因此還需要一些其他的東西。
【1】 vue-template-compiler
:關於他的作用,根據 readme.md
檔案中所介紹的:
This package can be used to pre-compile Vue 2.0 templates into render functions to avoid runtime-compilation overhead and CSP restrictions. You will only need it if you are writing build tools with very specific needs. In most cases you should be using vue-loader or vueify instead, both of which use this package internally.
大致意思就是說,這個用於把 Vue 的模板檔案(應該指.vue)預編譯為渲染函式,避免執行時再編譯帶來的效能開銷。
就是說 .vue
檔案,在 js 執行時再拆開,然後使用是會消耗很多效能的。
一般情況下,不需要單獨用他,用 vue-loader
就行了(但是你卻需要單獨安裝他,安裝 vue-loader
時是不帶這個的)。
【2】 解析 css 內容當然還要 css-loader
,以及配套的 style-loader
。
根據你的需要,可能還需要更多,但一般情況下,只需要你單獨安裝好這 2 個就行了(安裝vue-laoder
不會附帶安裝這 2 個)。
2、配置
2.1、預設配置
預設配置下,vue-loader只具備基礎功能:
【1】.vue
檔案拆解:
- 將
.vue
檔案拆解成可用的三部分,然後扔到打包後的.js
檔案;
【2】HMR功能:
- 預設支援 HMR 功能(DEMO裡已預置,執行
npm run dev
可以通過使用); - 如果對規則感興趣的,請參照官網說明:熱過載 vue-loader
【3】css區域性作用域:
- 支援元件的 css 使用區域性作用域,在 style 標籤新增
scoped
即可。 - 例如:
<style scoped></style>
,這樣的話,該元件內的樣式只會對該元件生效(原理是給對應的元件加指定屬性名,然後 css 選擇器裡也加上屬性選擇器); - 支援在元件使用 scoped 屬性的情況下,讓某些樣式影響子元素。方法是使用
/deep/
或>>>
關鍵字,該關鍵字前的選擇器,會加區域性作用域;該關鍵字後面的選擇器,不會加區域性作用域。例如.app /deep/ .child
會被編譯為:··.app[data-v-04c2046b] .child··
【4】CSS Modules
- 簡單來說,就是可以將
<style></style>
標籤內的東西,加了module
屬性後,可以直接在 vue 元件後,獲取重新命名後的類名。 - 可以用作模擬 css 作用域的解決方案。
- 詳細說明見本文【3.1、CSS Modules】
需要額外配置才有的功能:
【1】es6程式碼轉換成es5:
- 通過配置,可以將
<script>
裡的 es6程式碼。 - 指例如 created 這個函式裡,使用的 es6 程式碼。
- 而 created 本身即可以用
created: function(){}
,也可以用created()
,都能正常識別),自動通過 babel 編譯為 es5 的程式碼; - 參照【2.4、使用babel-loader】
【2】圖片url
- 載入圖片,路徑是會被正常處理的,但是僅僅只有路徑是不行的。
- 就像 css-loader 也能處理圖片的路徑,但依然需要 file-loader 來處理圖片一樣。
- 參照【2.5、圖片】
【3】css 前處理器
- 只需要安裝對應的 css 前處理器的 loader,以及在
.vue
檔案裡標識一下,就能被vue-loader
所使用,無需額外在 webpack.config.js 裡配置。 - 使用方法見【2.3、使用css前處理器】
【4】自帶 postcss
- 檢視
vue-loader
的 package.json, 會發現在dependencies
裡有postcss
。 - 注意不是
postcss-loader
,loader 是給 webpack 用的,而postcss 是類似 less、sass 等,更全面的 css 處理器(不止是前處理器)。 - 但是假如我們需要
postcss-loader
的功能,那麼是不需要額外安裝postcss-loader
的。 - 詳細使用說明參照下面【2.2、使用 postcss 的功能】
2.2、使用 postcss 的功能
之前講過postcss-loader,點選檢視。
假如我們需要在 vue-loader 裡,通過 postcss
新增相容性 css 字首,很簡單。
1、先安裝 autoprefixer
,
npm install autoprefixer --save
複製程式碼
2、相容性外掛的配置,假如我們在 postcss.config.js 裡配置,如下寫就行了(跟使用 postcss-loader
方法是一樣的)
let autoprefixer = require('autoprefixer');
module.exports = {
plugins: [
autoprefixer({
browsers: [
// 加這個後可以出現額外的相容性字首
"> 0.01%"
]Z
})
]
}
複製程式碼
這就足夠了,無需其他操作。
2.3、使用css前處理器
這裡使用 less 作為示例,而 SASS 或者其他,是類似的。
首先要安裝 less-loader
:
npm i --save less-loader
複製程式碼
然後在 .vue
檔案,需要使用 less 語法的 <style>
標籤裡,新增一個屬性 lang="less"
就行。
但是,如果你使用的是 webstorm 作為 IDE,那麼 webstorm 是無法正常以 less 語法來識別這個的,因此我們還需要額外新增一個屬性 type="text/less"
。
因此給出示例程式碼(區域性作用域、less語法、支援webstorm識別):
<style scoped lang="less" type="text/less">
.child-component {
.text {
font-size: 30px;
font-weight: bold;
}
}
</style>
複製程式碼
2.4、使用babel-loader
使用 babel 很簡單,同樣,無需額外配置。
首先參照我寫的 babel-loader 這一篇內容,安裝 babel-loader 和相關的東西。
然後在專案跟目錄下新增 .babelrc
檔案,裡面的內容和 babel-loader
的配置是一樣的。
除此之外,無需其他額外配置。
2.5、圖片
引用圖片,我們還是需要使用 file-loader ,可能還需要使用 url-loader(根據需要不需要轉 base64 字串)
就假設我們需要同時使用這兩個吧,配置起來非常簡單。
先安裝 file-loader
和 url-loader
,參照 url-loader 和 file-loader。
然後配置一波圖片匹配在 webpack.config.js,就行了。
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
mimetype: 'image/png',
name: 'img/[hash].[ext]'
}
}
]
}
複製程式碼
2.6、其他
以以上幾個為例,想必大家已經瞭解了,vue-loader 本身無需特殊配置,也不需要給 .vue
檔案新增很多其他的 loader
的處理。
我們只需要安裝對應的 loader
,然後配置一下 loader 即可。
也就是說,如果要新增某個 loader
,大部分只需要安裝,不需要額外配置。
假如我們需要額外處理某些 loader,不使用 vue-loader 本身的,也是可以的。
參照官網這個說明 loaders,很簡單。
3、vue-loader 獨有功能
3.1、CSS Modules
簡單來說,就是模組化css。
如果看過我的 css-loader 這一篇的【2.8、modules等】,可能就能體會到 css-loader 的這個功能是如何在這裡實現的了。
例如,假如我在 .vue
檔案里加了以下標籤。
<!-- 呼叫方法示例:<div :class="$style.test"> -->
<style module>
.test {
border: 2px solid gold;
}
</style>
<!-- 呼叫方法示例: <div :class="foo.bar"> -->
<style module="foo">
.bar {
position: relative;
animation: move 2s linear infinite;
}
@keyframes move {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
</style>
複製程式碼
那麼編譯後,程式碼會變成以下情況:
<style type="text/css">
._1MwiT3GNpEBkInFbvenNqf_1 {
border: 2px solid gold;
}
</style>
<style type="text/css">
._2zuIotdSd4Qw4JyIOKek2x_2 {
position: relative;
animation: _1Uijvgp95FT2K79a3BqAeg_2 2s linear infinite;
}
@keyframes _1Uijvgp95FT2K79a3BqAeg_2 {
0% {
left: 0;
}
50% {
left: 100px;
}
100% {
left: 0;
}
}
</style>
複製程式碼
也就是說,加上 modules 屬性後,原本的樣式名會被重新命名,然後可以通過變數來獲取重新命名後的名字。
獲取方法如下:
【1】只有 module
屬性的 <style>
標籤中的 class 類名,通過 $style.類名
來獲取,例如: $style.test
;
【2】module
屬性被命名(例如 module="foo"
),通過 module名.類名
來獲取,例如: foo.bar
;
這個變數在對應元件中,可以通過 this.$style.test
或者 foo.bar
來獲取,
console.log(this.$style); // {test: "_1MwiT3GNpEBkInFbvenNqf_1"}
複製程式碼
4、問題和解決
4.1、引入 vue 但是不能正常執行
打包後,無法正常執行。檢視 console,有以下報錯:
You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
複製程式碼
原因可以參照這個文章Vue 2.0 升(cai)級(keng)之旅。
這裡簡單總結一下,就是預設引入的 Vue
,並不是 vue.js
,而是 vue.common.js
,而後者是執行時環境使用的。
解決方法很簡單:
【方法一】更改引入路徑:
引入的更改為:import Vue from 'vue/dist/vue.js'
【方法二】新增別名:
在 webpack.config.js 裡新增別名:
resolve: {
alias: {
'Vue': 'vue/dist/vue.js'
}
}
複製程式碼
注意,如果新增別名的話,alias 屬性的 key,需要和引入的 大小寫要保持一致。
即這裡的是大寫字母開頭的 Vue
,那麼引入的時候也應該是大寫字母開頭的:import Vue from 'Vue'
4.2、字尾名省略
一般情況下,如果要引入 child.vue
,那麼正常情況下,會使用 import child from './child.vue'
來實現
那麼假如我想省略掉字尾名,寫成 import child from './child'
,該怎麼辦?
解決辦法:
修改 webpack.config.js 中的 resolve 屬性,例如:
// 以上省略
resolve: {
extensions: ['.js', '.vue'],
//以下省略
複製程式碼
就可以無字尾名引用 .vue
結尾的檔案了,注意,如果有相同名字但不同字尾名的,有先後順序。