webpack学习6-手写plugin2

1. 编写一个 类似于CopyPlugin的插件

参数三个 from to ignore

2. 准备工作

1. 下载工具

1. webpack
2. webpack-cli
3. tapable // tapable类
4. schema-utils // 校验option
5. globby // 处理文件路径

3. 编写

1. webpack.config.js

const path = require('path');
const CopyWebpackPlugin = require('./plugin/CopyWebpackPlugin');
module.exports = {
    mode: 'production',
    plugins: [
        new CopyWebpackPlugin({
            from:'public',
            to: 'css',
            ignore: ['**/index.html'] // 过滤掉所有的index.html
        })
    ]
};

2. CopyWebpackPlugin.js

const {validate} = require('schema-utils');
const schema = require('../schema.json');
const path = require('path');
const globby = require('globby');
const {promisify} = require('util');
const fs = require('fs');
const readFile = promisify(fs.readFile);
const webpack = require('webpack');
const {RawSource} = webpack.sources;

class CopyWebpackPlugin {
    constructor(options){ // 参数通过构造器传入
        // 校验options的合法性
        validate(schema, options,{
            name: 'CopyWebpackPluginOptions'
        });
        this.options = options; // 绑定到this上,方便后续访问
    }
    apply(compiler){
        compiler.hooks.thisCompilation.tap('CopyWebpackPlugin',(compilation)=>{
            compilation.hooks.additionalAssets.tapAsync('CopyWebpackPlugin', async (cb)=>{
                const {from, to='.', ignore} = this.options;
                // 得到工作目录,webpack.config.js所在的目录,类似于process.cwd();
                const {context} = compiler.options;  
                const absoluteFrom = path.isAbsolute(from) ? form : path.resolve(context, from);
                // globby 可以传入三个参数, 第一个是要处理的文件夹, 第二个options 有个属性是ignore 第三个是回调函数
                const paths = await globby(absoluteFrom,{ignore});

                const files = await Promise.all(paths.map(async absolutePath=>{
                    const data = await readFile(absolutePath);
                    const baseName = path.basename(absolutePath);
                    const fileName = path.join(to,baseName);
                    return {
                        data: new RawSource(data),
                        fileName
                    }
                }))
                
                files.forEach(item=>{
                    compilation.emitAsset(item.fileName, item.data);
                })

                cb();
            })

        });
    }
}
module.exports = CopyWebpackPlugin;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值