CSS-LOADER配置詳解

qq20004604發表於2017-12-04

CSS-LOADER配置詳解

前注:

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

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

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

1、概述

對於一般的css檔案,我們需要動用三個loader(是不是覺得好麻煩);

1、css-loader

先附上官網文件(中文)的連結:css-loader文件

不過說實話,這個官方文件講的很糟糕,看的人一臉懵逼。

css-loader主要用於處理圖片路徑(其實也包括例如匯入css檔案的路徑),並且會將css樣式打包進js檔案中(以模組的形式打包匯入);

但問題在於,他不會將這些程式碼插入html中,因此還需要通過例如style-loader來實現將打包好的css程式碼插入html檔案中。

2、style-loader

同樣先附上官網文件(中文)的連結:style-loader文件

基本用法:

用於將 css-loader 打包好的css模組,插入到html檔案中,變成一個 <style>標籤;

3、file-loader

file-loader文件

基本用法:

用於處理各種資原始檔,一般是圖片,不然圖片是沒辦法被同時打包的。

2、css-loader配置詳解

先吐槽一波,中文文件裡的說明,真的是描述的一點都不清楚。

2.1、root

名稱 型別 預設值 描述
root {String} / 解析 URL 的路徑,以 / 開頭的 URL 不會被轉譯

官方文件裡對這個解釋不夠嚴謹。

首先,假如不設定設個屬性,如果理解為,以 / 開頭的url不會被轉譯,從結果來看,也不算錯;

然而,假如設定這個屬性的話,那麼就不一樣了。

在面對圖片路徑時,這個屬性有三種情況:

  1. 當不設定這個屬性的時候,css-loader不會去解析以/開頭的圖片路徑,也不會報錯;
  2. 當設定這個屬性的時候,即使你設定其值為預設值 /css-loader也會去嘗試解析這個路徑,如果找不到對應的圖片,會報錯;
  3. 當設定這個屬性的值為非預設值,和【2】中的行為是一樣的,css-loader去嘗試解析這個路徑,如果找到圖片,則正常解析,找不到,會報錯;

當設定這個屬性時,是指,當url以 ``/``為開頭時,到底去找哪裡的資料夾作為解析以 ``/``為開頭的url路徑的檔案;

當面對css檔案路徑時,即在css檔案裡,通過 @import 引入css檔案時,這個是不對css檔案的路徑生效的(即使找不到,也不會報錯)。

示例:

檔案樹:

根目錄
|-- src
| |-- app.js
| |-- src
|   |-- logo.png
|
|-- static
| |-- abc.png
|
|-- webpack.config.js
複製程式碼

那麼在 webpack.config.js 裡配置的時候,應該這麼寫:root: __dirname + '/static/'

__dirname 表示根目錄的絕對路徑。假如根目錄的路徑是 D:/abc/def,那麼 __dirname 就表示 D:/abc/def ,而 __dirname + '/static/ 則表示 D:/abc/def/static

這就是告訴 css-loader ,遇見 / 開頭的url路徑,你應該去 D:/abc/def/static 這個路徑下去找檔案。

2.2、

名稱 型別 預設值 描述
url {Boolean} true 啟用/禁用 url() 處理

首先,我們已知,css-loader 正常會解析css屬性裡的圖片url路徑,例如 background: url('/logo.png') 裡面的值。

那麼,假如某圖片不在你的工程裡,而是在伺服器上。

而你是可以預知打包後的html檔案和這個圖片的相對路徑關係,你就可以直接寫那個時候的路徑,並將url設定為false。

但是,如果設定為false,那麼所有url都不會進行轉義了(也不會觸發file-loader),自然也不會報錯(即使圖片不存在)。

示例:

假如打包後,上傳到伺服器的目錄為:

dist
|-- app.js
|-- logo.png
複製程式碼

那麼你如果想引用 logo.png ,那麼把 url 設定為 false 之後,然後路徑這麼寫就行了 background: url('./logo.png')

2.3、alias

名稱 型別 預設值 描述
alias {Object} {} 建立別名更容易匯入一些模組

說實話我自己搗鼓了半天也沒徹底搞明白其原理,但是琢磨出來一些用法:

1、對圖片路徑生效

假如檔案結構:

根目錄
|--static
|  |-- logo.png
|-- webpack.config.js
複製程式碼

解釋:

  1. 已知: 圖片放在 /static 目錄下;
  2. 已知:不確認css檔案放在哪裡(因為模組化,方便移動,所以可能更改模組的目錄結構);
  3. 需求:我想要確保我的css檔案必然能引用到這個圖片,即使更改模組的檔案路徑,也不影響(不需要我二次去修改);
  4. 行動:那麼新增 css-loader 的屬性,設定如下:alias: {'@': __dirname + '/static/'} ;
  5. 行動:在css檔案裡,圖片如下引用 background: url(~@/logo.png)
  6. 結果:我就可以確保必然css檔案必然能引用到這個圖片了;
  7. 注意: @ 前要加 ~webpack 識別(~webpack 負責識別,認為是根目錄,而 @css-loader 負責);

2、對 @import 引入的css檔案無效;

假如檔案結構:

根目錄
|--static
|  |-- style.css
|  |-- foo.css
|-- webpack.config.js
複製程式碼

解釋:

  1. 檔案目錄結構如上;
  2. style.css 如果通過 @import '~@/foo.css' 來匯入;
  3. 即使在 webpack.config.js 裡這麼設定 alias: {'@': __dirname + '/src/style/'} 也是沒有用的;

3、解決場景:

這個可以應用的場景挺多,不過現在很多是通過webpack的別名通用配置來解決

  1. css檔案和圖片檔案分離;
  2. 也可以分類擺放圖片(例如@開頭的是風景類圖片,peopel開頭的是人物圖片);
  3. 記得在別名之前加一個波浪線~讓webpack識別,否則無法正常工作;

2.4、import

名稱 型別 預設值 描述
import {Boolean} true 啟用/禁用 @import 處理
  1. 假如你通過@import匯入的是某個打包後工程所在位置的css檔案;
  2. 即該檔案不在打包前的工程裡(例如CDN);
  3. 那麼這個就有用;
  4. 表現效果@import導進來的css沒有被打包,只是單純的引入了(該@import程式碼被直接放在style標籤裡);
  5. 你可以檢視dist/index.html的style標籤來深刻了解;

這裡給一個簡單的示例:

webpack打包前:

// foo.css
@import 'http://abc.com/m.css'
複製程式碼

webpack打包後:

// html檔案(假設使用了style-loader把css通過style標籤插入)
<style>
@import 'http://abc.com/m.css'
</style>
複製程式碼

2.5、minimize

名稱 型別 預設值 描述
minimize {Boolean|Object} false 啟用/禁用 壓縮
  1. 這個很好理解,原本寫css檔案的時候,我們各種換行空格,這個改為true之後,換行和空格就去掉了;

  2. 一般開發的時候,取環境變數,當環境變數為生產環境的時候,設定為true;開發環境的時候,設定為false;

  3. 關於生產環境的配置,可以檢視參考示例,搜尋 minimize 即可;

壓縮前程式碼:

* {
    margin: 0;
    border: 0;
    padding: 0;
}

.box {
    border-radius: 150px;
}
複製程式碼

壓縮後程式碼:

*{margin:0;border:0;padding:0}.box{border-radius:150px}
複製程式碼

2.6、sourceMap

名稱 型別 預設值 描述
sourceMap {Boolean} false 啟用/禁用 Sourcemap

  1. minimize 設定為 true 後,css程式碼被壓縮了,那麼如果我們要除錯的話就很麻煩;
  2. sourceMap 設定為 true 後,通過Chrome控制檯的 Sources 標籤,在左邊欄上面選 Sources ,可以在樹結構的 (no domain) 裡,檢視到壓縮後和壓縮前的CSS程式碼;
  3. 即使 minimize 沒有設定為 true (不壓縮),由於css程式碼被扔到了js裡,因此也是無法直接檢視我們寫的css程式碼的;
  4. 但是 sourceMap 設定為true後,就可以通過【2】中描述的途徑來檢視我們寫的css程式碼;

啟用 sourceMap 壓縮前的程式碼:

https://github.com/qq20004604/webpack-study/blob/master/5%E3%80%81Loader/css_loader/01.png

啟用 sourceMap 壓縮後的程式碼:

https://github.com/qq20004604/webpack-study/blob/master/5%E3%80%81Loader/css_loader/02.png

2.7、importLoaders

名稱 型別 預設值 描述
importLoaders {Number} {Number} 在 css-loader 前應用的 loader 的數量

說實話,加不加這個,感覺沒啥區別(我還專門研究了一波postcss和autoprefixer讓他生效。

見我關於postcss的配置,為了正常執行,我在專案裡webpack把這個註釋掉了,可以取消掉註釋 // importLoaders: 0 // 感覺沒什麼用

如果有見解,歡迎指正

2.8、modules等

名稱 型別 預設值 描述 說明
modules {Boolean} false 啟用/禁用 CSS 模組 1、初步理解:這個相當於把css視為模組。例如我有一個css檔案 foo.css ,然後裡面有一個類 .bar,我可以在js檔案裡通過 import foo from './foo.css'匯入這個css檔案;

2、在打包後,foo.css裡的類 .bar 會變成具有唯一性的一個字串(舉個例子假設他變成了abcdefg);

3、假如我在html裡使用的是class='bar',那麼顯然是無法正常生效的(bar被轉為了abcdefg);

4、那麼我可以使用變數foo.bar(在js這裡,這是一個變數),賦給原本使用class='bar'的這個DOM節點;

5、由於是變數,所以他的值事實上已經被css-loader轉為了abcdefg,可以正常執行了;

6、推薦阮一峰的部落格CSS Modules 用法教程
camelCase {Boolean|String} false 以駝峰化式命名匯出類名 1、這個需要結合modules來看,在modules設定為true時,我們可以通過變數名來獲取更名後的css類名;

2、但我們寫css類名的時候,一般是例如foo-bar這種寫法,在js裡顯然不合適;

3、因此把這個啟用為true,我們就可以使用fooBar這種駝峰式寫法了,方便js引用;
localIdentName {String} [hash:base64] 配置生成的識別符號(ident) 1、這個也是跟modules相關的,用於對原本混算複雜不具有可讀性的類名,進行重新命名;

2、我覺得這個文章講這個比較好,你真的知道 css-loader 怎麼用嗎?,搜尋關鍵詞:localIdentName

這三個是一起使用的的,見表格內容吧。

3、專案地址

github.com/qq20004604/… ,請 Starfork 到本地後,注意相關配置。