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;