webpack 实现 BannerWebpackPlugin

文章介绍了如何使用BannerWebpackPlugin这个自定义插件,在Webpack打包过程中给JS和CSS文件头部添加作者注释。首先,文章列出了项目的目录结构和所需依赖,然后展示了src/index.js和webpack.config.js的配置,包括MiniCssExtractPlugin的使用。接着,详细讲解了BannerWebpackPlugin插件的实现,通过schema-utils进行选项校验,并在emit钩子中处理文件。最后,验证了插件的执行效果并提供了源码链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BannerWebpackPlugin 插件用于给打包产物头部添加注释文本

准备工作

npm i webpack webpack-cli

创建如下项目目录

├── plugins
├── src
│   │── a.txt
│   │── index.css
│   │── index.js
│   └──webpack.png
├── package.json
├── package-lock.json
└── webpack.config.js

代码实现

src/index.js

import txt from './a.txt';
import './index.css';
import webpackPng from './webpack.png';

console.log(txt);
console.log(webpackPng);

console.log('hello BannerWebpackPlugin');

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const BannerWebpackPlugin = require('./plugin/BannerWebpackPlugin');

module.exports = {
  mode: 'production',

  output: {
    clean: true,
  },

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
      {
        test: /\.txt$/i,
        type: 'asset/source',
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin(),
    new BannerWebpackPlugin({
      author: '雁行2',
      ext: ['js', 'css'],
    }),
  ],
};

plugin/BannerWebpackPlugin.js

const { validate } = require('schema-utils');

const schema = {
  type: 'object',
  properties: {
    author: {
      type: 'string',
    },
    ext: {
      type: 'array',
    },
  },
  additionalProperties: false, // 是否允许不存在的选项传入
};

class BannerWebpackPlugin {
  constructor(options = {}) {
    // 校验插件options
    validate(schema, options, {
      name: 'BannerWebpackPlugin',
      baseDataPath: 'options',
    });
    this.bannerExt = options.ext || ['js'];
    this.author = options.author;
  }

  apply(compiler) {
    // 绑定到 “emit” 钩子,在新的打包产物输出前进行
    compiler.hooks.emit.tapAsync('BannerWebpackPlugin', (compilation, callback) => {
      // 获取输出文件目录
      const { assets } = compilation;
      const paths = Object.keys(assets).filter((filePath) => {
        const arr = filePath.split('.');
        const ext = arr[arr.length - 1];
        return this.bannerExt.includes(ext);
      });
      console.log('paths', paths);

      paths.forEach((filePath) => {
        const asset = assets[filePath];
        const source = `
/*
  Author:${this.author}
*/
${asset.source()}
`;

        // 向 compilation 添加新的资源,使用`compilation.emitAsset`,但此处为已有资源,所以使用`compilation.assets`覆盖资源
        // 覆盖资源
        compilation.assets[filePath] = {
          // 资源内容
          source() {
            return source;
          },
          // 资源大小
          size() {
            return source.length;
          },
        };
      });

      callback();
    });
  }
}

module.exports = BannerWebpackPlugin;

验证测试
执行 npx webpack,可以看到打包结果如下,符合期待。

在这里插入图片描述
在这里插入图片描述

源码:https://gitee.com/yanhuakang/webpack-demos/tree/master/proficient/step_8-BannerWebpackPlugin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__畫戟__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值