5
There are dreams, dry goods, WeChat search [Da Qian World] Pay attention to this Shuawanzhi who is still doing dishes in the early morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line factory interview complete test sites, materials and my series of articles.

Recently, one after another UniUsingComponentsWebpackPlugin plug-in (described below), this is my third open source project, I hope everyone will maintain it together, star together, and the other two:

background

The first pain point

Friends who develop small programs with uniapp should know that when we want to use third-party UI libraries ( vant-weapp , iView-weapp ) in uniapp, if we want to use it globally, we need to add corresponding component declarations to src/pages.json in usingComponents

// src/pages.json
"usingComponents": {
    "van-button": "/wxcomponents/@vant/weapp/button/index",
  }

But in the development process, we are not sure which components are needed, so we may declare them all (PS: this is more common when doing public libraries), so we have to write them one by one. As programmers, we absolutely This dumb method is not allowed. This is the first pain point .

The second pain point

To use third-party components, in addition to src/pages.json wxcomponents in the corresponding production directory, and copy the third-party library to the file. This is customized by uniapp. For details, see: https://uniapp.dcloud .io/frame?id=%e7%9b%ae%e5%bd%95%e7%bb%93%e6%9e%84.

This is the second pain point .

The third pain point

The second pain point is that we copy the entire UI library to wxcomponents , but when it is finally released, we are unlikely to use all the global components inside, so we will publish unnecessary components to increase the size of the code.

Some friends will think that when you copy the third-party library to wxcomponents , you can just copy the used ones. This rationale is true, but there may also use components to other components, we have to look at one, then introduced one by one, which has returned first pain point .

With these three pain points, there must be a plug-in to do these silly things and deal with these three pain points. So there is UniUsingComponentsWebpackPlugin plug-in, this webpack plug-in mainly solves the following problems:

  • After configuring the third-party library, the native components under it can be automatically introduced without manual configuration
  • Unused native components can be automatically removed during production build

webpack plugin

The plug-in system of webpack is a strongly coupled architecture based on Tapable. It will be accompanied by sufficient context information when the hook is triggered at a specific time. The hook callback defined by the plug-in can and can only interact with the data structure and interface behind these contexts. The interaction produces a side effect, which in turn affects the compilation status and subsequent processes.

From the morphological point of view, the plug-in is usually a class apply

class SomePlugin {
    apply(compiler) {
    }
}

apply function of the plug-in object in the order of registration after startup, and at the same time pass in the compiler object compiler . The plug-in developer can use this as a starting point to reach any hook defined inside webpack, for example:

class SomePlugin {
    apply(compiler) {
        compiler.hooks.thisCompilation.tap('SomePlugin', (compilation) => {
        })
    }
}

Pay attention to the core statement compiler.hooks.thisCompilation.tap , where thisCompilation is the hook object provided by the tapable warehouse; tap is the subscription function for registering callbacks.

Webpack's plug-in system is based on tapable , so it is necessary to familiarize yourself with the types of hooks provided by tapable and their respective characteristics.

At this point, I won't continue the introduction, and you can go to the official website for more details about the plug-in.

Here is recommended Tecvan "Webpack plug-in architecture in-depth explanation" https://mp.weixin.qq.com/s/tXkGx6Ckt9ucT2o8tNM-8w

Realization idea

The UniUsingComponentsWebpackPlugin plug-in mainly uses three compiler hooks.

The first hook is environment :

compiler.hooks.environment.tap(
      'UniUsingComponentsWebpackPlugin',
      async () => {
        // todo someing
      }
    );

This hook is mainly used to automatically introduce the native components under it, so that no manual configuration is required. solves the first pain point .

The second hook thisCompilation , this hook can get compilation , which can operate on the final packaged product:

compiler.hooks.thisCompilation.tap(
      'UniUsingComponentsWebpackPlugin',
      (compilation) => {
        // 添加资源 hooks
        compilation.hooks.additionalAssets.tapAsync(
          'UniUsingComponentsWebpackPlugin',
          async (cb) => {
            await this.copyUsingComponents(compiler, compilation);
            cb();
          }
        );
      }
    );

So this hook is used to node_modules copy of the third library in our production dist directory of wxcomponents , solve the second sore point .

ps: Here you can also directly use the existing copy-webpack-plugin plug-in to achieve.

The third hook done indicates that the execution of compilation

    if (process.env.NODE_ENV === 'production') {
      compiler.hooks.done.tapAsync(
        'UniUsingComponentsWebpackPlugin',
        (stats, callback) => {
          this.deleteNoUseComponents();
          callback();
        }
      );
    }

After the execution is completed, it means that we have generated the dist directory, and can read the file content, analyze, obtain which components are used, and then delete the files corresponding to the components that are not used. This can solve our third pain point, .

PS: Here I judge that it will be removed only in the production environment. The development environment does not have it, and it is not necessary.

use

Install

npm install uni-using-components-webpack-plugin --save-dev

Then add the plug-in to WebPack Config. For example:

const UniUsingComponentsWebpackPlugin = require("uni-using-components-webpack-plugin");

module.exports = {
  plugins: [
    new UniUsingComponentsWebpackPlugin({
        patterns: [
        {
            prefix: 'van',
            module: '@vant/weapp',
        },
        {
            prefix: 'i',
            module: 'iview-weapp',
        },
        ],
    })
  ],
};
Note: uni-using-components-webpack-plugin only applies to small programs developed in UniApp.

parameter

NameTypeDescription
patterns{Array<Object>}Specify the relevant for the plug-in

Patterns

moduleprefix
Module nameComponent prefix

module refers to package.json in name . If you use Vant, the corresponding module is @vant/weapp . If you use ibb, the corresponding module is iview-weapp each of package.json .

prefix refers prefix components, such as Vant use is van prefix beginning, iview use is i prefix beginning, specifically to see their respective official documents.

PS: For to spit on vant, ask others to use the van prefix, and then declare the sub-components in my own component, but do not use the van prefix, such as the picker component, the JSON file in it is written like this:

{
  "component": true,
  "usingComponents": {
    "picker-column": "../picker-column/index",
    "loading": "../loading/index"
  }
}

picker-column and loading do not have the van . Because of this problem, when doing the automatic removal function, I judge which components to use based on the prefix. Because loading and picker-column not prefixed, they will be deleted, resulting in the final picker not available. In order to solve this problem, a lot of work has been increased.

hope that the later version of Vant can be optimized.

Summarize

This article uses custom Webpack plugins to achieve some daily technical optimization needs. It mainly introduces the basic composition and simple architecture of the Webpack plug-in. Through three pain points, it leads to the uni-using-components-webpack-plugin plug-in, and introduces how to use it and how to realize it.

Finally, there is more knowledge to learn about Webpack plug-in development. It is recommended to read the official document " Writing a Plugin " for learning.

code is deployed, the possible bugs cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

comminicate

If you have dreams and dry goods, search for [Moving to the World] Follow this brushing wit who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.


王大冶
68k 声望104.9k 粉丝