笔记-浅析vue-cli脚手架

vue官方为vue项目提供了一个脚手架vue-cli,有了它,很方便的生成一个可用的demo项目,于是在上面进行vue开发可谓得心应手,不用管那么多配置架构。

但也因为有了它,初学者可能知道了怎么用,却不知其所以然,尤其是下载了一大堆npm包,刚开始看得我一脸懵逼,虽然npm3包管理node_module根目录生成的目录文件是比package声明的依赖要多,但本来 依赖也是不少的,这么多的配置,还是要有一定的认识,这样才能提升对项目构建的理解,对开发debug也有益处。

先简单说一下vue-cli的用法

要求 nodejs >= 4.x

安装方式:

npm install -g vue-cli

使用方式:生成一个project-name的项目

vue init webpack project-name

安装依赖包

cd project-name
npm install

启动开发模式:

npm run dev

启动产出模式:

npm run build

技术

主要用到的技术是 webpack babel

项目目录一览

从项目目录来看 ,其目录架构主要分为环境配置、项目配置、源码、依赖包配置

- build
    - build.js            //产出模式入口文件
    - check-version.js    //检查node版本和npm版本
    - dev-client.js       //开发模式entry文件模块之一
    - dev-server.js       //开发模式入口文件
    - util.js             //工具文件
    - webpack.base.conf.js//webpack配置
    - webpack.dev.conf.js //开发模式wp配置
    - webpack.prod.conf.js//产出模式wp配置

- config
    - dev.env.js  //定义了 NODE_ENV 变量
    - index.js    //项目配置入口
    - prod.env.js //定义了 NODE_ENV 变量

- src//web项目源码
- .babelrc //babel配置信息
- package.json //项目配置信息,主要是依赖包和script指令

1.config 项目配置

先看看config,目录的内容比较少,主要是配置项目入口文件以及静态资源优化等

大致配置字段如下:

env: 读取的是x.env.js的配置,内容只有NODE_ENV

index:项目入口html文件路径

assetsSubDirectory: 资源子目录,一般是static

assetsPublicPath: 资源路径公共部分

build产出模式下配置:
    
    assetsRoot: 产出模式下产出根目录
    productionSourceMap:产出资源sourcemap配置开关
    productionGzip: false, //Gzip配置 需要依赖包 compression-webpack-plugin
    productionGzipExtensions: ['js', 'css']

dev开发模式下配置:

    port: 开发模式下会启动一个server,所以这里配置可用端口
    proxyTable: 本地开发势必会用到与后台接口交互,非同一个服务下势必有跨域问题,
    这个配置用于配置代理,代理同域接口访问到跨域接口
    配置举例:
        
        //这样就能同域接口转发到异域接口(即10087端口的服务)
        '/api': {
            target: 'http://localhost:10087',
            changeOrigin: true,
            pathRewrite: {
              '^/api': '/api'
            }
          }

注意:关于assetsXXX的配置,这里只是定义了有这么一个配置,这里的配置key跟webpack实际的配置字段名是不一样的,待后面继续说明。

2.build目录:项目架构配置

从package.json的scripts可以看到,项目主要两个指令,都是执行build里的脚本

npm run dev:   node dev-server.js
npm run build: node build.js

2.1webpack配置

细化下来,脚本主要执行的还是webpack的打包加载等功能,而webpack内容比较深入,建议先看看一些入门教程 关于webpack入门

其中,webpack.base.conf文件是两种模式共用的webpack配置

主要定义了entry入口文件、输出、模块查找路径、加载器(url、vue、babel、json)等等。
对vue加载器的定义,用了util.js(其提供了css和style loader配置设定)

webpack配置跟config的关联:

  1. output.path就是读取的config的assetsRoot
  2. publicPath对应config的assetsPublicPath
  3. module.loaders处定义query.name时,用了util.js调用了assetsPath方法,该方法实际用上了assetsSubDirectory.

而webpack.prod.conf是产出模式的webpack配置

主要定义了loaders配置,开发者工具配置devtool

插件方面plugins配置:DefinePluginUglifyJsPluginOccurrenceOrderPluginExtractTextPluginHTMLWebpackPluginCommonsChunkPlugin
另外再根据config是否配置productionGzip来选择注入CompressionWebpackPlugin

webpack.dev.conf文件则是开发模式的webpack配置

入口文件打包加入了dev-client.js,并配置loaders,devtool 以及plugins

2.2入口文件分析

分别对两种模式的入口文件进行走读

2.2.1产出模式:build.js

一开始就检查node跟npm版本: check-version.js (版本要求配置在package.json的engines字段)

tips: 脚本用到的semver包主要是对版本号这类做处理,semver.clean(process.version)获取当前node版本号

其中引入的依赖包:ora包用于在终端显示执行loading过程,shelljs/global包 使rm、mkdir、cp等指令js方法化,方便直接js代码使用,程序中这些指令使用只是输出原本静态资源的部分以及目录,通过webpack编译部分则由webpack来产出

大致流程如图:

image 查看原图

2.2.2开发模式:dev-server.js

同样也是检查nodenpm版本

express来启动web服务

用到的中间件之一,http-proxy-middleware来实现接口代理

webpack-dev-middleware 将编译的webpack产出文件包裹的中间件(文件不存在硬盘)

webpack-hot-middleware 热加载中间件,热加载中间件定义了编译后分发reloadaction

var hotMiddleware = require('webpack-hot-middleware')(compiler)
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

而dev-client.js则监听reload,用于当热加载更新时刷新页面,另外用了opn包来实现启动浏览器访问项目

大概流程看下图:express用的中间件机制,在这里就不扩展了。

image 查看原图

细看下来,内容其实说多也不算多,说少也不少,再深入下去就是对webpack配置的理解与应用了。