# Loader
Webpack 本身只能處理 JavaScript 模塊,如果要處理其他類型的文件,就需要使用 loader 進行轉換。
Loader 可以理解為是模塊和資源的轉換器,它本身是一個函數,接受源文件作為參數,返回轉換的結果。這樣,我們就可以通過 `require` 來加載任何類型的模塊或文件,比如 CoffeeScript、 JSX、 LESS 或圖片。
先來看看 loader 有哪些特性?
- Loader 可以通過管道方式鏈式調用,每個 loader 可以把資源轉換成任意格式并傳遞給下一個 loader ,但是最后一個 loader 必須返回 JavaScript。
- Loader 可以同步或異步執行。
- Loader 運行在 node.js 環境中,所以可以做任何可能的事情。
- Loader 可以接受參數,以此來傳遞配置項給 loader。
- Loader 可以通過文件擴展名(或正則表達式)綁定給不同類型的文件。
- Loader 可以通過 `npm` 發布和安裝。
- 除了通過 `package.json` 的 `main` 指定,通常的模塊也可以導出一個 loader 來使用。
- Loader 可以訪問配置。
- 插件可以讓 loader 擁有更多特性。
- Loader 可以分發出附加的任意文件。
Loader 本身也是運行在 node.js 環境中的 JavaScript 模塊,它通常會返回一個函數。大多數情況下,我們通過 npm 來管理 loader,但是你也可以在項目中自己寫 loader 模塊。
按照慣例,而非必須,loader 一般以 `xxx-loader` 的方式命名,`xxx` 代表了這個 loader 要做的轉換功能,比如 `json-loader`。
在引用 loader 的時候可以使用全名 `json-loader`,或者使用短名 `json`。這個命名規則和搜索優先級順序在 webpack 的 `resolveLoader.moduleTemplates` api 中定義。
```
Default: ["*-webpack-loader", "*-web-loader", "*-loader", "*"]
```
Loader 可以在 `require()` 引用模塊的時候添加,也可以在 webpack 全局配置中進行綁定,還可以通過命令行的方式使用。
接上一節的例子,我們要在頁面中引入一個 CSS 文件 style.css,首頁將 style.css 也看成是一個模塊,然后用 `css-loader` 來讀取它,再用 `style-loader` 把它插入到頁面中。
```css
/* style.css */
body { background: yellow; }
```
修改 entry.js:
```js
require("!style-loader!css-loader!./style.css") // 載入 style.css
document.write('It works.')
document.write(require('./module.js'))
```
安裝 loader:
```bash
npm install css-loader style-loader
```
重新編譯打包,刷新頁面,就可以看到黃色的頁面背景了。
如果每次 `require` CSS 文件的時候都要寫 loader 前綴,是一件很繁瑣的事情。我們可以根據模塊類型(擴展名)來自動綁定需要的 loader。
將 entry.js 中的 `require("!style!css!./style.css")` 修改為 `require("./style.css")` ,然后執行:
```bash
$ webpack entry.js bundle.js --module-bind 'css=style-loader!css-loader'
# 有些環境下可能需要使用雙引號
$ webpack entry.js bundle.js --module-bind "css=style-loader!css-loader"
```
顯然,這兩種使用 loader 的方式,效果是一樣的。