vue-cli2.x 的使用与项目结构分析

vue-cli是vue官方提供的一个前端脚手架,专门用于快速构建一个单页面web应用,自动生成基于vue + webpack的项目模板。

基本使用

引入vue-cli

  • 全局引入vue-cli2.x

    npm install -g vue-cli
  • 引入完成检测

    vue --version
  • 注:区别于vue-cli3.x的引入方法

    npm install -g @vue/cli

创建项目

  • 在所需目录下,创建一个基于vue + webpack的前端项目

    vue init webpack <project-name>
  • 根据提示配置信息后创建完成

    vueclidemo

代码结构

代码目录

代码文件构成

首先来看main.js的内容,这也是整个项目代码部分的入口。其功能,就是创建了一个Vue实例,并且引入了名为App的入口组件。这也是整个项目唯一一次创建Vue实例。在这点上可以有些理解:

  • 作为一个单页面应用的脚手架,项目构建的页面就只有一个Vue实例。若在浏览器或者客户端下打开新的页面,则两个页面属于两个不同的实例。

  • Vue文件本身就是一个实例,但同时也可以被注册成为Vue组件(component)被其他组件所引入,而作为组件引入时,不将其视为一个实例看待。

  • vue-cli的Vue实例挂载在id为app的dom上,这一点我们也可以在入口文档index.html中看到。

  • 实例引入的App组件,相当于一个根节点,通过router将不同界面串在一起,构成一棵树。不同界面下也可以引入新的组件,组件之间可以进行通信等操作。

那么再来看一下main.js中反复提及的App组件与router:

App.vue其实就是一个正常的Vue文件,上述代码给出了代码模板的部分,vue-cli作为官方脚手架很自然的引入了一个Vue的logo,当然这肯定得直接去掉。然后就是router标签,可以在上文main.js里看到,在Vue实例创建的时候就全局挂载了router,所以App.vue不再需要引入什么文件就可以直接使用router,这与Vuex同理。

router部分则就是vue-router的引入、使用,以及注册在router上的Vue组件的配置,vue-cli默认会注册一个HelloWorld组件,我们可以在components下面找到,这个HelloWorld也算是官方给出的一个Vue文件的标准写法。

基础配置

Vue入口与基本的代码结构清楚之后,再来看config目录下的基础配置,文件目录如下:

开发环境与生产环境的配置其实就是在两个环境下设置不同node的全局变量来区分两个环境

那么看了代码后很容易就有一个疑问,为什么开发环境要多此一举地用 webapck-merge,直接和生产环境一样的写法不是更好?

  • 其实光看默认给的代码,确实是多此一举,但真正在开发的时候,两个环境下必然存在其他的配置,使用 webpack-merge 后,在生产环境添加的配置,就不用在开发环境再添加一遍,节省了时间,提高了容错率。而开发环境特有的配置只需在开发环境的配置中添加即可。

  • 当然有个问题是这个写法没法为生产环境提供特有的配置,但是在实际生产中,其实生产环境需要的配置往往在开发环境下也是必要的,这也是为什么要把merge加在开发环境下的原因。

接下来是基础配置下的 config/index.js 文件,所谓的基础配置,其实也是webpack中的部分配置和打包脚本的部分配置。config/index.js 文件中的内容,更倾向于面向开发人员的个性配置。那么直接来看代码。

整体来看,就配置了 dev 与 build ,也就是上文说的 webpack 开发环境部分和打包脚本部分的面向开发的配置。其实从引入角度也可以看出来。

vuecliconfigdev

dev 的配置重点在 webapck.dev.conf.js 内进行了使用,下文也会提及。而在其他文件中的使用,就都是配合条件运算符(?:)区分环境来使用的。再看dev 部分的代码。

vuecliconfigbuild

build 则重点在 webpack.prod.conf.js 内进行了使用,而其他地方的使用其实都是在条件应算符下与dev相对应的选择。所以打包的配置同时也可以说是生产环境的配置。

webapck配置

webpack配置位于build文件夹下,具体目录如下

webpack.base.conf.js

那么从 webpack 基础配置开始入手,开发环境和生产环境的 webpack 配置无非就是根据环境区分后,一同 merge 至基础配置上的。

先看开头部分,引入了 node 模块 path,同目录下的 util.js (工具类方法) 与 vue-loader.conf.js (vue-loader配置模块),以及上文基础配置中提到的 config/index.js。

另外封装了 path.join() 的方法,这边简单提一下path内部的方法与参数:

  • path.resolve([from...],to) - 把一个路径或路径片段的序列解析为一个绝对路径。相当于执行cd操作。

  • path.join(path1,path2,path3.......) - 将路径片段使用特定的分隔符( window: )连接起来形成路径,并规范化生成的路径。若任意一个路径片段类型错误,会报错。若某个片段为 '..',则会回到目录的上一级。

  • __dirname - 当前被执行文件所在的目录。

接下来看正文部分。

在看webpack的module配置之前,先来看一看工具类内的方法 assetsPath 和 vue-loader 的配置内容,配合上文基础配置的内容,我们很容易就能知道assetsPath的作用就是将静态资源放入static文件夹下。

在vue-loader中,有个 transformToRequire 的配置,它节省了组件在引入一些资源时,需要的引入代码,举个例子。

现在有个 控件,我们用原生的 src 来引入其需要的图片,logoUrl 表示路径参数,在没有 transformToRequire 的配置时,我们需要用 require 或者 import 来引入资源。

而当在vue-loader中配置了 transformToRequire 的内容后,引入这些资源就可以按如下的写法来写。于是代码就简化了。

那么,继续看module部分的配置,就显得非常简单了,使用 vue-loader 解析 vue 文件。其他就是常规配置,包括 babel-loader 解析 js 文件等。图片、视频、字体等资源也用了相应的 loader 进行解析,并打包至static文件夹下。

webpack.dev.conf.js

继续看开发环境下 webpack 的配置,首先分析一波引入的模块。

都还是一些比较正常的本地配置与外部插件引入。值得提一提的就是几个插件,

  • CopyWebpackPlugin : webpack拷贝静态资源插件;

  • HtmlWebpackPlugin : 自动生成入口html文件插件,webpack的老熟人插件了;

  • FriendlyErrorsPlugin : 上文有提到过,用于调整报错内容;

  • portfinder : npm配置端口的依赖。

接下来是主体部分的配置,

HOST 与 POST 先留着,放到下文 devServer 里面说明。总体来看,开发环境的配置就是将开发环境特有的 webpack 配置通过 webpack-merge 合并到 webpack 基础配置当中。里面用到的开发环境特有的静态资源,比如插件 (plugin),直接在文件内进行了引入。而其需要的自定义设置,其实看注释也可以发现,都是在上文提到的基础配置 (/config/index.js) 中,支持开发人员进行自定义配置的。

那么既然 module 和 devtool 两个部分内容比较少,就先提一提,module.rules 就在 base 配置的基础上,增加了开发环境下不同扩展名样式代码的映射方式,去看工具类(utils)的代码,可以发现样式代码支持的扩展名有 css, postcss, less, sass, scss, stylus, styl 共七种。而 devtool 则是 vue 项目主体源码在控制台的映射方式。

继续看各个部分的细节。

看完整个细节配置,其实很多内容都在 config/index.js 有所提及,这也侧面反应了 config 才是面向开发者的配置内容。

最后部分则是一个异步方法,获取到端口后开始运行webpack

webpack.prod.conf.js

生产环境下的 webpack 配置,重点来看其与开发环境的差异

首先还是从引入的模块部分开始入手。显然,像 FriendlyErrorsPlugin 这类开发环境下的提示性质的插件已经被去除,取而代之的是 OptimizeCSSPluginUglifyJsPlugin 这类的对代码进行优化与压缩的插件,以此来尽可能的减小生产环境下的项目包体。而由于运行环境的差异,生产环境也不再需要运行地址与端口的配置,交由后端进行处理。

继续看 webpack 主体部分的配置,module 部分相比开发环境,多了一个 extract: true 的配置,查看工具类中的方法,可以发现其实就是启用了 vue-style-loader 来加载样式代码,依旧是代码的优化。而 devtool 则不再与开发环境那样使控制台展示源代码,而是经过转译后的js代码,一来可以说是对生产环境下代码的保护,二来也是为了提高加载效率。

那么最大的区别,就是开发环境下的 devServer 替换为了 outputoutput 的配置就不像devServer 那么繁琐了,仅仅配置了打包输出路径,bundle 文件的命名,以及chunk文件的命名。

至于插件部分,一部分已经在开发环境的配置中进行了说明,且这一部分官方的代码注释写的相当详细,所以只挑选了几个值得提一提的生产环境下的插件

最后一块的代码是与我们上文所提及的 productionGzipbundleAnalyzerReport 配置相关的。前者规定是否开启gzip,需要配合后端使用。而后者则是用于查看控制台中的 bundle 识图。这两个 if 逻辑在默认的配置下都是不执行的。当然在执行后,我们也可以通过代码发现这两个都会被添加进入 webpack.plugins 当中。两者的最终目标,依旧是为了优化打包后的代码。

项目打包配置

项目打包脚本build.js与webpack配置一样位于build目录下。毕竟打包也是基于webpack的。具体打包命令已经在本文开头贴出,从 package.json 中也可以看出打包命令其实就是 node build.js

由于篇幅比较小,那么直接看代码。

其他配置

其他还有一些位于根目录下的插件配置,包括每个项目都有的 .gitignoreREADME.md,以及 package.json。在依赖配置文件中,我们可以看到 vue-cli 一共提供了三个命令,两个执行功能,分别用于开发环境与生产环境。

而另外在根目录下并不是很常见的配置,就 vue-cli 使用的一些非常便利的开源插件

  • .babelrc - 用于设置 javascript 的编译规则以及插件

  • .postcssrc.js - 方便样式代码编写,如插件 autoPreFixer 提供的自动补充浏览器前缀的功能,减少了许多样式代码编写的工作量

  • .eslintrc.js - eslint是用来管理和检测js代码风格的工具,可以和编辑器搭配使用,如vscode的eslint插件 当有不符合配置文件内容的代码出现就会报错或者警告。如果项目建立配置时不选择开启eslint,那么根目录下也不会有这个配置文件

结语

前后一共分了六期对vue-cli2脚手架代码进行了分析。总的来说,vue-cli作为一个Vue官方提供的前端脚手架,对于一个新人上路的Vue开发来说是相当友好的,确实是做到了低成本,上手即开发的效果。如果有更复杂的需要,也可以基于vue-cli脚手架进行改进,更加符合自身的项目要求。在Vue已经发展到3.x的当下,虽然vue-cli2已经有了vue-cli3这一全新版本,但它依旧被不少开发所喜爱。

对于vue-cli2的构建思路,其本质上还是在于webpackVue的相结合。在学习过程中,可以明显感受到,大部分时间其实都是在学webpack配置,在一个个搞懂webpack代码中各个纷繁复杂配置的作用。甚至可以把vue-cli当成一个学习webpack的扩展。

最后更新于

这有帮助吗?