Vue | vue cli新手入门 详细解读

前言

本文将从vue cli项目中的入口文件入手,深入浅出地解析vue cli在开发环境下的工程的运行原理。

一、有关vue cli 3(选读)

1.1 本文解析采用cli 2做示例,但原理同样适用于vue cli 3

若你是cli 3开发者,参考本文时,仅需注意cli 3的三点改动:

  1. cli 3内化了项目默认配置(相关文件位于node_modules/@vue/cli-service/lib/config),开发者可通过新增vue.config.js添加webpack配置。
  2. index.html被放到了public文件夹下
  3. webpack配置的书写使用webpack-chain 风格
1.2 查看vue版本号、vue-cli版本号
1.2.1 查看vue版本号

方法一:npm ls vue
方法二:package.json
在这里插入图片描述
在这里插入图片描述

1.2.1 查看vue-cli版本号

在这里插入图片描述

1.3 vue-cli下载最新版本

卸载2.x版本的vue-cli :
npm uninstall -g vue-cliyarn global remove vue-cli

安装3.x版本的@vue/cli :
npm install -g @vue/cliyarn global add @vue/cli

再次输入 vue -V 检验:

在这里插入图片描述

二、入口文件的概述

  • 在vue cli构建的项目中,main.js是项目的入口文件,定义了vue实例,并引入根组件app.vue,将其挂载到index.htmlid为app的节点上。
    在这里插入图片描述

2.1 main.js:

2.1.1 两种方式:

在Vue构造函数时,需要配置一个el属性
在这里插入图片描述
但是也可以像我一样这么写
在这里插入图片描述

2.1.2 render函数的作用

render函数是vue通过js渲染dom结构的函数createElement,约定可以简写为h

render: h => h(App) 缩写前

render:function(createElement){
   return createElement(App);
}

进一步缩写为(ES6 语法)

render(createElement){
    return createElement(App);
}

再进一步缩写为:

render(h){
  return h(App)
}

按照 ES6 箭头函数的写法,就得到了:

h => h(App)

实际渲染

import App from './App'
import Vue from 'vue'
new Vue({
  el:'#root',
  template:'<App></App>',
  components:{
    App
  }
})

手动挂载

在Vue构造函数时,需要配置一个el属性,如果没有没有el属性时,可以使用.$mount('#app')进行挂载。
// 配置了el属性:
new Vue({
    el:"#app",
    router
});

// 如果没有配置el属性,可以使用手动挂载$mount("#app")
new Vue({
    router
}).$mount('#app');

官方解释翻译:它来自单词 hyperscript,这个单词通常用在 virtual-dom 的实现中。Hyperscript 本身是指 生成HTML 结构的 script 脚本,因为 HTML 是 hyper-text markup language 的缩写(超文本标记语言)

createElement 函数是用来生成 HTML DOM 元素的,也就是上文中的 generate HTML
structures,也就是 Hyperscript,这样作者才把 createElement 简写成 h。 h是 Vue.js 里面的
createElement 函数,这个函数的作用就是生成一个 VNode节点,render 函数得到这个 VNode 节点之后,返回给 Vue.js 的 mount 函数,渲染成真实 DOM 节点,并挂载到根节点上

  • 注意:
    vue实例挂载后,会对节点原内容进行覆盖。所以,即便index.html和app.vue中都定义了<div id="app"></app>, 最终网页也不会出现两个id为app的节点。

2.2 index.html:

<body>
    <div id="app"></div>
</body>

2.3 app.vue:

<template>
  <div id="app">
    .....
  </div>
</template>

三、问题

main.js的作用已经明了,但仍有三个疑问:

  1. main.js为什么叫入口文件,什么是“入口文件”?
  2. 在运行npm run dev后,若不做特殊设置,index.html实际页面中仅挂载了app.js一个脚本,所有组件去哪儿了,app.js是如何形成的?
  3. vue实例化在main.js中,但在index.html中并没有引入main.js,main.js与index.html是如何产生关联的?

四、原因:Webpack

vue cli搭建的项目本质是一个集成预设置的webpack项目。是webpack驱动着项目的打包,热重载和本地运行。
而上述问题都是由webpack逐一处理的:

  1. 入口文件是一个webpack概念;入口文件是webpack构建内部依赖图的起点
  2. app.js是由webpack打包生成的输出文件
  3. 而将app.js挂载到index.html这一过程是由webpack的一个插件——html-webpack-plugin完成的。

4.1 什么是webpack

webpack 是JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,然后将应用程序所需的所有模块打包成一个或多个 bundle

4.2 webpack的核心作用

  1. 浏览器仅能识别html,cssjs,而无法识别封装的less,vue,jsx等文件,而webpack则可以将这些文件解析打包成浏览器能识别的基本文件。
  2. 模块化开发中,我们会编写大量模块,如果不打包就上线,那么页面加载或交互时,将会发起大量资源请求。为了性能优化,需要使用webpack这样的打包器对模块进行打包整合,以减少请求数。就像简单的vue项目,所有组件最终都将被打包到一个app.js中。
  3. 相较于无差别打包依赖模块的传统打包器,webpack的核心优势在于它从入口文件出发,递归构建依赖关系图。通过这样的依赖梳理,webpack打包出的bundle不会包含重复或未使用的模块,实现了按需打包极大的减少了冗余

在这里插入图片描述

4.3 webpack配置文件

vue cli 2 在build目录下默认有三种场景配置 ——webpack.base/dev/prod.conf.js
base是基础配置,dev/prod分别是开发和产品场景的配置,它们在merge基础配置后追加或覆盖相关配置。

const devWebpackConfig = merge(baseWebpackConfig, {
        //  开发环境设置
})

在运行或打包时,会根据你的命令选择不同的配置文件。脚本配置是写在package.json中的,如npm run dev就是使用开发环境配置。

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  }

一份配置包含了入口文件,输出和各种插件的配置。

4.4 vue的入口文件设置

webpack.base/webpack.dev中,vue默认设置main.js为项目的唯一入口。
在项目打包时,webpack会从main.js开始构建依赖图,梳理整个项目依赖且不重复的模块。
入口配置如下:

entry: {
    app: './src/main.js'
  },
4.4.1 入口设置延伸(选读)

webpack的入口设置,这里不展开讲。
如果你要做多页面项目,而非默认的SPA,那么你要为每个页面设置一个入口。如果你要将app与第三方库分离,也要设置两个入口。
这些操作可参考webpack的官方文档

webpack官方文档
https://www.webpackjs.com/concepts/entry-points/

如果你想要封装自己的UI库,那么在入口部分的设置,你可以参考以下这篇文章。

实现element-ui的按需引入,按需打包加载 https://segmentfault.com/a/1190000015884948

4.5 输出文件配置

配置中还定义了项目的输出设定。
在output中,你可以配置打包输出文件的路径,名称,进行分离js/css等操作。

// webpack.base.conf
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },

这里只讲一下 filename 这一属性:
filename定义的是输出文件的名称[name]是webpack中的占位符,它对应entry中对象的键名
默认配置中仅有一个入口–app。所以,在默认的开发模式下,本项目的所有资源最终打包生成的文件就是app.js。
注:在开发模式下,项目是跑在webpack-dev-server的虚拟服务器上,此时app.js仅存在于内存中。

4.6 HtmlWebpackPlugin配置

vue的webpack默认配置中还加入了htmlwebpackplugin插件,用于生成index.html与挂载JS脚本。
配置参数中:
filename是输出文件名,
template是本地模板文件名,HtmlWebpackPlugin默认挂载的模板就是根目录下的index.html。
inject属性定义了js脚本加载的位置,默认值true,则在body最下方加载。
你还可以添加其它参数,比如网站图标favicon等,这一系列参数均可参考webpack官方文档

new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true,
      favicon:'static/img/temple.png'
    })

五、 总结

当你输入 npm run dev 后,发生了这样一连串事件:
webpack选择了开发配置,并进入main.js入口文件,构建项目依赖图
webpack将整理后的所有依赖模块打包成输出文件app.js,
接着htmlwebpackPlugin将它挂载到index.html页面上。
最终,它呈现出的模样如下所示:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值