从零开始学习webpack5.x(三)

217 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战 」。

前面我们了解了webpack的outputentry。但是webpack自带的能力只能处理jsjson文件,要想处理其他文件,那么就必须要用到loader
接下来继续了解一下webpack如何使用loader处理js,json以外的文件的。

Loader

上面我们也提到loader是用来处理jsjson之外的文件,将他们转换为有效的模块。那么接下来就看一下loader是如何工作的。

使用loader

使用loader有两种方式:

  1. 配置方式:在webpack配置文件中定义loader,例如在配置文件中配置解析css的loader如下:
    // webpack.config.js
    module.exports = {
      mode: 'development',
      entry: getEntry,
      output: {
        filename: '[name].bundle.js',
        chunkLoadingGlobal: 'var test1 = 111',
      },
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
              { loader: 'style-loader' },
              { loader: 'css-loader' }
            ],
          },
        ],
      },
    };
    
    上面代码中,module字段作用是决定webpack在项目中如何处理不同类型的模块。[module完整配置]
    test用于匹配对应文件,他可以是一个正则表达式,也可以是字符串。
    use表示匹配后的文件使用以下loader,注意一点:loader的执行顺序是从下往上执行。
  2. 内联方式:在每个文件中import
    import Styles from 'style-loader!css-loader?modules!./styles.css';
    

编写一个loader

介绍了loader如何使用,那么接下来介绍一下如何编写一个loader。

  • 例如:编写一个loader,匹配所有的js文件并且注入代码到文件中。
// entry.js
function test1() {
  console.log('test1');
  console.log(inject);
}
test1();

// entry1.js
function test2() {
  console.log('test2');
  console.log(inject);
}
test2();

// loader/inject.js
module.exports = function (source) {
  console.log(source);
  return `
    var inject = 'inject code';
    ${source}
  `;
};


// webpack.config.js
const path = require('path')
module.exports = {
  mode: 'production',
  entry: {
    app: path.resolve(__dirname, 'src', 'entry.js'),
    lib: path.resolve(__dirname, 'src', 'entry1.js'),
  },
  output: {
    filename: '[name].bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [{ loader: path.resolve(__dirname, 'loader', 'inject') }],
      },
    ],
  },
};

执行webpack后输出

// app.bundle.js
console.log("test1"),console.log("inject code");

// lib.bundle.js
console.log("test2"),console.log("inject code");
  • 上面代码可以看到, 我们在loader中注入了一个值为inject code的变量,打包后变量都注入到了所有test匹配到的文件中。
  • loader函数需要接收一个参数,该参数为匹配到的文件以字符串形式输出,在拿到文件数据后,我们就可以针对数据进行修改或者扩展,最后将处理后的数据return出去。
  • 如果存在多个loader,loader会从下往上执行,上层的loader接收到的数据是下层loader处理后的数据。

loader特性

接下来了解一下loader的特性,根据特性我们可以写一些更加复杂的loader。

  • 链式调用,其实就是上文提到的loader从下往上执行
  • loader的方法可以是同步,也可以是异步的
  • loader运行在node.js中,可以执行任何操作,包括且不限于一些文件I/O操作,对操作系统进行操作,进程创建操作。

小结

本节主要讲了webpack基本配置中的loader

  • loader是用于处理webpack自身不能处理的文件的,理论上通过编写loader可以处理所有文件。
  • loader是一个函数,入参是一个匹配到的文件的字符串,输出的是处理后的数据(字符串)。
  • loader具有链式调用;同步/异步调用;在node中执行,可以进行任何操作的特性。

文章是从零开始学习webpack系列的第三篇,其他章节可以看下面👇:

从零开始学习webpack5.x(一)
从零开始学习webpack5.x(二)
从零开始学习webpack5.x(三)
从零开始学习webpack5.x(四)
从零开始学习webpack5.x(五)
从零开始学习webpack5.x(六)