手动实现一个Webpack的Loader

393 阅读1分钟

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

Webpack的构建流程

图片.png

Loader的作用

Webpack 是在 node 下运行的,只能识别 .js.json 格式的文件,如果碰到其他后缀名的文件,Webpack 不能直接进行解析,因此在编译阶段就需要各种 Loader 去“翻译”对应的模块内容,再找到该模块依赖的模块,然后递归的进行编译处理。

在原则上 Loader 应该遵守单一职责,也就是说每个 Loader 只做一件事,只关心输入和输出。因此一个需要“翻译”的模块或者文件可能需要经过链式的调用多个 Lodaer 才能使用。

Loader的基础

一个webpack.config.js配置,如何使用Loader

module.exports = {
  entry: {
    app: './index.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    rules: 
      {
        test: /\.css$/, // 正则匹配以.css为后缀的文件
        use: ['style-loader', 'css-loader', 'postcss-loader'] // 链式调用loader
      }
      ...
    ]
  }
}
  • Loader 中使用的是“洋葱模型”,也就是说 Loader 的执行顺序是从右到左的,因此如果要解析 postcss,需要把 postcss-loader 放在最后面,转换成 css,然后传给 css-loader 转为 style,最后再传给 style-loader 图片.png

  • 一个 Loader 需要导出一个函数,这个导出的函数的工作就是获得处理前的原内容,对原内容执行处理后,返回处理后的内容。深入浅出Webpack

module.exports = function(source) {
  // source 为 compiler 传递给 Loader 的一个文件的原内容
  // 该函数需要返回处理后的内容,这里简单起见,直接把原内容返回了,相当于该 Loader 没有做任何转换
  return source;
};

手写一个Loader

知道了基本概念以后,就可以手动来实现一个。这里举例做一个在文件顶部添加注释的 Loader

  • 准备工作
  1. webpack.config.js 中添加这句,webpack打包默认进行代码压缩,会清除注释
  optimization: {
    minimize: false
  },
  1. 安装 loader-utils 依赖,注意版本是 2.x,是loader的工具包,可以获取配置的参数等信息
  • 新建一个自己的 Loader
const loaderUtils = require('loader-utils')

module.exports = function(context) {
  console.log('-------authLoader--------')
  const { sign } = loaderUtils.getOptions(this) // 获取配置的参数
  // 把签名拼上原数据并返回
  return (`/**
    Author: ${sign}
  **/ 
  ${context}`)
}
  • webpack.config.js 中使用自己的 Loader
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            // 找到loader所在的路径
            loader: path.resolve(__dirname, './loader/authLoader.js'), 
            // loader-utils可以获取这里的配置信息
            options: {
              sign: '味精王'
            }
          }
        ],
      },
    ]
  },
  • 执行 webpack 命令可以看到编译完成的文件成功加上了注释

图片.png

  • end