当前位置: 首页 > Web前端 > vue.js

了解vuecli背后的流程

时间:2023-03-31 18:35:49 vue.js

vuecreatemy-vue-project执行后会发生什么,依次执行【系统】系统定位到bin/vue.js文件,通过nodebin/vue.jscreatemy-项目文件;[vue.js]bin/vue.js使用commander定义命令选项create,将create命令匹配到create方法(lib/create.js),执行该方法;[create.js]使用lib/create.jsInquirer.js查询用户和配置项目;【Creator.js】根据用户配置生成package.json文件(基础信息,从项目配置中注入对应的开发依赖devDependencies);[Creator.js]执行npmi安装Dependency;(PS:这里封装了常用的npm操作,可以直接复制到自己的项目中使用)【Creator.js】加载vue-cli插件(@vue/cli-service是第一个插件执行);[Generator.js]执行所有插件(执行cli-service插件会生成工程文件结构);[Creator.js]生成README.md文件;以上就是create命令的基本执行流程,如果我们想扩展create方法,比如根据我们定义的模板生成一个目录结构,可以新建一个插件(generator,可以参考cli-service),并在插件中生成自定义目录结构。一、命令执行过程当你在控制台输入npm-v并回车时,到底发生了什么?让我们看看npm命令在哪里。通过执行whichnpm,(不知道which命令的同学可以参考这里:whichoflinuxcommand),可以看到npm命令的可执行文件在/usr/local/bin/npm,打开文件夹查看,是一个替代品,右击“显示原体”(Mac用户方法,其他用户请搜索“软链接”),找到命令:/usr/local/lib/node_modules/npm/bin/npm-cli.js,看到是js代码,相信大家都松了一口气。我们不要急于查看npm-cli.js中的源代码。我们先思考一个问题:Q1:系统是如何找到npm这个命令的可执行文件的?A1:了解which命令的同学都知道,which命令会根据PATH变量中的路径顺序查找可执行文件。执行echo$PATH可以打印出变量内容:/usr/local/bin:/usr/bin:/bin(比如这是我的部分内容,目录之间用':'分隔),所以系统首先会在/usr/local/bin下找到npm可执行文件,将/usr/local/bin/npm链接到/usr/local/lib/node_modules/npm/bin/npm-cli.js。所以调用npm命令相当于执行npm-cli.js。一般来说:在控制台执行命令时,系统会先在环境路径(PATH)中找到可执行文件,然后执行该文件。那么,有同学就好奇了:Q2:系统是如何执行这些文件的(比如上面的npm-cli)?A2:打开npm-cli.js文件,我们看到的第一行代码是:#!/usr/bin/envnode,这行代码有什么用呢?详情请参考:stackoverflow——#!/usr/bin/env有什么用?,大致意思是告诉系统用什么解释器来执行这个文件,比如#!/usr/bin/envnode就是告诉系统npm-cli.js应该由node来执行。所以npm-v相当于node/usr/local/lib/node_modules/npm/bin/npm-cli.js-v。$node/usr/local/lib/node_modules/npm/bin/npm-cli.js-v6.4.1二、npm包构建cli的原理了解了命令执行过程后,我们就可以创建自己的cli命令了。①先写my-cli.js文件:#!/usr/bin/envnodeconsole.log('Hellocli!');②在/usr/local/bin(或PATH中任意路径)下创建一个软链接:ln-smy-cli.jsmy-cli③为my-cli命令添加可执行权限:(如果不添加权限,则会报错bash:/usr/local/bin/my-cli:Permissiondenied)chmod777my-cli④验证效果:$my-cliHellocli!在上面的基础上,虽然我们可以创建自己的命令,但是如果这个命令要给团队使用,大家需要复制my-cli.js文件,创建一个软链接。添加可执行权限非常麻烦。如何将自己的命令分发给别人?让我们进一步探索并创建一个基于npm分发的命令。当我们下载并使用npm模块命令时,我们将执行以下操作:npminstall-g@vue/clivuecreatemy-project在全局安装vue-clinpm模块之后,我们在全局添加了一个新的vue命令。这背后究竟发生了什么?正是npminstall帮我们自动执行了上面提到的②和③步骤(如有错误请指出)。现在npm已经帮我们完成了这些简单但繁琐的脚本操作,我们只需要按照npm规范配置代码即可。过程比较简单,请参考:通过npm包制作命令行工具的原理。总结一下开发过程:npminit新建一个npm模块目录;开发命令(如上面的my-cli.js);将bin字段添加到package.json(bin:{"my-cli":"./my-cli.js"});发布npm;全局安装可以使用my-cli;三、VUE-CLI中的核心库vue-cli源码了解如何优雅的实现一个cli。介绍几个vue-cli中用到的几个库:commander——命令行参数解析库;Inquirer.js——命令行常用交互形式的集合(问答、选择……);chalk——美化命令行风格;ora-命令行加载程序;commander几乎是开发cli必不可少的工具,原理(参考commander源码),基本使用方法如下:#!/usr/bin/envnodevarprogram=require('commander');program。version('0.1.0').option('-p,--peppers','添加辣椒').option('-P,--pineapple','添加菠萝').option('-b,--bbq-sauce','添加烧烤酱').option('-c,--cheese[type]','添加指定类型的奶酪[marble]','marble').parse(process.argv);core流程如下:1.通过option定义采集命令的功能选项;2.parse解析命令参数(进程获取);3.使用命令参数匹配之前收集到的函数选项,执行之前的方法(传入参数);/***解析`argv`,设置选项,定义时调用命令。**@param{Array}argv*@return{Command}用于链接*@apipublic*/Command.prototype.parse=function(argv){//隐式帮助if(this.executables)this.addImplicitHelpCommand();//存储原始参数this.rawArgs=argv;//猜名字this._name=this._name||基名(argv[1],'.js');//github-style没有子命令的子命令if(this.executables&&argv.length<3&&!this.defaultExecutable){//这个用户需要帮助argv.push('--help');}//处理argvvarparsed=this.parseOptions(this.normalize(argv.slice(2)));varargs=this.args=parsed.args;varresult=this.parseArgs(this.args,parsed.unknown);//可执行子命令varname=result.args[0];变种别名命令=空;//检查子命令的别名if(name){aliasCommand=this.commands.filter(function(command){returncommand.alias()===name;})[0];}if(this._execs[name]&&typeofthis._execs[name]!=='function'){returnthis.executeSubCommand(argv,args,parsed.unknown);}elseif(aliasCommand){//是子命令的别名args[0]=aliasCommand._name;返回this.executeSubCommand(argv,args,parsed.unknown);}elseif(this.defaultExecutable){//使用默认子命令args.unshift(this.defaultExecutable);返回this.executeSubCommand(argv,args,parsed.unknown);}返回结果;};