to-zip-webpack-plugin是一个webpack打包后的产品(输出目录)的压缩插件。对于经常压缩包目录的同学,手动压缩的步骤就省略了。本文将介绍该插件的基本使用和插件的具体实现。插件目前已经放到了github上,同时也发布到了npmgithub的地址:https://github.com/booms21/to...插件的基本使用首先我们创建一个简单的React+Webpack项目xxbot,然后在webpack中。添加新的ToZipWebpackPlugin()到config.js。这里不需要添加任何配置,因为构建的dist文件(输出)默认会被压缩。我们运行npmrunbuild命令,看到构建完成后,多了一个...3823.zip压缩文件。打开这个文件,发现和打包后的产品dist文件夹一样。当然,你也可以添加一些配置,让压缩操作更加个性化:比如下面的配置将dist压缩成一个timestamp.tar文件,另外在当前目录下压缩一个README.md文件。解压...7229.tar和mymd.tar,发现这两个文件的内容没有问题。两种不同的压缩作业不会相互影响。当需要制作压缩文件时,此时就可以使用了。当然,还有其他配置。插件内部实现先看一下这个插件的具体实现:首先我们看一下webpack官网对插件的描述:官方文档说插件的一个实例-in传入plugin属性,还需要包含apply方法。所以我们需要使用class来实现:我们插件的主要任务是压缩webpack输出的输出文件,所以我们需要在官方插件列表中找到一个afterEmithook来实现插件的功能——在(压缩文件输出到输出目录后)入口文件index.js中创建一个ToZipWebpackPlugin类,构造函数中所有参数设置默认值:index.jsclassToZipWebpackPlugin{constructor({zlibLevel,format,fileName,defaultFileName,source,log,deleteFileList,archive,}={}){constFILETYPE=["zip","tar"];//支持的压缩文件类型this.options={};this.timeFormatter=newTimeFormatter();this.options.zlibLevel=isNaN(zlibLevel)?9:zlib级别;//默认压缩级别为9this.options.format=FILETYPE.includes(format)?格式:“邮编”;//默认类型是zipthis.options.fileName=isString(fileName)?文件名:this.getFileName("time");//默认文件名时间字符串isString(defaultFileName)?(this.options.fileName=this.getFileName(defaultFileName)||this.options.fileName):这个。选项.文件名;this.options.source=isString(source)?sou注册:“”;this.options.deleteFileList=deleteFileList;this.options.archive=存档;this.options.log=日志;}delete(deleteFileList){returndel(deleteFileList);}getFileName(type){consttypeTable={timestamp:String(this.timeFormatter.getTimestamp()),time:this.timeFormatter.getDateStr("yyyymmddhhMMss"),uuid:v4(),};返回类型表[类型];}apply(compiler){compiler.hooks.afterEmit.tapAsync("ToZipWebpackPlugin",(complition,callback)=>{this.options.archive&&doArchive(this.options);//压缩前的压缩操作outputArchive(this.options,complition.options.output.path);isArray(this.options.deleteFileList)&&this.delete(this.options.deleteFileList);callback();});}}钩子回调增加3个步骤:压缩前执行的自定义压缩存档>默认输出压缩>最后删除的文件,记得最后要执行callback();然后我们看一下outputArchive(打包产品输出压缩函数):outputArchive.jsconstpath=require("path");constfs=require("fs");constarchiver=require("archiver");const{logger}=require("./util");constoutputArchive=(options,outputPath)=>{constfilename=options.fileName;constabPath=path.join(outputPath,"/",文件名+"."+options.format);constsourceDir=path.join(path.relative(path.resolve(),outputPath));constoutput=fs.createWriteStream(path.relative(outputPath,abPath));//设置压缩格式constarchive=archiver(options.format,{zlib:{level:options.zlibLevel},//设置压缩级别。});archive.on("warning",function(err){options.log&&logger(err);if(err.code==="ENOENT"){//记录警告}else{//抛出错误throwerr;}});archive.on("error",function(err){options.log&&logger(err);throwerr;});档案.on("finish",()=>{constmsg="Compressionfinish!-"+path.join(path.resolve(),path.relative(outputPath,abPath))+"Size:"+(archive.pointer()/1024/1024).toFixed(2)+"M";console.log(msg);options.log&&logger(msg);});archive.pipe(输出);archive.directory(sourceDir);archive.finalize();//压缩完成};module.exports=outputArchive;过程比较简单,获取outputPath并转化为绝对路径abPath,然后使用archiver库进行压缩,压缩完成后使用log4js进行日志记录最后看一下doArchive的实际情况:doArchive.jsconstdoArchive=(options)=>{if(isString(options.archive.source)&&isString(options.archive.targetDir)){constabPath=path.join(options.archive.targetDir,"/",options.archive.fileName+"."+options.format);//目标压力缩小路径constoutput=fs.createWriteStream(abPath);//设置压缩格式constarchive=archiver(options.format,{zlib:{level:options.zlibLevel},//设置压缩级别。});//捕获警告的良好做法(即统计失败和其他非阻塞错误)archive.on("warning",function(err){options.log&&logger(err);if(err.code==="ENOENT"){//记录警告}else{//抛出错误throwerr;}});archive.on("error",function(err){options.log&&logger(err);throwerr;});archive.on("完成",()=>{constmsg="压缩完成!-"+abPath+"Size:"+(archive.pointer()/1024/1024).toFixed(2)+"M";控制台日志(消息);options.log&&记录器(味精);});archive.pipe(输出);if(fs.lstatSync(options.archive.source).isFile()){conststrum=fs.createReadStream(options.archive.source);archive.append(strum,{name:path.basename(options.archive.source)});}else{archive.directory(path.relative(__dirname,options.archive.source));//将源压缩为相对路径的目录更改}archive.finalize();//压缩完成}};module.exports=doArchive;基本的压缩操作还是和outputArchive一样,但是doArchive是可以自定义压缩文件夹和压缩目标输出目录的时候当archive.source是文件时,需要使用archive.append进行压缩。否则,archive.directory可以用来压缩目录,当它是一个文件夹。至此整个插件就完成了。
