preface

Not long ago, the boss of the group released a VUE-CLI3 DLL package, as a new in the VUE project, it was time to learn some new technology, so IN my spare time, I copied a copy of the code, Also look at how to write a DLL package from “zero” (this section uses webPack’s dllPlugin as an example).

Understand the document

Read through the official website of the document, because the knowledge is more, and there is no detailed example (refers to the “dumb-teaching style”), so the development of this third-party package learning costs are still some, especially webpack-chain and node part of the knowledge, here is a summary of some key points.

The plugin name

I didn’t use vue-cli-plugin- as a filename prefix when I originally named the folder, and as a result, Vue Invoke kept telling me that I couldn’t find the package. So I went to look at the source… In @ vue/cli/lib/invoke, js, its a key way to obtain packet Id resolvePluginId, this method in the @ vue/cli – Shared – utils/lib/pluginResolution, js, source code is as follows:

exports.resolvePluginId = id= > {
  // already full id
  // e.g. vue-cli-plugin-foo, @vue/cli-plugin-foo, @bar/vue-cli-plugin-foo
  if (pluginRE.test(id)) {
    return id
  }
  // scoped short
  // e.g. @vue/foo, @bar/foo
  if (id.charAt(0) = = =The '@') {
    const scopeMatch = id.match(scopeRE)
    if (scopeMatch) {
      const scope = scopeMatch[0]
      const shortId = id.replace(scopeRE, ' ')
      return `${scope}${scope === '@vue/' ? ` ` : `vue-`}cli-plugin-${shortId}`}}// default short
  // e.g. foo
  return `vue-cli-plugin-${id}`
}
Copy the code

It is clear that vue invoke will only look for packages prefixed with vue-cli-plugin-, which is explained in the final section of the documentation on the official website (which we will see later) :

In order for a CLI plug-in to be used by other developers, you must publish it to NPM following the vue-cli-plugin-

naming convention.

Therefore, the package.json name field conforms to the rules.

The creator and the service

@vue/cli and @vue/cli-service. The first part is @vue/cli. This part introduces the directory structure of plug-ins, so we can build a plug-in framework based on this:

Vue - cli - plugin - XXX ├ ─ ─ the README. Md ├ ─ ─ the generator | └ ─ ─ index. The js ├ ─ ─ index. The js ├ ─ ─ package. The json ├ ─ ─ prompts | └ ─ ─ index. Js ├ ─ ─ service | ├ ─ ─ the config - file. Js | └ ─ ─ regist -command. Js └ ─ ─ yarn. The lockCopy the code

Next, we will analyze the role of each part in detail.

generator

Document analysis

As mentioned in the documentation, the generator within the plug-in will be invoked in two scenarios:

  • During the initial creation of a project, if the CLI plug-in is installed as part of the project creation preset
  • The plug-in is passed after the project is createdvue invokeIs installed when called independently

Because most of the third party plugin scenarios developed are based on changing the configuration of the installed project, preset is not used in many scenarios (the project is usually manually configured and the generation of ~/.vuerc is not preferred in most cases), so this is only used for the manually invoked generator.

There are two ways to trigger the generator:

  • vue invoke
  • vue add

The following is a brief description of the differences between the two commands.

Vue invoke instruction

This command applies only when the package has been installed into the project through YARN or NPM. In this case, vue Invoke is required.

Note: the packageName is the remaining packageName without vue-cli-plugin-xxx. For example, if the packageName is vue-cli-plugin-xxx, then vue invoke XXX is used

vue add

This directive is used when the corresponding package is not installed in the project and is used in the same way as Vue Invoke

Note: If the source of the package is not correct, please add your own NPM source address (–registry).

Content writing

After all this analysis, the focus is on what we should write inside the generator and what it affects. Ok, let’s continue with the documentation (˃̶͈̀ロ˂̶͈́)੭ꠥ

Generator has three parameters, not verbose here as the preset configuration is not concerned here, so the only useful part for us is the first parameter API. The first part we need to change is the package.json in the project, using the method extendPackage, as shown in the following example:

// Modify 'package.json' field // vue section contents can not be module.exports = (API, options,) RootOptions) => {// modify 'package.json' field api.extendPackage({scripts: {test: 'vue-cli-service test'
    },
    vue: {
      pluginOptions: {
        testVendors: {// The parts that need to be prepackaged, vendors: [], // Output file name outputName:'vendor.dll.js'// Output address outputPath:'./public/vendor'// Whether to call cleanWebpackPlugin cleanCache:true}}}}); }Copy the code

Vue fields added here are automatically added to vue.config.js or package.json after invoke.

If you have promots configured and need the contents of this section, you can use the second options parameter to get the contents of the configuration. (The method of configuration.vuerc is not tried, because deconstruction + default + Prompts are enough.)

Prompts if you need to configure the template reference official source, feel prompts to write a template plug-in is also good.

Note: The render() function inside your template is based on the path of the current folder.

prompts

This part is not actually covered in this project, but it should be mentioned anyway. The official documentation for this part of the built-in plug-in has a detailed description (official plug-in), third-party plug-in mentioned a point:

This file should export an array of questions for Inquirer. These parsed answer objects are passed as options to the plug-in’s generator.

Therefore, if necessary, we have to write the questions in the form of an array. Such as:

module.exports = [
  {
    name: 'entry'.message: "What's the output file's name?".type: 'input'.default: 'vendor'}]Copy the code

The configuration result of this section is captured in the second parameter of the Generator section.

service

ConfigureWebpack, registerCommand, chainWebpack, registerCommand It’s not a good idea to just change the configuration of an existing project (unless you’re confident), so we can use the configureWebpack to merge the changes.

This section generally does three things:

  1. Change the user’s Webpack configuration file (i.e. Vue.config.js)
  2. Register instructions with cli-service
  3. Specifies the schema for registered directives

Let’s start with the simple part ~ (order: 3, 1, 2)

The specified mode

Well, this is the simplest, after all, the official website documentation, the reasons will not be repeated, the code is as follows:

module.exports.defaultModes = {
  <your direct>: <target mode>
}
Copy the code

Vue-cli-service: your direct is the generator part of the script registered with vue-cli-service. For example, the command registered with vue-cli-service is direct. Mode can be handled according to the actual situation. Generally, there is no problem with production mode.

Change a user’s configuration file

This is where knowledge of Webpack-chain comes in. To take a look at what is in pluginAPI (portals), some of the methods you might use include:

  • GetCwd: gets the current working directory
  • Resolve: equivalent to path.resolve
  • RegisterCommand: registerCommand (with three parameters!)
  • ChainWebpack: Chain calls to webpack
  • ConfigureWebpack: Used to merge Webpacks
  • ResolveChainableWebpackConfig: used to resolve webpack

Here we use configureWebpack to change the configuration and registerCommand to register our commands. Config-file and regist-command. Js are the two files that correspond to these files.

configureWebpack

The pluginOptions field in vue.config.js generated by invoke can be retrieved by using the options parameter. Work with api.configureWebPack to inject our WebPack configuration. Roughly written as:

api.configureWebpack(config= > {
  // Add a plugins
  config.plugins.push(
    /* Plugin */)});Copy the code
registerCommand

View the source code writing, found that there are three parameters, respectively:

  • API: pluginAPI instance
  • Options: Used to add configuration description
  • Fn: callback function used to trigger execution (such as running a Webpack configuration)

The official writing is as follows, which we can imitate

api.registerCommand(
  "test",
  {
    description: "This is an instruction.".// Command meaning
    usage: "vue-cli-service test".// How to use the command
    options: {
      /* Parameter Description */}},async args => {
    /* You can write a chain-webpack and call it, or do something else */});Copy the code

Summary of some problems

1. The packaging location of DLL in Demo is faulty

One problem with using the default packaging location: public/vendor is that the build file contains this vendor folder, and some of the configurations we inject don’t take effect.

Solution: Change the default public/vendor package location, as long as it is not generated in the public folder, no problem, please refer to the public section of vue-CLI official website.

2. Webpack function

At present, it is not clear how to use the second callback parameter.

ConfigureWebpack can only use push?

I tried to create a new webpack-chain myself and return it (merge method, if any). It should be ok to return config.toconfig (), but it didn’t work, so I still use push method

demo

portal

Reference documentation

  • Plug-in Development Guide
  • Vue CLI 3 Uses: Plug-ins and Preset (two)
  • Generate the Webpack configuration using the Webpack-chain chain
  • How to use VUE-CLI 3 preset to Build a Front-end project template based on a Git REPo
  • vuetify
  • Webpack function parameters
  • Webpack Chain Chinese document

–by kazehaiya