NiceLeeのBlog 用爱发电 bilibili~

Webpack Plugin制作1-将LICENSE打包到目的文件夹

2021-10-12
nIceLee

阅读:


现在制作一个插件,它会在打包的时候将LICENSE放到目的文件夹中。

准备工作

假设node环境已经到位。
现在从零开始,一步一步实现我的小目标。

  • 搭建空白项目

    # 下面我们的一切都将在这个目录下进行
    mkdir diy-plugins-loaders
    cd diy-plugins-loaders
    # 初始化工程
    npm init
    # 安装webpack依赖
    npm i -D webpack webpack-cli
    # 新建目录
    mkdir src && mkdir build && mkdir plugins && mkdir loaders
    echo console.log('hello') >> src/index.js
    echo "this is a license" > LICENSE
    
  • 配置webpack.config.js
    再也没有比这个更简单的配置了

    const { resolve } = require('path')
    module.exports = {
      entry: resolve(__dirname, "./src/index.js"),
      output: {
          path: resolve(__dirname, "./build"),
            filename: "bundle.js"
        },
        plugins: [],
        module: {
            rules: []
        },
        mode: 'development'
    }
    
  • 添加快捷指令 修改 package.json
    "scripts": {
      "dev": "webpack --mode development",
      "build": "webpack --mode production"
    }
    
  • 好了,现在我们可以使用以下命令进行打包了
    • 开发模式: npm run dev
    • 生产模式: npm run build
  • 这个简单的工程目录如下:

    - build
    - node_modules
    - package.json
    - plugins
    - loaders
    - src
        - index.js
    - LICENSE
    

简单的分析

我们的插件要做的事情是,将传入的license文件,打包到打包目录中。
简单点说,就是用nodejs复制一个文件。

  • 现在我们关注几个事情:
    • 该如何让webpack调用我们的plugin
    • 插件该如何获取传入的文件路径
    • 插件该如何获取输出的打包路径

如何让webpack调用plugin

首先,以html-webpack-plugin为例,我们来看看是怎样使用其它的插件的

  • 下载插件
    npm i -D html-webpack-plugin

  • 在webpack.config.js中导入插件
    const HtmlWebpackPlugin = require(‘html-webpack-plugin’)

  • 在webpack.config.js中使用插件

    module.exports = {
        ...
        plugins: [
            new HtmlWebpackPlugin()
        ],
        ...
    }
    

再参考官方文档
所谓插件显然就是一个类,这个类拥有一个apply方法,大部分功能实现都在这里面进行。

现在,我们来做一个插件,这个插件什么都不做,只输出一个打印语句。
我们约定,把所有的插件代码放到plugins文件夹下。

  • 新建0.createLicense.js,内容如下:
    class CreateLicensePlugin {
      constructor(options = {}) {
      }
      apply(compiler) {
          console.log('这是一个自定义插件');
      }
    }
    module.exports = CreateLicensePlugin;
    
  • 在webpack.config.js中导入我们自己写的插件
    const CreateLicensePlugin = require(‘./plugins/0.createLicense’)

  • 在webpack.config.js中配置使用我们的插件

    module.exports = {
        ...
        plugins: [
            new CreateLicensePlugin()
        ],
        ...
    }
    

接下来,npm run build,你会发现会有插件的log输出。

如何获取传入的文件路径

这个问题其实比较简单。
配置的时候不是先new一个实例化插件对象吗,我们在插件类的构造函数中接收参数即可。

如何获取输出的打包路径

在官网的示例中,我们可以看到插件的apply是传递了一个compiler参数的,这个compiler有两个重要属性。
       const { hooks, options } = compiler;
顾名思义,

  • hooks是编译过程中各个状态的钩子集合,这个官网有详细解释compiler-hooks
    这里我们选done这一状态hook。
    如果你需要详细了解hook的状态和时机,官方是建议看源码:

    To learn this, search for hooks.< hook name>.call across the webpack source

  • options,也就是配置的意思。要配置当然从这里面拿。

最终实现

/*
  该插件用于将licensePath的文件输出到输出目录下License.txt, 用法如下:
    plugins: [
        ...,
        new CreateLicensePlugin({
            licensePath: './LICENSE'
        }),
    ],  
 */
const pluginName = 'CreateLicensePlugin';
const fs = require("fs");
const { resolve } = require("path");
class CreateLicensePlugin {
    //在构造函数里面接收配置参数
    constructor(options = {}) {
        this.licensePath = options.licensePath || './LICENSE'
    }
    apply(compiler) {
        const { hooks, options } = compiler;
        const outputPath = options.output.path
        // 当全部完毕后执行
        hooks.done.tap(pluginName, () => {
            // 将LICENSE复制到目标文件夹
            if (fs.existsSync(this.licensePath)) {
                const output = resolve(outputPath, 'LICENSE.txt')
                console.log(outputPath);
                console.log(output);
                const data = fs.readFileSync(this.licensePath);
                fs.writeFileSync(output, data)
            } else {
                console.error(`${this.licensePath} is not exist!`)
            }
        });
    }
}
module.exports = CreateLicensePlugin;

源代码

https://github.com/nicennnnnnnlee/webpack-plugin-loader-examples

系列文章


内容
隐藏