Have a dream, have dry goods, wechat search [big Move the world] pay attention to this in the early morning is still in the bowl washing wisdom. In this paper, making github.com/qq449245884… Has been included, a line of large factory interview complete test sites, information and my series of articles.

Recently, gradually built a UniUsingComponentsWebpackPlugin plugin (described below), this is the third open source projects, hope everyone together to maintain, star together ah, the other two:

  • vue-okr-tree

    Vue 2-based organization architecture tree component

    Address: github.com/qq449245884…

  • ztjy-cli

    A simple template for the team to initialize scaffolding

    Address: github.com/qq449245884…

  • UniUsingComponentsWebpackPlugin

    Address: github.com/qq449245884…

    With UniApp, for integrating applets native components

    • A third-party library can be configured to automatically import native components under it without manual configuration
    • Production builds can automatically weed out unused native components

background

The first pain point

If you do use uniApp, you should know that when you try to use third-party USER interface (UI) apps, you want to use them globally. You need to add the corresponding component declaration to usingComponents in SRC /pages. Json, for example:

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

But during development, we don’t know exactly which components we need, so we might declare them all (PS: this is more common when doing public libraries), so we have to write them one by one, and as programmers we don’t allow that to happen. This is the first pain point.

Second pain point

To use third-party components, in addition to SRC /pages. Json, you also need to create wxComponents in the corresponding production directory and copy the third-party library to this file. This file is customized by Uniapp, see uniapp.dcloud. IO /frame? Id = % e…

This is the second pain point.

The third pain point

Second, we copied the entire UI library to WXComponents, but when we finally released it, we were unlikely to use all of its global components, so we released unnecessary components as well, increasing the size of the code.

When you copy a third-party library to WXComponents, you can just copy the library you are using. That’s true, but there may be other components in the component, and we have to look at them one by one, and then introduce them one by one, which brings us back to the first pain point.

With these three pain points, there has to be a plugin to do these stupid things and deal with these three pain points. Hence UniUsingComponentsWebpackPlugin plug-ins, the webpack plug-in mainly solve the following questions:

  • A third-party library can be configured to automatically import native components under it without manual configuration
  • Production builds can automatically weed out unused native components

Webpack plug-in

The plug-in system of Webpack is a strong coupling architecture based on Tapable implementation. It will attach sufficient context information when triggering hooks at a specific time. The hook callback defined by the plug-in can or can only produce side effect with the data structure and interface interaction behind these contexts. This in turn affects compilation status and subsequent processes.

Morphologically, a plug-in is usually a class with the apply function:

class SomePlugin {
    apply(compiler){}}Copy the code

After startup, Webpack will call the apply function of the plug-in object one by one in the order registered, and pass in the compiler object at the same time. The plug-in developer can use this as a starting point to reach any hooks defined in Webpack, for example:

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

Observe the core statement compiler. Hooks. ThisCompilation. Tap, including thisCompilation tapable warehouse provide hooks object; Tap is a subscription function that registers callbacks.

Webpack’s plug-in architecture is based on the hooks that Tapable provides, so it’s important to familiarize yourself with the hook types and features that Tapable provides.

At this point, there is no further introduction, more details about the plug-in can be found on the official website.

Here recommend Tecvan bosses to write the Webpack plug-in architecture depth interpretation mp.weixin.qq.com/s/tXkGx6Ckt…

Implementation approach

UniUsingComponentsWebpackPlugin plug-in mainly USES three compiler hook.

The first hook is environment:

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

This hook is mainly used to automatically import native components under it so that manual configuration is not required. Address the first pain point.

ThisCompilation is the second hook that can retrieve the compilation and operate on the final packaged product:

compiler.hooks.thisCompilation.tap( 'UniUsingComponentsWebpackPlugin', (compilation) = > {/ / add resources hooks compilation. The hooks. AdditionalAssets. TapAsync (' UniUsingComponentsWebpackPlugin ', async (cb) => { await this.copyUsingComponents(compiler, compilation); cb(); }); });Copy the code

So this hook is used to copy the third library in node_modules to wxComponents in our production dist directory, addressing the second pain point.

Ps: This can also be done directly with the existing copy-webpack-plugin.

The third hook, done, indicates that the compilation has completed:

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

After the execution is completed, it means that we have generated the dist directory. We can read the file contents, analyze and obtain which components are used, and then delete the files that are not used. That would take care of our third pain point.

PS: I guess it’s only in production, not in development.

use

The installation

npm install uni-using-components-webpack-plugin --save-dev
Copy the code

Then add the plug-in to WebPack Config. Such as:

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

module.exports = {
  plugins: [
	new UniUsingComponentsWebpackPlugin({
    	patterns: [{prefix: 'van'.module: '@vant/weapp'}, {prefix: 'i'.module: 'iview-weapp',},],})],};Copy the code

Note: uni-using-components-webpack-plugin is only applicable to applets developed in UniApp.

parameter

Name Type Description
patterns {Array} Specify the correlation for the plug-in

Patterns

module prefix
Module name Component prefix

Module refers to the name involved in package.json. If the appellate module is Vant, the appellate module is @vant/ appellate; if the appellate module is iView, the appellate module is iView-appellate. See their respective package.json.

Prefix refers to the component prefix. For example, Vant uses a prefix starting with van and iView uses a prefix starting with I. See their official documentation for details.

For example, the picker component, whose JSON file reads:

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

Picker-column and loading are not prefixed with van. Because of this problem, I judge which components to use according to prefixes in the automatic elimination function. As loading is not prefixed here, picker-column will be deleted. So the picker doesn’t work. To solve this problem, a lot of work has been added.

Hopefully the official Vant version will be optimized.

conclusion

This article uses a custom Webpack plug-in to achieve some technical optimization requirements for everyday use. This paper mainly introduces the basic composition and simple architecture of Webpack plug-in. Through three pain points, it introduces the uni-using-components-webpack-plugin, and introduces the usage and implementation ideas.

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

The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

communication

Have a dream, have dry goods, wechat search [big Move the world] pay attention to this in the early morning is still in the bowl washing wisdom.

In this paper, making github.com/qq449245884… Has been included, a line of large factory interview complete test sites, information and my series of articles.