webpack plugins

汪学真
2023-12-01

前言:

plugins:插件
在vue项目开发中,通常在vue.config.js中会配置webpack的相关配置
其中在plugins中配置相关的插件

plugins:[
	new xxx(), // 使用相关插件
	new xxx(),
	...
]

自定义插件

官网介绍

核心plugins钩子:compilercompilation 对象

理解:

Plugin通过访问Compiler和Compilation对象来完成工作。
一、
compiler是webpack的入口执行实例,其主要功能是监控代码、启动和终止一个compilation等宏观任务。compilation是具体负责核心编译工作的,主要是模块依赖分析,优化、连接,打包等工作。打个粗略的比方,compiler是人,compilation是人的大脑,架构设计上是类似的。
给webpack写plugin的时候,我们需要通过compiler提供的钩子来tap宏观生命周期,其中一个最主要的阶段就是compilation(创建编译对象)的hook,通过该hook,我们拿到编译对象,从而得以进一步tap入实际的编译过程。
二、
compiler 在 webpack 构建之初就已经创建,并且贯穿webpack整个生命周 ( before - run - beforeCompiler - complie - make - finishMake - afterComplier - done)
只要是做webpack编译,都会先创建一个compiler
compilation是到准备编译模块时,才会创建compilation对象
是 compile - make 阶段主要使用的对象

构建自定义插件:

目录格式:

|----src
		|----main.js
|----plugins
		|----my-webpack-plugin.js
|----package.json
|----webpack.config.js

基础构建:

// my-webpack-plugin.js
// 一个 JavaScript 类
class MyExampleWebpackPlugin {
  // 在插件函数的 prototype 上定义一个 `apply` 方法,以 compiler 为参数。
  apply(compiler) {
    // 指定一个挂载到 webpack 自身的事件钩子。
    compiler.hooks.emit.tapAsync(
      'MyExampleWebpackPlugin',
      (compilation, callback) => {
        console.log('这是一个示例插件!');
        console.log(
          '这里表示了资源的单次构建的 `compilation` 对象:',
          compilation
        );

        callback&&callback();
      }
    );
  }
}

案例:在vue中每次打包都自动在index.html页面打印版本号

// public/index.html
<script>
    console.log("v:5.7 Tue Mar 29 2022 13:51:05 GMT+0800");
 </script>
// plugins/set-version.js
const fs = require('fs')
const moment = require("moment");

class setVersion {
  apply(compiler) {
    // environment钩子:在编译器准备环境时调用, 时机就在配置文件中初始化插件之后。
    compiler.hooks.environment.tap(
      "setVersion",
      (compilation, callback) => {
        this.setVersion('./public/index.html', './versions.json')
        callback && callback();
      }
    )
  }


  /**
   * @description: 在versions.json文件中记录的版本号上增加并重新写入增加后的值,再根据正则匹配到index.html文件中对应位置进行修改写入
   * @param {*} htmlPath
   * @param {*} versionPath
   */
  setVersion(htmlPath, versionPath) {
    // 读取version.json和html文件
    const readVersion = fs.readFileSync(versionPath, 'utf8');
    const readHtml = fs.readFileSync(htmlPath, 'utf8');
    // 获取当前version
    let {
      version,
      unix
    } = JSON.parse(readVersion)
    const nowUnix = moment().format('X')
    const nowTime = moment()
    let str = ""

    if (unix && nowUnix - unix > 120) { // 120s内打包都会使用同一个版本号
      // version增加0.1
      let NewVersion = (Number(version) + 0.1).toFixed(1)
      // 写入version.json文件
      fs.writeFileSync(versionPath, JSON.stringify({
        version: NewVersion,
        unix: nowUnix
      }));

      // 编辑html(根据正则匹配到console.log("v:  字符串进行修改)
      str = readHtml.toString().replace(/console.log\("v:.*\)/g, `console.log("v:${NewVersion} ${nowTime}")`)
    } else {
      // 编辑html(根据正则匹配到console.log("v:  字符串进行修改)
      str = readHtml.toString().replace(/console.log\("v:.*\)/g, `console.log("v:${version} ${nowTime}")`)
    }

    // 写入html文件
    fs.writeFileSync(htmlPath, str);

  }
}

module.exports = setVersion
// 根目录下创建 versions.json,记录版本号
{"version":"5.7","unix":"1648533016"}
// vue.config.js
const setVersion = require('./plugins/set-version')
module.exports = {
    configureWebpack:{
        plugins: [
      		new setVersion() // 使用插件
    	]
    }
}

结束:这样在每次打包时都会自动更新版本号并添加当前日期

 类似资料:

相关阅读

相关文章

相关问答