Writing is not easy, without the permission of the author is prohibited in any form of reprint!


If you think this article is good, welcome to follow, thumb up and share!


The Nuggets
Webpack Plugin Knowledge Sharing

Know the Plugin

  • Loader is used for conversion of specific module types;
  • Plugin can be used to perform a wide range of tasks, such as packaging optimization, resource management, environment variable injection, etc.

The Plugin is commonly used

CleanWebpackPlugin

  • Each time you change some configuration and repackage, you need to manually delete the dist folder:
  • We can use a plug-in to help us do this, the CleanWebPackPlugin;

Installation:

  • npm install clean-webpack-plugin --save

Configuration:

const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = { entry: "./src/js/main.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "build"), }, module: {... }, plugins: [new CleanWebpackPlugin()], };

HtmlWebpackPlugin

  • Our HTML files are written in the root directory, and the dist folder that you end up packing doesn’t have an index.html file.
  • When the project is deployed, it is necessary to have the corresponding entry file index.html;
  • So we need to package index.html as well;

The installation

  • npm install html-webpack-plugin --save

configuration

  • You can pass in variables like title,
  • You can customize the template, template, fill in the template path
const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: "./src/js/main.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "build"), }, module: {... }, plugins: [ new HtmlWebpackPlugin({ title: "LeBronChao Webpack", template: "./public/index.html", }), ], };

Template and variable reference methods

<! DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <h1>LeBronChao Webpack</h1> </body> </html>

The effect

  • An index.html file is now automatically generated in the build folder
  • The bundle. Js file that we packaged is also automatically added to this file
  • How is this file generated?

    • By default it is generated from one of EJS’s templates;
    • In the HTML-webpack-plugin source code, there is a module default_index.ejs;

DefinePlugin

Used to define global constants

The installation

  • Webpack built-in, no installation required

configuration

const { DefinePlugin } = require("webpack"); module.exports = { entry: "./src/js/main.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "build"), }, module: {... }, plugins: [ new DefinePlugin({ BASE_URL: "'./favicon.ico'", }), ], };

Note:

  1. If a variable is assigned as a string, it should be nested. If a variable is assigned as a string, it should be filled in “”, as above.

How to use the template

<! DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title><%= htmlWebpackPlugin.options.title %></title> <link rel="icon" href="<%= BASE_URL %>" /> </head> <body> <h1>LeBronChao Webpack</h1> </body> </html>

CopyWebpackPlugin

  • During Vue packaging, if we put some files in the public directory, that directory will be copied to the dist folder.

    • This copy function, we can use the CopyWebPackPlugin to complete;

Installation:

  • npm install copy-webpack-plugin --save

Configuration:

  • The rules for replication are set in patterns;
  • From: Sets which source to start copying from;
  • To: The location copied to, which can be omitted, will be copied to the packaging directory by default. The path is written with the packaging directory as the root directory.
  • GlobOptions: Sets some additional options where ignore can write files that need to be ignored:

    • DS_STORE: A file automatically generated in the Mac directory;
    • Index. HTML: There is no need to copy as we have already generated index. HTML with the HtmlWebpackPlugin.
const CopyWebpackPlugin = require("copy-webpack-plugin"); module.exports = { entry: "./src/js/main.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "build"), }, module: {... }, plugins: [new CopyWebPackPlugin ({patterns: [{from: "public", // output to: "build", globOptions: { ignore: ["**/index.html", "**/.DS_Store", "**/abc.txt"], }, }, ], }), ], };

A custom Plugin

  • Webpack has two very important classes, Compiler and Compilation

    • They monitor all the life cycles of Webpack by injecting plug-ins
    • Plug-in injection requires a variety of hooks
    • Hook is derived from the Tapable library
  • To customize a Plugin, start with a library called Tapable

    • Tapable is an official written and maintained library
    • Tapable is managing the required hooks that can be applied to a plug-in

Tapable Hook classification

  • Sync Sync

    • SyncHook
    • SyncBailHook
    • SyncWaterfallHook
    • SyncLoopHook
  • Asynchronous Async

    • Paralle (parallel)

      • AsyncPrarllelHook
      • AsyncParallelBailHook
    • Series (serial)

      • AsyncSeriesHook
      • AsyncSeriesBailHook
      • AsyncSeriresWaterfallHook
    • Synchronous and asynchronous

      • Sync hook is a sync hook
      • Two event handling callbacks, starting with async, do not wait for the last processing callback to finish before executing the next callback.
  • Other categories

    • Baill: When there is a return value, no subsequent event firing is performed.
    • Loop: This event is executed repeatedly if the return value is true. If undefined or nothing is returned, the event exits
    • Waterfall: When the return value is not undefined, the result of this return is used as the first parameter for the next event
    • Parallel: Hook that executes event processing callbacks simultaneously
    • Series: Serial, will wait for the previous event processing callback Hook

The use process of Hook

  1. Create a Hook object

    • The array passed to the New object is the key that needs to be passed in
  2. Register the events in Hook
  3. Triggering event
  • plugin.js
const {SyncWaterfallHook} = require("tapable")

class tapableTest{
    constructor () {
        this.hooks = {
            syncHook:new SyncWaterfallHook(['name','age'])
        }

        this.hooks.syncHook.tap("event1",(name, age) => {
            console.log("event1", name, age);
            return "event1"
        })

        this.hooks.syncHook.tap("event2",(name, age) => {
            console.log("event2", name, age);
        })
    }

    emit(){
        this.hooks.syncHook.call("lebron", 21);
    }


}

const index= new tapableTest()
index.emit()

// event1 lebron 21 
// event2 event1 21

Customize an AutouploadPlugin

After front-end development is complete, it is often necessary to package and upload the code. Individual developers usually use Nginx to deploy services. It is too cumbersome to upload code every time. Write a Plugin to let it automatically upload to the Nginx folder.

  • The plugin configuration

    • Host: The address of the host
    • Username: host username
    • Password: Host SSH login password
    • RemotePath: The folder where the service is deployed remotely
const AutoUploadPlugin = require(".. /plugins/autoUploadPlugin") plugins:[ new HtmlWebpackPlgin(), new AutoUploadPlugin({ host:"xx.xx.xx.xx", username:"root", password:"xxxxxxx", remotePath:"/test" }) ]
  • AutoUploadPlugin.js

    • Use the Node-SSH library to complete a series of remote operations

      1. npm i node-ssh
    • Constructor

      1. Generate an SSH object
      2. Receive options parameter –
    • Each Plugin requires an apply function to register the plug-in

      1. The hooks registration event is called through the Compiler object
      2. Get the path to the packaged output folder through the Compilation object
      3. Establish an SSH connection
      4. Delete the original content from the remote server
      5. Upload the generated file to the server
      6. Close the SSH connection
      7. Implement the callback
const { NodeSSH } = require("node-ssh") class AutoUploadPlugin { constructor (options) { this.ssh = new NodeSSH() This. The options = options} the apply (compiler) {/ / use the compiler. The files are generated after the hook hooks. AfterEmit. TapAsync (" AutoUploadPlugin ", async (compilation, callback) => { // 1. Obtain the output folder path const outputPath = compilation. OutputOptions. The path / / 2. Await this.connectServer() // 3. Const serverDir = this.options.remotePath await this.ssh.execCommand(' rm-rf ${serverDir}/* ') // 4. Await this.uploadFiles(OutputPath, ServerDir) // 6. Close the SSH this. SSH. The dispose (); callback() }) } async connectServer () { await this.ssh.connect({ host: this.options.host, username: this.options.username, password: this.options.password }) } async uploadFiles (localPath, RemotePath) {const status = await this.ssh.putDirectory(localPath, remotePath, {// Recursive: True, // Concurrency: 10}) console.log("Upload "+ status? } module.exports = autouploadPlugin.} module.exports = autouploadPlugin
  • Webpack Plugin: Webpack Plugin
  • Nuggets: Front end LeBron
  • Zhihu: Front-end Leon
  • Continue to share technical blog posts, follow the WeChat official account 👇