世界就像一个巨大的图书馆,我们读着别人,做着自己,等待被读。 :

前端框架Vue自学之Vue CLI(五)

终极目标:掌握和使用Vue(全家桶:Core+Vue-router+Vuex)

本博客目的:记录Vue学习的进度和心得(Vue CLI)

内容:学习和使用Vue CLI2 和 Vue CLI3。如果了解webpack如何一步步配置的,建议可以先看我的前一个博客:前端框架Vue自学之webpack(四)

正文:

Vue CLI 

一、Vue CLI 

  1、前言

  前面(上一个博客)中,学习webpack的相关知识,知道webpack的一些配置,最后知道如何把生产配置和开发配置进行分离。

  如果只是写几个vue的demo,则是不需要vue CLI的。在实际开发(大型项目)中,我们一般不会重头到尾写webpack的配置,我们会通过一个工具,叫脚手架,自动生成我们weback的配置,提升我们的工作效率。

  CLI(command-line interface,命令行界面,俗称脚手架(软件工程学引用这个建筑学概念)),其含义很简单。举个例子,当我们要写一个项目1,用了ES6的JavaScript,LESS的CSS扩展语音,后端使用node。我们每次写完一个功能,都需要把ES6转为ES5,编译LESS,压缩JS等操作。每次修改代码都要做的这些操作属于重复性工作。后来,我们学习了webpack或者是gulp,写了webpack脚本(webpack配置),每次有代码改动,只需在终端输入webpack等就可以自动完成上述的重复性工作,我们写的webpack脚本就是为了减少重复性工作。但是,我们写完这个项目1还得写项目2,项目3等,我们每次都用相同的技术栈,每次的webpack脚本都大同小异,这个时候,写这么多的webpack脚本,也是一种减少重复性工作的重复性工作

  而脚手架就是可以帮我们解决这个问题的工具。脚手架一个命令,目录结构、webpack脚本、babel配置、空的测试文件都帮我们搞好了. 直接写核心业务代码,不做重复性工作,这就是脚手架的作用。当然不同的技术的技术栈会有自己的目录结构、工作流程,例如我们前端框架比如vue、angular、react会有自己的脚手架(XXX-CLI)。现在我们就来学习一下vue CLI。

   2、vue cli及使用前提

   在使用vue.js开发大型应用时,我们需要考虑代码目录结构,项目结构和部署、热加载、代码单元测试等事情。如果每个项目都要手动完成这些工作,那无疑效率比较低的,所以通常我们会使用一些脚手架工具(Vue CLI)来帮助我们完成这些事情。

  Vue CLI是一个官方发布vue.js项目脚手架,使用vue-cli可以快速搭建Vue开发环境以及对于的webpack配置。

  由于webpack是依赖于node环境,所以Vue CLI也是依赖node环境。在使用Vue CLI前,需要安装NodeJS(可在Node官网下载安装),Node环境要求8.9以上。Node安装好了之后,是自带软件包管理工具npm,npm是一个NodeJS包管理和分发工具,以及成为了非官方的发布Node模块的标准。后续我们会经常使用npm来安装一些开发过程中依赖包。 

  Vue.js官网脚手架工具就使用了webpack模板,对所有的资源会压缩等优化操作,它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效。webpack的全局安装,是通过在终端输入npm install webapck -g。

  3、Vue CLI的使用

  首先安装Vue CLI脚手架。在终端输入 npm install -g @vue/cli ,它是全局安装(一般不需要本地安装)。这个是一个脚手架Vue CLI3(可能2019年年底的版本已经到4.1.1,不过也没关系。因为我学的时候用的是3.2.1版本,所以也可以指定版本npm install -g @vue/cli@3.2.1),我们先学脚手架2,安装3版本也没事,因为我们可以在脚手架3的基础上拉取一个脚手架2的模板使用即可当做脚手架2。

  注意,如果安装的太慢,可以借助将npm的仓库地址改为淘宝镜像(输入npm config set registry https://registry.npm.taobao.org --global  和 npm config set disturl https://npm.taobao.org/dist --global),之后再安装(速度飞起)。然后可以通过vue --version查看自己安装的版本。

   由于我们先学习一下Vue CLI2。现在,我们得拉取Vue CLI2的模板。终端输入npm install -g @vue/cli-init(# `vue init` 的运行效果将会跟 `vue-cli@2.x` 相同)。这个时候我们既可以使用Vue CLI3,也可以使用Vue CLI2了。

  Vue CLI2初始化项目,在对应的目录下,终端输入 vue init webpack my-project(my-project是项目名称)即可,接着可能会有很多选项,我们在下一小节具体详细说明。

  补充:Vue CLI3初始化项目是通过vue create my-project(后续会使用到的)。

   4、vue-cli2初始化项目过程

  首先cd到某个目录,然后终端输入vue init webpack vuecli2test(最终会创建名为vuecli2test,在里面初始化项目目录和文件),此时会下载一些模板(download template),之后会有一些选项给我们选择,具体有:(这些项目信息最终会保存在package.json里面)

  project name (vuecli2test),输入项目名称,如果直接回车会默认是一原来项目文件夹名vuecli2test为项目名,但不能包含大写字母等。即括号里面的内容是默认信息,如果直接回车会自动填充。

  project description(A Vue.js project),描述信息,这里我们填写为 test vue cli2

  Author,作者名。如果我们之前有配置全局的.gitconfig,这里也会有默认的作者信息。

  Vue build(Use arrow key),它是提示我们编译模式是选择runtime-only还是runtime-compiler,因为之前(上个博客)说过,runtime-only要求代码中,不可以有任何的template,因为这个版本没有编译template的代码,但是其大小很小(少6kb),运行效率高。runtime-compiler中可以有template,因为有complier可以用于编译template。这里我们先不管编译template的问题,先选runtime-compiler,后续我们会继续分析两者的。

  Install vue-router,是否安装vue路由。在大型项目中,我们通常都会使用vue的全家桶,即VueCore+vue-router+vuex(vue内核+vue路由+vue状态管理工具)。如果我们选择安装,则后续可以直接使用这个路由,因为脚手架已经帮我们安装好了。这里,我们先不安装。

  Use ESLint to lint your code,是否使用ESLint。 ESLint对JS进行规范检查,如果我们写的JS代码不规范就会编译不通过。如果选择使用,会出现pick an ESLint preset,要你选择一种规范(Standard,Airbnb,自定义规范)。这里我们选先不使用。如果不小心使用了,也可以在config的index.js文件中的UseEslint改为false即可。

  Set up unit tests,设置单元测试。如果安装单元测试,可能还得需要一些第三方的测试框架。单元测试会提供很多断言,来对我们某些模块进行单独的测试。这里我们先选不设置。

  Setup e2e tests with Nightwatch,设置端到端(end to end)测试并安装Nightwatch。Nightwatch是一个利用selenium或webdriver或phantomjs等进行自动化测试的框架。一般是测试人员会使用到这个东西。我们这里先选no。

  Should we run `npm install` for you after the project has been created(npm,yarn,自己管理),选择管理工具。我们这里选npm。

  选择完之后,会自动根据我们的选择进行项目初始化。初始化完成之后,就生成了我们的项目目录。

  

  5、Vue CLI2的目录结构解析

  上一小节中,我们用Vue CLI2初始化了我们的项目,这里生成了多目录,形成了一个目录结构,我们来一个一个了解一下。

  首先,项目里面有build文件夹config文件夹。里面都是webpack打包和配置的文件。在面对这么多的文件的时候,我们不要一个一个看,先打开我们的package.json,看scripts脚本(就是在终端通过npm run XXX执行的对应脚本),里面有我们dev,start,build。其中,"build": "node build/build.js"(node是可以执行js文件的,这里执行的是 build文件夹的build.js),我们可以打开 build文件夹的build.js,观察细节。build.js文件大致思路是,首先引入各种包,每次执行npm run build时,先把之前打包创建的dist删除(remove),然后根据./webpack.prod.conf的webpack配置进行打包。./webpack.prod.conf这个文件是生成版本的webpack配置,查看源码,发现之前跟我们之前讲的webpack配置文件分离(在我之前的博客),把基本公共配置与生产独有的配置进行合并。基本公共配置里有很多webpack的插件,例如抽离组件的CSS等。而开发webpack配置,运行的是build文件夹内webpack.dev.conf.js,也是把基本公共配置与开发调试的配置合并而成的。config文件夹内的文件也是配置文件,定义一些全局变量,端口号等和一些开发配置和生产配置。(可见,如果我们一个一个配置这些文件非常繁琐,而使用脚手架就大大帮助了我们,某些配置不满意,我们也可以自己去修改它,非常方便

  补充:node是用C++开发的,其核心是Chrome V8引擎(使得JS直接生成二进制码再到浏览器运行,之前是生成字节码,运行速度没前者快),为我们的JS提供运行环境。以前的JS运行查看结果,是得通过将其引入到HTML文件中,通过浏览器打开这个HTML文件,查看JS一些结果。后面有人想用JS开发服务器,但是因为服务器没有浏览器,困难重重,之后Ryan Dahl基于Chrome V8引擎开发node。node能够使用V8引擎解析JS做服务器的底层支撑,所以只要装了node,就可以通过node在我们电脑执行我们的JS代码。 

  node_modules文件夹,这个是我们当前项目很多依赖的包。具体有什么的呢?我们可以通过package.json的devDependences和dependencies选项来看,devDependences(开发依赖)里面有很多依赖,而dependencies(运行依赖)只有一个vue。  

   src文件夹。里面放开发源码。我们写的代码都在里面。

  static文件夹。里面放入静态资源。这个静态资源最后打包的时候,会原封不动的打包到dist文件夹内。

  .babelrc文件。 ES6转为ES5的一些相关配置。

  .editorconfig文件。对我们写的代码格式进行统一,例如缩进,换号等。在大公司里,一般项目代码编写格式都是有要求的。

  .gitignore文件。当你上传一些文件的时候,规定一些不用上传的文件。

  .postcssrc.js文件。CSS进行转换的时候一些配置的东西。

  index.html文件。一个HTML模板,最后打包的时候是根据这个HTML文件,创建打包文件到build目录下的dist文件夹内。

  package.json文件。管理node包里面相关的东西,还有一些信息管理。

  package-lock.json文件。因为有时候node安装一些包的版本可能是在package.json规定以上的版本,package-lock.json文件是真实记录实际安装在node_modules的版本。

  README.md文件。一些说明文档。

  6、runtimecompiler和runtimeonly的对比

  其区别只在main.js里面。

  (图左是runtimecompiler,图右是runtimeonly)

    runtimecompiler中,使用APP是现在components注册,然后在template中使用这个组件作为模板。结合vue程序运行过程,当使用template时,其会先保存在vue实例的options里面,然后parse(解析)为ast(abstract syntax tree,抽象语法树,是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示在源代码中出现的构造。),然后其会complier编译成render渲染函数,接着会渲染一些虚拟节点,最后构成为虚拟DOM树(virtual DOM),最后更新,构造真实的DOM(真实的UI)。所以在untimecompiler中,是template -> ast -> render -> vdom -> UI。

  runtimeonly中,使用APP是通过render渲染函数(并用ES6的箭头函数语法),h函数是vue用于把vdom转换为dom节点。结合vue程序运行过程,其是render -> vdom -> UI。其步骤比runtimecompiler少,即代码少,性能更高。这也是为什么之前在脚手架构建项目的时候,说runtimeonly比runtimecompiler更小的原因。所以,以后我们的开发,一般选择runtimeonly

  (vue程序运行过程如下图所示:)

   render函数是可以用在原来写的runtimecompiler的main.js里面,之前的runtimecompiler的template模板就是替换其el挂载的HTML元素,而render函数可以代替template,用createElement函数,生成对应标签,标签的属性,数组(放置标签内的内容,甚至可以是createElement函数)(接着替换其el挂载的HTML元素)。render函数可以使用组件(代替之前template和components的组合用法),就是把组件传入createElement里面。(上述这样做相当于没了template转ast,再转为render的步骤,其实就是runtimeonly的main.js的写法)

  但是我们会有所疑惑,在runtimeonly的main.js中,render函数里引用的组件(如APP)是从vue文件引用的,而vue文件里面不是也有template标签吗?所以是不是得先解析为ast,再编译为render呢?其实不是的。vue文件中的template最终会编译为一个普通的对象,已经渲染为render函数了(内部是通过webpack配置安装好的vue-template-compiler loader解析编译的,所以我们一般使用runtime-only也是包含这个loader的,很方便)。

  (npm run build的内部逻辑图)

    (npm run dev的内部逻辑图)

   7、Vue CLI3创建项目和目录结构

  vue-cli3 与2版本有很大区别。vue-cli3是基于webpack4打造,vue-cli2还是webpack3;vue-cli3的设计原则是“0配置”,移除的配置文件根目录下的build和config等目录;vue-cli3提供了vue ui 命令,提供了可视化配置,更加人性化;移除了static文件夹,新增了public文件夹(相当于static,里面的文件也是原封不动的会打包到dist文件夹内),并且index.html移动到public中。

  Vue CLI3创建项目,终端输入 vue create testvuecli3 (是项目名称),会出现一些选项:

  please pick a preset(default,Manually select features),选择预配置。我们选第二个手动选择。

  check the features needed for your project,选择我们项目需要的选项。这一步出现了很多项,我们可以按空格去选择。这里我们只需要Babel。(PWA,渐进式增强WEB应用。有一些缓存、推送和通知等功能,很灵活,但目前国内用的比较少)

 

   Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (In dedicated config files, in package.json)这是让我们选择这些配置文件放在独立的文件还是packa.json里面。这里,我们选择单独文件。 

 Save this as a preset for future projects,保存当前的预配置。选择yes。

 save preset as,配置名字。随便输入,这里我输入wu。

 此时完成了项目创建和预配置。注意,当我们第一次创建好项目,在以后创建项目时,会出现我们之前创建过的预配置供我们选择。例如我刚刚创建的预配置是wu,这里新项目的配置也有这个预配置。当选择这个wu预配置,项目就可以自动按照配置创建工程了。(如果我们日后想删除这个配置,可以在终端输入vue config 找到这个预配置文件,将其删除)

  

     如果安装的git,用vuecli3创建工程时,会有.git文件夹(本地仓库),当在终端输入git相关命令,可以进行git操作。

  此时,目录有了一些改变(相对于vue cli2),看上去更加简洁了,但主要文件的功能和脚手架2差不多。

  

  查看package.json的scripts选项,里面开发测试时用npm run serve,打包是npm run build。

  

  此外,在入口文件main.js中,Vue.config.productionTip 的意思是在发布一个产品,在构建的时候给我们提示一些信息。在开发调试时是不需要的,所以让Vue.config.productionTip = false。main.js中,是通过.$mount('#app')取代el:'#app',来挂载id为app的HTML元素,其实没有差别,最终其都会被render函数渲染替换掉。

  8、Vue CLI3配置文件的查看与修改

  在vue CLI3查看配置有三种方案:

  第一种,启动配置(本地)服务器:vue ui(终端输入)。之后会启动GUI(图形用户界面)和打开一个浏览器窗口,里面可以创建项目,导入项目等。    

 

    当选择导入我们刚用vue CLi3创建的项目文件夹时,左边会出现项目仪表盘,插件,依赖,配置,任务等选项,点开我们可以看到很多细节信息并且可以添加插件,安装依赖等。其中,在项目配置中,可以发现启动运行时编译选项是关的,即默认选择的时候runtime-only,在main.js中的代码也证实了这一点(因为没有使用template)。

    第二种,查看node_modules文件夹。由于在package.json中发现,一些webpack依赖,在Vue CLI3中是通过@vue/cli-service和@vue/cli-plugin-babel这两项来封装管理的。所以,我们可以打开node_modules文件夹的@vue文件夹中的cli-service文件夹的webpack.config.js,发现其是引用./lib/Service的js文件,这就是真正的配置的webpack文件(Service.js也有引入其他公共配置,开发配置等)。

  第三种,创建vue.config.js文件(根目录下)。当我们需要修改某些配置的时候,需要在根目录下创建vue.config.js文件(名字不能换),文件里面通过module.exports={XXX}导出一些配置。其最后会和之前说的@vue中的一些配置进行合并。

  

posted @ 2019-12-18 16:53  Secret_Wu  阅读(685)  评论(0编辑  收藏  举报