Webpack3之Vue-loader配置簡述

qq20004604發表於2018-01-15

VUE-LOADER配置簡述

前注:

文件全文請檢視 根目錄的文件說明

如果可以,請給本專案加【Star】和【Fork】持續關注。

有疑義請點選這裡,發【Issues】。

DEMO地址

0、使用說明

首先你得會用 Vue.js,不然可能對本文部分內容無法理解

安裝:

npm install
複製程式碼

執行:

// 開發模式(推薦使用這個)
npm run dev

// 普通模式(需要執行後手動重新整理頁面)
npm run test
複製程式碼

單獨安裝 Vue-loader:

  1. 首先要有 Vue;
  2. 其次解析 vue 檔案還要 vue-template-compiler
  3. 解析 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-loaderurl-loader,參照 url-loaderfile-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 結尾的檔案了,注意,如果有相同名字但不同字尾名的,有先後順序。

相關文章