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 created
vue invoke
Is 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:
- Change the user’s Webpack configuration file (i.e. Vue.config.js)
- Register instructions with cli-service
- 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