1. 程式人生 > 實用技巧 >8-webpack之loader

8-webpack之loader

1、關於loader

在之前的例項中,主要是用 webpack 來處理 js 程式碼,並且 webpack 會自動處理 js 之間相關的依賴,


但在開發中往往不僅僅有基本的 js 程式碼處理,也需要載入 css、圖片,也包括一些高階的將 ES6、TypeScript 轉成 ES5 程式碼,

將scss、less 轉成 css,將 .jsx、.vue 檔案轉成 js 檔案等;


對於webpack本身的能力來說,對於這些轉化是不支援的,我們需要給 webpack 擴充套件對應的 loader;


loader 是 webpack 中一個非常核心的概念,webpack 可以使用 loader 來預處理檔案;


2、css-loader

(1)loader的安裝配置

通過 npm 安裝需要使用的 loader:

npm install style-loader css-loader --save-dev


style-loader :將模組的匯出作為樣式新增到 DOM 中

css-loader :解析 CSS 檔案後,使用 import 載入,並且返回 CSS 程式碼


在 webpack.config.js 中的 module關鍵字下進行配置:

module.exports = {
  …,
  module: {
    rules: [
      {
        test: /\.css$/,
        // webpack 在讀取使用的loader的過程中,是按照從右向左的順序讀取的,所以順序不能顛倒
        use: [ 'style-loader', 'css-loader' ]
      }
    ]
  }
}


3、CSS檔案的處理

專案開發過程中,我們必然需要新增很多的樣式,而樣式我們往往寫到一個單獨的檔案中;


結構如下,CSS檔案和js檔案分別有不同的目錄:


在 normal.css 中,將 body 設定為 red:

body {
    background-color: red;
}


這時,normal.css 中的樣式是不會生效的,因為我們還沒有引用它,所以 webpack 不能找到該檔案;

在入口檔案 main.js 中引用 css 檔案:

// 引用 css 檔案
require('./css/normal.css')


配置完成以後,可以使用 npm run build 命令將 css 檔案程式碼也一併打包到 bundle.js 檔案中了,此時,css 中的程式碼會生效:


4、less檔案處理

less-loader 載入和轉譯 LESS 檔案;


安裝:

npm install --save-dev less-loader less


在 css 資料夾中新建 less 檔案 special.less:

@fontSize:50px;
@fontColor:orange;

body{
  color: @fontColor;
  font-size: @fontSize;
}


配置:

{
        test: /\.less$/,
        use: [{
          loader: "style-loader", // creates style nodes from JS strings
        }, {
          loader: "css-loader" // translates CSS into CommonJS
        }, {
          loader: "less-loader", // compiles Less to CSS
        }]
      }



在 main.js 中引入 less 檔案:

// 引用 less 檔案
require('./css/special.less')
// 為了檢視 less 生效的程式碼,新增一些文字
document.writeln('<h2>你好,小鳴</h2>')


使用npm run build打包,檢視效果;


5、url-loader 和 file-loader

file-loader :將檔案傳送到輸出資料夾,並返回(相對)URL;

url-loader :像 file loader 一樣工作,但如果檔案小於限制,可以返回 data URL;


(1)url-loader

在src/img下準備兩張圖片,一張(test.jpg)小於13kb,一張(timg.jpg)大於13kb;


修改normal.css檔案,設定test.jpg為背景:

body {
  /*background-color: darkgray;*/
  background: url("../img/timg.jpg");
}


安裝 url-loader:

npm install --save-dev url-loader


修改 webpack.config.js 配置檔案,配置 url-loader:

{
  test: /\.(png|jpg|gif)$/,
  use: [{
    loader: 'url-loader',
    options: {
    limit: 13000
    }
  }]
}


打包,執行 index.html,就會發現背景圖片渲染出來了;


此時的背景圖是通過base64顯示出來的;

其實,這是limit屬性的作用,當圖片小於13kb時,對圖片進行base64編碼:


(2)、file-loader

那麼問題來了,如果圖片大於 13kb 呢?

將 background 的圖片改成 timg.jpg:

body {
    /* background-color: red; */
    background: url(../img/timg.jpg);
}

此時再打包就會報錯,這是因為大於 13kb 的圖片,會通過 file-loader 進行處理,但專案中並沒有 file-loader,所以需要安裝一下 file-loader:

npm install --save-dev file-loader


再次打包執行,會發現 dist 資料夾下多了一個圖片檔案;


但是,我們發現圖片並沒有顯示出來,這是因為圖片使用的路徑不正確,

預設情況下,webpack 會將生成的路徑直接返回給使用者,但我們整個程式是打包到了 dist 資料夾下的,所以這裡需要在路徑下再新增一個 dist/


再次打包執行,發現 timg.jpg 的背景能夠顯示出來了;


(3)修改圖片檔名稱

webpack 自動幫助我們為圖片生成了一個非常長的名字,這是一個32位 hash 值,目的是防止名字重複;

但在真實開發中,我們可能對打包的圖片名字有一定的要求,比如:將所有的圖片放在一個資料夾中,跟上圖片原來的名稱,同時也要防止重複;


所以,我們可以在 options 中新增如下選項:

  • img:檔案要打包到的資料夾
  • name:獲取圖片原來的名字,放在該位置
  • hash:8:為了防止圖片名稱衝突,依然使用 hash,但是我們只保留8位
  • ext:使用圖片原來的副檔名



再次打包,發現在 dist/img 資料夾中的圖片是按照我們預先設定的名字命名:


6、babel-loader

webpack 打包的 js 檔案中,ES6 語法並沒有轉成 ES5,那麼就意味著可能一些對 ES6 還不支援的瀏覽器沒有辦法很好的執行我們的程式碼;


如果希望將 ES6 的語法轉成 ES5,那麼就需要使用 babel;

在webpack中,直接使用 babel 對應的 loader 就可以了;


安裝babel-loader:

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015


配置 webpack.config.js 檔案:

{
        test: /\.js$/,
        // exclude: 排除
        // include: 包含
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      }


重新打包,檢視 bundle.js 檔案,發現其中的內容變成了 ES5 的語法;