【前端必會】webpack loader 到底是什麼

語言: CN / TW / HK

概述

  1. webpack的使用中我們會遇到各種各樣的外掛、loader。
  2. webpack的功力主要體現在能理解各個外掛、loader的數量上。理解的越多功力越深
  3. loader是什麼呢?

背景

瞭解loader前,我們在來看個問題,有了前面的基礎我們還是用個簡單的樣例來說明

由於一切都是模組,我們想用js import的方式統一載入css資源

//main.js
import "./main.css";
window.addEventListener("load", function () {});
//main.css
body {
  color: aquamarine;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Webpack App</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
  </head>
  <body>
    <h1>Hello webpack splitchunks</h1>
    <button id="btn1">頁面1</button>
    <button id="btn2">頁面2</button>
  </body>
</html>

嗯,如果能這樣載入就好了,我就不需要在寫 <style>、<link> 標記了,那麼是不是這麼寫呢

好,我們來試一下

//index.js
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const config = {
  context: path.resolve(__dirname),
  mode: "production",
  optimization: {
    minimize: false,
  },
  entry: "./main.js",
  target: ["web", "es5"],
  output: {
    clean: true,
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html",
    }),
  ],
};

const compiler = webpack(config);
compiler.run((err, stats) => {
  console.log(err);
  let result = stats.toJson({
    files: true,
    assets: true,
    chunk: true,
    module: true,
    entries: true,
  })
  debugger
});

看下結果,有個錯誤,

moduleName:'./main.css'

'Module parse failed: Unexpected token (1:5)\nYou may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

這裡正是提示我們css檔案不能用import的方式載入,想要載入css檔案,你就需要loader

開始

先裝2個loader

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

新增loader配置

const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const config = {
  context: path.resolve(__dirname),
  mode: "production",
  optimization: {
    minimize: false,
  },
  entry: "./main.js",
  target: ["web", "es5"],
  output: {
    clean: true,
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

const compiler = webpack(config);
compiler.run((err, stats) => {
  console.log(err);
  let result = stats.toJson({
    files: true,
    assets: true,
    chunk: true,
    module: true,
    entries: true,
  })
  debugger
});

執行後沒有了錯誤,頁面也正常顯示了

看下生成了什麼程式碼(程式碼太多,擷取一部分)

css檔案居然被轉換成了字串,而且執行時會自動新增到 <style> 標記中

總結

  1. loader 可以讓webpack處理更多,更豐富的檔案型別,即使這個檔案並不是js檔案
  2. 有了loader的設計,webpack的應用場景強了。
  3. css-loader正是將我們的css檔案轉成了javastript的字串
  4. style-loader 則幫助我們將生成的樣式字串新增的 <style> 標記中,他倆配合的也真是挺到位。
  5. loader的設計並不侷限於樣式的這個場景,理解這兩個loader可以讓我們更深入的理解loader的設計,比如如果我想把es6語法的js檔案都轉成es5的js執行時,是不是也可以呢?
  6. loader參考: http://webpack.docschina.org/loaders/css-loader