preface

If you are using the Vue framework, then you certainly know what the Vue CLI is. Vue-cli 3, which is the standard tool (scaffolding) for vue.js development and provides project scaffolding and prototyping.

In addition to daily build packaging projects, an important part of Vue CLI3 is cli-plugins, plug-in development.

This article will teach you how to create one scientificallyVue - CLI plug-in, and project independencenpmThe package.

1. What isCLI plugin

It can modify the internal Webpack configuration and inject commands into vue-cli-service. A good example is @vue/cli-plugin-typescript: When you call it, it adds an app.vue type to your project from tsconfig.json and changes the app.vue type. The whole process doesn’t have to be performed manually.

Plug-ins are very useful, but there are many different cases: Electron builders, adding UI libraries such as iView or ElementUI…. What if you want to provide a plugin for a particular library but it doesn’t exist? In this case, it’s a good idea to build a plug-in for your own project.

In this article, we will build a Vue-cli-plugin-rx. It allows us to add vue-Rx libraries to our projects and get RxJS support in our VUE applications.

2. Vue- CLI plug-in directory structure

The CLI plug-in is an NPM package that can add additional features to @vue/ CLI projects. It should always contain:

  • aServicePlug-in as its main export
  • Optional contains oneGeneratorAnd aPromptFile.
.├ ─ Readme.md ├─ Generator.js# Generator (optional)├ ─ ─ prompts. Js# Prompt file (optional)├ ─ ─ index. Js# service plug-in└ ─ ─ package. JsonCopy the code

If you need to select whether to create some sample components from the command line at the same time as the plug-in installation, the directory can be changed to:

.├ ── readme.md ├── generator │ ├─ index.js# generator├ ─ ─ prompts. Js# Command line prompt installation├ ─ ─ index. Js# service plug-in└ ─ ─ package. JsonCopy the code

2.1 GeneratorAPI

A CLI plug-in published as an NPM package can contain a generator.js or generator/index.js file. The generator in the plug-in will be called in two scenarios:

  • During the initial creation of a project, ifCLIThe plug-in is created as a projectpresetIs installed.
  • The plug-in is passed after the project is createdvue invokeIs installed when called independently.

The GeneratorAPI allows a generator to inject additional dependencies or fields into package.json and to add files to the project.

2.2 Service plug-in

The Service plug-in takes a function that takes two arguments: a PluginAPI instance and an object that contains the project’s local options. It can extend/modify the internal Webpack configuration for different environments and infuse it with other commands vue-cli-service.

But here, we just want to add a few dependencies and sample components as necessary. So our index.js looks like this:

module.exports = (api, opts) => {}
Copy the code

If you want to change the internal Webpack configuration or other operations, please read this section in the official Vue CLI documentation

2.3 Package. Json

Keywords specify what keywords can be found in a library search, so it’s usually a little bit more item-related in this case, it’s an array of strings.

{
  "name": "vue-cli-plugin-rx"."version": "1.0.0"."description": ""."main": "index.js"."keywords": [
    "vue"."vue-cli"."rxjs"."vue-rx"]."author": ""."license": "ISC"
}
Copy the code

3. Add dependencies using the Generator

The Generator helps you add dependencies and change project files. So, the first step we need is to have our plugin add dependencies: RXJS and vue-rx (you can also add others) :

// generator/index.js
module.exports = (api, options, rootOptions) => {
  api.extendPackage({
    dependencies: {
      'rxjs': '^ 6.3.3'.'vue-rx': '^ 6.1.0',}}); }Copy the code

The generator exports a function that takes three arguments: the GeneratorAPI instance, the generator option, and – if the user creates the project with a preset – the entire preset is passed as the third argument.

The API. ExtendPackage method will modify the project’s package.json.

In the example in this article, we add two dependencies to Dependencies.

Now we need to change the main.js file. To make RxJS work in the Vue component, we need to import VueRx and call vue.use (VueRx).

  • First, we create a string that we want to add to the main file:
let rxLines = `\nimport VueRx from 'vue-rx'; \n\nVue.use(VueRx); `;Copy the code
  • useapi.onCreateCompletehook. It is called when the file is written to disk:
api.onCreateComplete(() => {
    const fs = require('fs');
    const mainPath = api.resolve(' './src/main.js');
};
Copy the code
  • Now we modify the contents of the file:
api.onCreateComplete(() => {
    const fs = require('fs');
    const mainPath = api.resolve('./src/main.js'); // Get the contentlet contentMain = fs.readFileSync(mainPath, { encoding: 'utf-8'}); const lines = contentMain.split(/\r? \n/g).reverse(); // import const lastImportIndex = lines.findIndex(line => line.match(/^import/)); lines[lastImportIndex] += rxLines; ContentMain = lines.reverse().join()'\n');
    fs.writeFileSync(mainPath, contentMain, { encoding: 'utf-8' });
  });
};
Copy the code

4. Test the cli-plugin locally

First let’s create a simple vue-cli project:

vue create test-app
Copy the code

CD to the project folder and install our newly created plug-in:

cd test-app NPM install --save-dev file://Users/hiro/ exercise/test /vue-pluginCopy the code

After installing the plug-in, you need to call it:

vue invoke vue-cli-plugin-rx
Copy the code

Now, if you look at main.js for the test-app project, you will see:

import Vue from 'vue'
import App from './App.vue'
import VueRx from 'vue-rx';
Vue.use(VueRx);
Copy the code

In the meantime, looking at package.json will reveal:

"dependencies": {
    "core-js": "^ 2.6.5." "."rxjs": As per paragraph 6.3.3 of ^."vue": "^ 2.6.10"."vue-router": "^ 3.0.3." "."vue-rx": "^ 6.1.0"."vuex": "^ 3.0.1." "
  }
Copy the code

5. Create sample components using the Generator

After the above verification, the plug-in is valid. At this point, we can extend its functionality and create sample components that others can easily understand and use.

5.1 Writing sample components

This sample component we created. It should be a file in the SRC/Components folder of the project.

So we can be in the generator directory, create/template/SRC/components:

This is a simple RxJS driven counter with two buttons

<template>
    <section>
        <h1>Click on 'Count' button to count your clicks</h1>
        <button v-stream:click="count$">Count clicks</button>
        <button @click="clearCounter">Clear counter</button>
        <p>{{result$}}</p>
    </section>
</template>

<script>
import {
  filter,
  bufferWhen,
  debounceTime,
  map,
  startWith,
} from 'rxjs/operators';
export default {
  domStreams: ['count$'].subscriptions() {
    return{ result$: this.count$.pipe( filter(event => !! event), bufferWhen(() => this.count$.pipe(debounceTime(400))), map(clicks => clicks.length), startWith(0), ), }; }, methods: {clearCounter() { this.count$.next(null); ,}}}; </script> <style> button { padding: 10px; font-size: 14px; margin-right: 10px; border-radius: 4px; outline: none; } </style>Copy the code

Don’t worry about what RxJS did (I didn’t understand it anyway), it’s vans.

At this point we need to change generator/index.js so that it recognizes and writes to the folder.

api.render('./template', {
  ...options,
});
Copy the code

When you callapi.render('./template')When,generatorWill useEJSApply colours to a drawing./template(as opposed togeneratorTo parse the file path in

5.2 Cli Prompt Installation

What if the user is a veteran and doesn’t want to own the sample component? Prompts During plug-in installation, we can add prompt code to prompts that the user can take on the command line:

module.exports = [
  {
    name: `addExample`,
    type: 'confirm',
    message: 'Do you want to add sample components to the project Components directory? ',
    default: false,},];Copy the code

Ask the user if you want to add the sample component to the project Components directory. The default value is false.

At this point we need to modify generator/index.js:

if (options.addExample) {
    api.render('./template', {
      ...options,
    });
}
Copy the code

Yarn add --save-dev file://Users/hiro/ exercise/test /vue-plugin vue invoke vue-cli-plugin-rx. Yarn add --save-dev file://Users/hiro/ exercise/test /vue-plugin vue invoke vue-cli-plugin-rxCopy the code

You will see:

components

6. How do I publish plug-ins

From official documents

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

. After the plugin follows the naming convention:

  • be@vue/cli-serviceDiscovery.
  • Being searched by other developers;
  • throughvue add <name>orvue invoke <name>Install it.

You just need to add the description in package.json and create logo.png in the plug-in project root directory.

The next step is to sign up for npmjs.com

2, set the warehouse address to NPM official warehouse address (most domestic use Ali Taobao mirror, if not changed to publish will fail) NPM configsetRegistry https://registry.npmjs.org/ 3, landing NPM, the user name Password E-mail all need to match the NPM whoami NPM login Username: XXXXX Password: Email: (this IS public) [email protected] LoggedinAs XXXXX on https://registry.npmjs.org/. 4, after landing can publish, execute the following commandcd dist && npm publish && cd. / or NPM Publish dist If the following information is displayed, the project is published successfully. + [email protected] Log in to https://www.npmjs.com/ to view the published projectCopy the code

Finished.

conclusion

Vue-cli plugin development. For many projects, when you need to introduce some components or features you’ve written before, but don’t want to copy main.js and package. json, this is a quick way to develop. When someone asks you how to organize your project’s component libraries, TSK… You said you were installing your own plugins.

A collection of the author’s nuggets

  • “Vue Practice” 5 minutes for a Vue CLI plug-in
  • “Vue practices” arm your front-end projects
  • “Advanced front end interview” JavaScript handwriting unbeatable secrets
  • “Learn from source code” answers to Vue questions that interviewers don’t know
  • “Learn from the source code” Vue source code in JS SAO operation
  • “Learn from source code” thoroughly understand the Vue option Props
  • “Vue Practice” project to upgrade vue-CLI3 correct posture
  • Why do you never understand JavaScript scope chains?

The public,