Webpack 4 系列 - loaders

長跑是我個人的一種修行。我在跑步的時候,會有各種各樣的想法。其實(shí)跑步就是一個鍛煉精神強(qiáng)度的過程,不論進(jìn)入腦海的想法多么恐怖,你還是要繼續(xù)跑步,你還是要繼續(xù)做你現(xiàn)在正在做的事情,這是一種意志品質(zhì),這種意志品質(zhì)決定了你人生的意義以及高度。

webpack 雖然是一個模塊打包工具,但是這不是它唯一的功能,也不是我們使用它的唯一目的。盡管 webpack 只能理解 JavaScript,但是它可以通過使用 loaders 來擴(kuò)展功能。官方的文檔是這樣介紹它的:

Loaders can transform files from a different language (like TypeScript) to JavaScript or inline images as data URLs. Loaders even allow you to do things like import CSS files directly from your JavaScript modules!

添加 loaders

要使用 loaders,需要在 webpack.config.js 文件中聲明它們,而要聲明它們,你需要添加一個 module.rules 的屬性。

css-loader

css-loader 模塊會解析導(dǎo)入的 css 文件

$ npm install css-loader

參考下面的配置:

webpack.config.js

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
    ]
  }
}

rules
rules 屬性是一個包含了所有 loaders 的數(shù)組,這些規(guī)則會被應(yīng)用在每一個能夠匹配 test 屬性的文件上。實(shí)際上,這是一種正則表達(dá)式。

use
use 屬性聲明了對應(yīng)了這些文件所要使用的具體 loader。

將 loaders 鏈在一起

通過上面的代碼,你就可以在你的 JavaScript 代碼中引入 css 文件了。但是這樣還不足以讓 css 文件產(chǎn)生效果,我們需要一個東西來讓瀏覽器理解這些代碼。我們需要的是:style-loader

$ npm install style-loader

這樣意味著我們需要對 css 文件使用兩種不同的 loaders,你可以這樣將 loaders 連接起來。

webpack.config.js

module.export = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
     ]
  }
}

我們可以發(fā)現(xiàn),use 屬性不僅可以是單純的字符串,還可以是數(shù)組。這樣,就把 loaders 給連接起來了。值得注意的的是:在數(shù)組中的 loaders 是按照逆序執(zhí)行的

style.css

body {
  background-color: skyblue;
}

index.js

import './style.css'

通過這一系列的配置之后,整個工作的流程是這樣的:

  1. webpack 會嘗試解析 style.css 這個文件
  2. 文件名匹配了正則表達(dá)式:/\.css$/
  3. 這個文件會被 css-loader 讀取
  4. css-loader 的結(jié)果會傳遞給 style-loader
  5. 最后,style-loader 會返回一段 JavaScript 代碼

默認(rèn)情況下,輸出的整個打包文件時 ./dist/bundle.js,現(xiàn)在這個文件將會把所有生成的樣式添加到 <style> 標(biāo)簽中去,如果將 bundle.js 連接到 HTML 文件,那么運(yùn)行之后的 HTML 文件會變成這樣:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="../dist/bundle.js"></script>
  <!--這里引入了 css 文件中的樣式-->
  <style type="text/css">body {
    background-color: skyblue;
  }
  </style>
  <title>Document</title>
</head>
<body>
</body>
</html>

sass-loader

通過已有的知識,你可以很輕松地讓你的項(xiàng)目支持 sass / scss,我們需要的只是 sass-loader。

$ npm install sass-loader

你只需要將它添加到 loaders 的數(shù)組里就可以了。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  }
}

現(xiàn)在你就可以在項(xiàng)目里添加 scss 文件啦,在通過 css-loader 之前,這些文件會從 scss 編譯成 css。

給 loaders 一些參數(shù)

loaders 是可以接受一些額外的參數(shù)的,讓我們用 url-loader 來舉個例子。

$ npm install url-loader file-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 5000
            }
          },
        ]
      }
    ]
  }
}

這里需要注意,如果你想要將參數(shù)傳遞給 loaders,不能再直接使用字符串的形式將它傳遞給 use 這個屬性?,F(xiàn)在,每個 loader 是一個具有兩個屬性的對象:分別是 loader 和 options。

url-loader 會將你的圖片轉(zhuǎn)換成 base64 格式。如果你的圖片非常小,直接將它們放在你的代碼中可能更利于性能,因?yàn)檫@可以讓瀏覽器少發(fā)幾次請求。如果你的圖片很大,或許更好的做法是將它們分成多份,這樣瀏覽器可以同步的獲取它們。

這就是為什么 url-loader 這個 loader 會有 limit 這個屬性。在文件大小(單位 byte)低于指定的限制時,可以返回一個 DataURL。

Tips: 什么是 DataURL?

DataURL 給了我們一種很巧妙的將圖片“嵌入”到 HTML 中的方法。跟傳統(tǒng)的用 <img> 標(biāo)記將服務(wù)器上的圖片引用到頁面中的方式不一樣,在 DataURL 協(xié)議中,圖片被轉(zhuǎn)換成 base64 編碼的字符串形式,并存儲在 URL 中,冠以mime-type。我們可以使用 DataURL 優(yōu)化網(wǎng)站加載速度和執(zhí)行效率。

body {
  background-image: url('./big-background.png');
}
.icon {
  background-image: url('./icon.png');
}

上面的配置就會變成下面的樣子

body {
  background-image: url(ca3ebe0891c7823ff1e137d8eb5b4609.png);
}
 
.icon {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAALElEQVR4AWMYIWAU1FPLoP9AXEFI0QEi8H+YYdQyqIEaXuumRhh1DZdUMwoATlYWfwh9eYkAAAAASUVORK5CYII=);
}

使用 babel 轉(zhuǎn)譯(transpile) JavaScript

常見的 loader 還有就是 babel-loader 了。它可以使用 babel 轉(zhuǎn)譯 JavaScript 文件,這是一種使用最新版 JavaScript 來寫代碼的解決方案。它可以用來兼容以往的一些瀏覽器,也可以使用一些現(xiàn)代瀏覽器還不支持的語法特性。

$ npm install babel-loader babel-core babel-preset-env

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
};

這里我們使用了 exclude 這個屬性,這里也是一個正則表達(dá)式,如果文件的路徑與之相匹配的話,那么這個文件就不會被轉(zhuǎn)譯。

小結(jié)

這一次我們學(xué)習(xí)了 webpack 一個非常有用的特性:loaders。我們介紹了一些可以用到的 loaders,使用它們我們可以讓項(xiàng)目支持 scss,不僅如此,還知道了如何用 url-loader 處理圖片。另一個非常常用的 loader 就是 babel-loader,它用來對 javascript 進(jìn)行轉(zhuǎn)譯(還知道了轉(zhuǎn)譯的目的)。接下來,我們會更加深入 loaders,還會自己動手寫 loaders。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容