前言如果你正在使用Vue框架,你可能已经知道什么是VueCLI。是一套完整的Vue.js快速开发系统,提供项目脚手架。CLI的一个重要部分是cli-plugins。他们可以修改内部webpack配置并将命令注入vue-cli服务。一个很好的例子是@vuecli-plugin-typescript:当你调用它时,它会在你的项目中添加一个tsconfig.json,并更改App.vue的类型,所以你不需要手动进行。插件非常有用,但是如果你想为某个特定的库安装一个插件但它不存在怎么办?好吧,当我们遇到这种情况时……我们决定自己建造它。在这篇文章中,我们将构建一个vue-cli-plugin-tiantian。它允许我们将vue-rx库添加到我们的项目中,并在我们的Vue应用程序中获得RxJS支持。让我们看一下大概的流程。Vue-CLI插件结构首先,什么是CLI插件?它只是一个具有一定结构的npm包。关于文档,它必须有一个服务插件作为它的主要出口,并且可以有额外的功能,如生成器和提示文件。目前,还不清楚什么是服务插件或生成器,但别担心——稍后会解释!当然,就像任何npm包一样,CLI插件的根文件夹中必须有一个package.json,最好是带有一些说明的README.md。因此,让我们从以下结构开始。.├──README.md├──index.js#serviceplugin└──package.json现在让我们看看可选部分。生成器可以在package.json中注入额外的依赖项或字段,并将文件添加到项目中。我们需要它吗?当然,我们希望将rxjs和vue-rx作为我们的依赖项。更准确地说,如果用户想在安装插件时添加它,我们想创建一些示例组件。所以我们需要添加generator.js或者generatorindex.js。我更喜欢第二种方式。现在的结构是这样的:.├──README.md├──index.js#serviceplugin├──generator│└──index.js#generator└──package.json提示文件。我希望我的插件能够询问用户是否想要一个示例组件。我们需要在根目录中有一个prompts.js文件来实现此行为。所以,目前的结构是这样的:服务插件(Serviceplugin)一个服务插件应该输出一个函数,它接收两个参数:一个PluginAPI实例和一个包含项目本地选项的对象。它可以针对不同的环境扩展修改内部webpack配置,并向vue-cli-service注入额外的命令。让我们考虑一下:我们是想以某种方式更改webpack配置还是创建一个额外的npm任务?答案是否定的,我们只是想在必要时添加一些依赖项和示例组件。因此,我们需要在index.js中更改的是:module.exports=(api,opts)=>{}如果您的插件需要更改Webpack配置,请阅读VueCLI官方文档中的这一部分。https://cli.vuejs.org/dev-guide/plugin-dev.html#service-plugin通过生成器添加依赖上面提到了CLI插件生成器可以帮助我们添加依赖和更改项目文件。因此,我们需要做的第一步是为我们的插件添加两个依赖项:Rxjs和vue-rx:module.exports=(api,options,rootOptions)=>{api.extendPackage({dependencies:{'rxjs':'^6.3.3','vue-rx':'^6.0.1',},});}生成器应该输出一个接收三个参数的函数:GeneratorAPI实例、生成器选项以及——如果用户创建带有一些预设的项目——整个预设将作为第三个参数传递。api.extendPackage方法扩展项目的package.json。除非您将**{merge:false}**作为参数传递,否则嵌套字段将被深度合并。在我们的例子中,我们想将两个依赖项添加到依赖项部分。现在我们需要更改一个main.js文件。为了让RxJS在Vue组件中工作,我们需要导入一个VueRx并调用Vue.use(VueRx)。首先,让我们创建一个要添加到主文件的字符串:letrxLines=`\nimportVueRxfrom'vue-rx';\n\nVue.use(VueRx);`;现在我们要使用api.onCreateComplete钩子函数。文件写入磁盘时调用:api.onCreateComplete(()=>{//injecttomain.jsconstfs=require('fs');constext=api.hasPlugin('typescript')?'ts':'js';constmainPath=api.resolve(`./src/main.${ext}`);};这里我们要找的是main文件:如果是TypeScript工程,就是??main.ts,否则就是将main.jsfile.fs这里是文件系统现在让我们更改文件内容:api.onCreateComplete(()=>{//injecttomain.jsconstfs=require('fs');constext=api.hasPlugin('typescript')?'ts':'js';constmainPath=api.resolve(`./src/main.${ext}`);//getcontentletcontentMain=fs.readFileSync(mainPath,{encoding:'utf-8'});constlines=contentMain.split(/\r?\n/g).reverse();//injectimportconstlastImportIndex=lines.findIndex(line=>line.match(/^import/));lines[lastImportIndex]+=rxLines;//modifyappcontentMain=lines.reverse().join('\n');fs.writeFileSync(mainPath,contentMain,{encoding:'utf-8'});});;我们正在读取的内容主文件,把它分成几行,然后恢复它们命令。然后我们用import语句搜索第一行并在那里添加我们的rxLines。在此之后,我们反转行数组并保存文件。在本地测试CLI插件让我们在package.json中添加一些关于我们插件的信息,并尝试在本地安装它以进行测试。最重要的信息通常是插件名称和版本(将插件发布到npm时需要这些字段),请随时添加更多信息!可以在此处找到package.json字段的完整列表。这是我的文件:{"name":"vue-cli-plugin-tiantian","version":"xxx.1.5","description":"Vue-cli3pluginforaddingRxJSsupportXXXX","main":"index.js","keywords":["vue","vue-cli","rxjs","vue-rx"],"author":"TianTian","license":"MIT",}现在是时候检查我们的方法了该插件有效!为此,我们创建一个由vue-cli提供支持的简单项目:vuecreatetest-app转到项目文件夹并安装我们新创建的插件。cdtest-appnpminstall--save-devfile:/full/path/to/your/plugin//填写安装插件的路径后,你需要调用它:vueinvokevue-cli-plugin-rx现在,如果你尝试检查main.js文件,你可以看到它已经改变了。importVuefrom'vue'importAppfrom'./App.vue'importVueRxfrom'vue-rx';Vue.use(VueRx);此外,您可以在测试应用的package.json的devDependencies部分找到您的插件。使用生成器创建新组件当您的插件正常工作时,是时候稍微扩展它的功能以便创建示例组件了。现在是扩展其功能并使其能够创建示例组件的时候了。GeneratorAPI为此使用render方法。首先,让我们创建这个示例组件。它应该是位于项目的src/components文件夹中的.vue文件。在generator文件夹下创建一个template文件夹,然后在里面模拟整个结构:projectdirectory假设,你的示例组件应该是一个Vue的单文件组件,篇幅有限,本文深入讲解RxJS。因此创建了一个简单的RxJS驱动的点击计数器,带有两个按钮,如下所示:button现在,我们需要指示插件在调用时呈现此组件。为此,我们将以下代码添加到generator/index.js:api.render('./template',{...options,});这将呈现整个模板文件夹。现在,当插件被调用时,一个新的RxExample.vue将被添加到src/components文件夹中。通过提示处理用户选择如果用户不想使用示例组件怎么办?让用户在插件安装期间决定这一点不是明智之举吗?这就是提示存在的原因!我们之前在插件根目录下创建了提示。.js文件。该文件应包含一系列问题:每个问题都是一个对象,其中包含某些字段,例如名称、信息、选项、类型等。名称很重要:稍后我们将在生成器中使用它来创建条件来呈现示例组件。提示可以有不同的类型,但CLI中使用最广泛的是复选框和确认。我们将使用后者来创建一个答案为“是”的问题。那么让我们在prompts.js中加入提示代码吧!module.exports=[{name:`addExample`,type:'confirm',message:'Addexamplecomponenttocomponentsfolder?',default:false,},];我们有一个addExample提示,询问用户是否要将组件添加到组件文件夹。默认答案是“否”。让我们回到生成器文件并进行一些更正。将对api.render的调用更改为:if(options.addExample){api.render('./template',{...options,});}我们正在检查addExample是否有肯定的答案,如果有,该组件将被渲染。不要忘记在每次更改后重新安装和测试您的插件!发布值得我们注意:在发布插件之前,检查其名称是否与模式vue-cli-plugin-
