UzumakiItachi
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

UzumakiItachi

起风了,唯有努力生存。
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • WebPack

    • WebPack热更新原理
    • 实现一个通用的WebPack配置包
    • WebPack打包多页面应用
    • WebPack构建速度以及体积优化策略
    • 手写一个简易的WebPack
    • 实现一个简易的webpack-loader
    • 实现一个简易的Webpack-plugin
    • 深入WebPack code splitting
    • 实现一个合成雪碧图的loader
    • 实现一个压缩文件的plugin
      • 前言
      • jszip
      • 搭建插件运行环境
      • zip-plugin
      • compiler和compilation的区别
    • webpack5都升级了哪些东西
    • 实现一个自动收集路由信息的webpack插件
  • 浏览器相关

  • 工程化相关

  • 工作中遇到的问题以及解决方案

  • Git

  • Vite

  • 一些小工具

  • 算法

  • 服务器

  • HTTP

  • 技术
  • WebPack
hanhanbuku
2023-05-31
目录

实现一个压缩文件的plugin

# 前言

前面讲了如何实现一个简单的plugin,下面通过一个实战来跟深入的去了解一下plugin

# jszip

首先要实现压缩文件,肯定需要用到外部的工具包,下面来安装一下jszip这个包

npm install jszip
1

# 搭建插件运行环境

插件没有loader那样的loader-runner环境,所以我们需要搭建一个最简单的webpack,来实验一下我们的plugin

const path = require('path')
const ZipPlugin = require('./src/plugins/zip-plugins')

module.exports = {
    entry: path.join(__dirname,'./src/index.js'),
    output: {
        filename: "main.js",
        path: path.resolve(__dirname,'dist'),
        clean: true
    },
    plugins: [
        new ZipPlugin({
            filename: 'myZip'
        })
    ]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# zip-plugin

const jsZip = require('jszip')
const zip = new jsZip()
const path = require('path')
const RawSource = require('webpack-sources').RawSource
const webpack = require('webpack')

module.exports = class zipPlugin{
    constructor(options) {
        this.options = options
    }
    apply(compiler){
        compiler.hooks.compilation.tap('ZipPlugin',(compilation)=>{
            const folder = zip.folder(this.options.filename)
            for (let filename in compilation.assets){
                const source = compilation.assets[filename].source()
                folder.file(filename,source)
            }
            zip.generateAsync({
                type:"nodebuffer"
            }).then(res=>{
                // compilation.assets[outputPath] = new RawSource(res)
                compilation.hooks.processAssets.tapAsync(
                    {
                        name: 'ZipPlugin',
                        stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL, // see below for more stages
                    },
                    (assets,callback) => {
                        assets['myzip.zip'] = new RawSource(res)
                        console.log(assets,111)
                        callback()
                    }
                );
            })
        })
        console.log('这是我的第一个插件')
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

这里因为我们要对最后的产物里添加一个资源压缩包,所以我们选择订阅compiler上的compilation hook,然后通过compilation的processAssets hook来去写入我们的压缩包资源。 至于订阅方式是同步还是异步,看文档就行。文档上会标注每个hook是同步的还是异步的。我们只需要使用对应的方式去订阅就可以了。 assets就是最终的产物,我们把打好的压缩包转成source赋值到他身上,就可以看到最终得产物里有压缩包了。

# compiler和compilation的区别

这两个东西的关系我也不是很清楚,以至于很多时候不知道该订阅谁的钩子。但是从宏观角度来讲。我觉得compiler就像一个组织的老大一样,由他来控制整个组织的行动,他会创造很多指令,交由compilation 去执行,compiler主要就是触发一些生命周期的钩子,然后创建compilation对象,然后挂载插件。而具体的编译打包,以及产出的动作其实是compilation对象去做的。所以在写插件的时候也可以根据这个特点去对应的对象上找对应的钩子去订阅。

编辑 (opens new window)
上次更新: 2023/06/01, 19:51:21
实现一个合成雪碧图的loader
webpack5都升级了哪些东西

← 实现一个合成雪碧图的loader webpack5都升级了哪些东西→

最近更新
01
前端检测更新,自动刷新网页
06-09
02
swiper渲染大量数据的优化方案
06-06
03
仿抖音短视频组件实现方案
02-28
更多文章>
Theme by Vdoing | Copyright © 2023-2025 UzumakiItachi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式