天天看點

Webpack實戰(四):教教你如何輕松搞定-預處理器(loader)

前面三節,我主要給大家分享了有關webpack的一些配置的知識點,如何打包js檔案,而如果我們遇到其他類型的資源如圖檔、css、字型font等等,我們該如何處理呢?今天會介紹預處理器(loader),它賦予了Webpack可處理不同資源類型的能力,極大豐富了其可擴充性。

如果想了解Webpack的基礎配置可以參考以下位址:

​​Webpack實戰(一):Webpack打包工具安裝及參數配置​​

​​Webpack實戰(二):webpack-dev-server的介紹與用法​​

​​Webpack實戰(三):作為前端你不得不懂的Webpack資源入口和出口的配置​​

在一個項目中,我們要面臨着各種各樣的資源,如何讓Webpack很好的處理這些資源呢?這個時候我們需要借助于預處理器(loader),loader的字面意思是裝載器,在Webpack中它的實際功能則更像是預處理器。Webpack本身隻認識JavaScript,對于其他類型的資源必須預先定義一個或多個loader對其進行轉譯,輸出為Webpack能夠接收的形式再繼續進行,是以loader做的實際上是一個預處理的工作。

loader配置

  1. loader引入

    如果我們要引入css檔案,webpack是沒法處理的,如

// common.css
body {
  font-size: 20px;
  background: #0fc;
}      
//index.js
import './common.css'      
Webpack實戰(四):教教你如何輕松搞定-預處理器(loader)

執行的結果如上圖,由此可見,Webpack是無法處理css檔案,我們需要給安裝預處理css-loader。安裝步驟如下

npm install --save-dev css-loader      

然後我們将loader 引入項目中,配置webpack.config.js配置如下:

const path = require('path')
module.exports = {
  context: path.join(__dirname, './src'),
  entry: {
    index: './index.js'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'index.js'
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [ 'css-loader'],
      },
    ],
  }
}      

與loader相關的配置都在module對象中,其中module.rules代表了子產品的處理規則。每條規則内部可以包含很多配置項,這裡我們隻使用了最重要的兩項—test和use。

  • test可接收一個正規表達式或者一個元素為正規表達式的數組,隻有正則比對上的子產品才會使用這條規則。 如以/.css$/來比對所有以.css結尾的檔案。
  • use可接收一個數組,數組包含該規則所使用的loader,也可以是字元串,對象等。

很多時候,在處理某一類資源時我們都需要使用多個loader。如,對于SCSS類型的資源來說,我們需要sass-loader來處理其文法,并将其編譯為CSS;接着再用css-loader處理CSS的各類加載文法;最後使用style-loader來将樣式字元串包裝成style标簽插入頁面。

下面引入style-loader,安裝指令如下:

npm install --save-dev style-loader      

配置代碼如下:

const path = require('path')
module.exports = {
  context: path.join(__dirname, './src'),
  entry: {
    index: './index.js'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'index.js'
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  }
}      

此時再進行打包,樣式就會生效了,應該會看到頁面中插入了一個style标簽,包含了CSS檔案的樣式,這樣我們就完成了從JS檔案加載CSS檔案的配置。

打包效果如下圖:

Webpack實戰(四):教教你如何輕松搞定-預處理器(loader)

運作效果如下圖

Webpack實戰(四):教教你如何輕松搞定-預處理器(loader)

把style-loader放在css-loader前面,這是因為在Webpack打包時是按照數組從右邊往左邊的順序将資源交給loader處理的,是以要把最後生效的放在左邊。

loader作為預處理器通常會給開發者提供一些配置項,在引入loader的時候可以通過options将它們傳入

module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 
          {
            loader: 'css-loader',
            options: {
              // 有關css-loader的配置
            }
          }
        ],
      },
    ],
  }      
  1. 其他配置

    exclude與include是用來排除或包含指定目錄下的子產品,可接收正規表達式或者字元串(檔案絕對路徑),以及由它們組成的數組

module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
        exclude: /node_modules/
      },
    ],
  }      

exclude規則内的使node_modules中的子產品不會執行這條規則。該配置項通常是必加的,否則可能拖慢整體的打包速度。

module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
        include: /src/
      },
    ],
  }      

include代表該規則隻對正則比對到的子產品生效。假如我們将include設定為工程的源碼目錄,自然而然就将node_modules等目錄排除掉了。

如果exclude 和include同時存在,則exclude權限比較高

resource與issuer可用于更加精确地确定子產品規則的作用範圍,在Webpack中,我們認為被加載子產品是resource,而加載者是issuer

: {
    rules: [
      {
        use: ['style-loader', 'css-loader'],
        resource: {
          test: /\.css$/i,
          exclude: /node_modules/
        },
        issuer: {
          test: /\.js$/i,
          exclude: /node_modules/
        }
      },
    ],
  }      

通過添加resource對象來将外層的配置包起來,區分了resource和issuer中的規則,這樣就一目了然了。

enforce用來指定一個loader的種類,隻接收“pre”或“post”兩種字元串類型的值。事實上,我們也可以不使用enforce而隻要保證loader順序是正确的即可。配置enforce主要的目的是使子產品規則更加清晰,可讀性更強,尤其是在實際工程中,配置檔案可能達到上百行的情況,難以保證各個loader都按照預想的方式工作,使用enforce可以強制指定loader的作用順序。

常用的預處理器

  1. babel-loader用來處理ES6+并将其編譯為ES5,它使我們能夠在工程中使用最新的語言特性,同時不必特别關注這些特性在不同平台的相容問題。
npm install babel-loader babel-core babel-preset-env      
  • babel-loader:它是使Babel與Webpack協同工作的子產品。
  • babel-core:顧名思義,它是Babel編譯器的核心子產品。
  • babel-preset-env:它是Babel官方推薦的預置器,可根據使用者設定的目标環境自動添加所需的插件和更新檔來編譯ES6+代碼。

    配置檔案如下:

{
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          cacheDirectory: true,
          presets: [
            [
              'env', {
                modules: false
              }
            ]
          ]
        }
      }
    }      

由于babel檔案很大沒,是以要排除node_modules|bower_components

對于babel-loader本身我們添加了cacheDirectory配置項,它會啟用緩存機制,在重複打包未改變過的子產品時防止二次編譯,同樣也會加快打包的速度

babel-loader支援從.babelrc檔案讀取Babel配置,是以可以将presets和plugins從Webpack配置檔案中提取出來,也能達到相同的效果。

  1. ts-loader

    ts-loader與babel-loader的性質類似,它是用于連接配接Webpack與Typescript的子產品,安裝指令如下:

npm install ts-loader typescript      

webapck.config.js配置如下

rules: [
  {
  test: /\.ts$/,
  use:'ts-loader' 
  }
]      
  1. html-loader

    html-loader用于将HTML檔案轉化為字元串并進行格式化,這使得我們可以把一個HTML片段通過JS加載進來。

  2. handlebars-loader

    handlebars-loader用于處理handlebars模闆,在安裝時要額外安裝handlebars。

  3. file-loader

    file-loader用于打封包件類型的資源,并傳回其publicPath。

總結

繼續閱讀