Writing is not easy, without the permission of the author forbid to reprint in any form! If you think the article is good, welcome to follow, like and share!

Know the Plugin

  • Loader is used for conversion of specific module types;

  • Plugins can be used to perform a wide range of tasks, such as packaging optimization, resource management, environment variable injection, and so on.

The Plugin is commonly used

CleanWebpackPlugin

  • The dist folder needs to be manually deleted each time some configuration changes are made and repackaged:

  • We can do this with the help of a plug-in called 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()],
};
Copy the code

HtmlWebpackPlugin

  • Our HTML file is written in the root directory, and the dist folder in the final package has no index.html file.

  • In the project deployment, 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 a variable like title,

  • You can customize a template. Template specifies the path of the template

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",})]};Copy the code

Templates and variables reference methods

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

The effect

  • An index. HTML file is now automatically generated in the Build folder

  • The bundle.js file we packaged is also automatically added to this file

  • How is this file generated?

    • By default, it is generated from an EJS template;
    • In the source code of the HTml-webpack-plugin, there is a default_index.ejs module;

DefinePlugin

Use to define global constants

The installation

  • Webpack is 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'",})]};Copy the code

Notes:

  1. If the variable defined is a string, it is required to nest the string. If the variable is a variable, it is required to fill the variable in “”, as above.

Template usage

<! DOCTYPEhtml>
<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>
Copy the code

CopyWebpackPlugin

  • During vue’s packaging process, if we put some files in a public directory, that directory will be copied to the dist folder.
    • To do this, we can use CopyWebpackPlugin;

Installation:

  • npm install copy-webpack-plugin --save

Configuration:

  • The rules for copying are set in patterns;

  • From: Sets the source from which replication starts;

  • To: the location to which to copy to, which can be omitted, will be copied to the package directory by default. The root directory of path writing is the package directory.

  • GlobOptions: Sets some additional options, where ignore can write files that need to be ignored:

    • DS_Store: a file that is automatically generated in the MAC directory.
    • Index.html: There is no need to copy because we have already generated index.html using 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".// Do not write, default to output
          to: "build".globOptions: {
            ignore: ["**/index.html"."**/.DS_Store"."**/abc.txt"],},},],}),],};Copy the code

A custom Plugin

  • Webpack has two very important classes: Compiler and Compilation

    • They listen to the entire webPack lifecycle by injecting plug-ins
    • Plug-in injection is dependent on various hooks
    • Hooks are from the Tapable library
  • To customize your Plugin, learn about a library called Tapable

    • Tapable is an officially written and maintained library
    • Tapable manages the required hooks that can be applied to plug-ins

Tapable Hook classification

  • Sync Sync

    • SyncHook
    • SyncBailHook
    • SyncWaterfallHook
    • SyncLoopHook
  • Asynchronous Async

    • Paralle
      • AsyncPrarllelHook
      • AsyncParallelBailHook
    • Series (serial)
      • AsyncSeriesHook
      • AsyncSeriesBailHook
      • AsyncSeriresWaterfallHook
    • Synchronous and asynchronous
      • The one starting with sync is a synchronization hook
      • Two event processing callbacks starting with async do not wait for the last callback to finish before executing the next callback.
  • Other categories

    • Baill: When there is a return value, no subsequent event firing will be executed.

    • Loop: When the return value is true, the event is executed repeatedly. When the return value is undefined or no content is returned, the event exits

    • Waterfall: When the return value is not undefined, the result returned this time will be taken as the first parameter of the next event

    • Parallel: a Hook that executes the event processing callback simultaneously

    • Series: serial, hooks that will wait for the last event handler callback

Use process of Hook

  1. Create Hook object

    • The New object is passed in the array of the key parameter
  2. Register the events in the 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
Copy the code

Customize an AutoUploadPlugin

After front-end development is complete, code is often packaged and uploaded. Individual developers usually use the Nginx deployment service. It is too much trouble to upload code each time. Write your own Plugin and let it automatically upload to the Nginx folder.

  • The plugin configuration
    • Host: indicates the address of the host
    • Username: indicates the username of the host
    • Password: indicates the SSH login password of the host
    • RemotePath: The folder of the remote deployment service
const AutoUploadPlugin = require(".. /plugins/autoUploadPlugin")

plugins: [new HtmlWebpackPlgin(),
    new AutoUploadPlugin({
        host:"xx.xx.xx.xx".username:"root".password:"xxxxxxx".remotePath:"/test"})]Copy the code
  • AutoUploadPlugin.js
    • Complete remote series operations using the Node-SSH library

      1. npm i node-ssh
    • Constructor

      1. Generating an SSH object

      2. Receive the options parameter –

    • Each Plugin requires an Apply function to register the plug-in

      1. Register events by calling hooks from the compiler object
      2. Obtain the path of the package output folder from the Compilation object
      3. Establishing 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.options = options
    }

    apply (compiler) {
        // Use the hook after the file is generated
        compiler.hooks.afterEmit.tapAsync("AutoUploadPlugin".async (compilation, callback) => {

            // 1. Obtain the path of the output folder
            const outputPath = compilation.outputOptions.path

            // 2. Connect to the server (SSH)
            await this.connectServer()

            // 3. Delete the contents of the original directory
            const serverDir = this.options.remotePath
            await this.ssh.execCommand(`rm -rf ${serverDir}/ * `)

            // 4. Upload the file to the server
            await this.uploadFiles(outputPath, serverDir)

            // 5. Disable SSH
            this.ssh.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, {
            // Upload all files recursively
            recursive: true./ / concurrency
            concurrency: 10
        })
        console.log("Upload " + status ? "Success" : "Failure")}}module.exports = AutoUploadPlugin
Copy the code
  • Nuggets: LeBron on the front end

  • Zhihu: LeBron on the front end

  • Continue to share technical blog posts, follow wechat public account 👇🏻