「转」Vue | vue cli入口文件解析(main.js,app.vue,index.html webpack)

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

有关vue cli 3(选读)
本文解析采用cli 2做示例,但原理同样适用于vue cli 3
若你是cli 3开发者,参考本文时,仅需注意cli 3的三点改动:

cli 3内化了项目默认配置(相关文件位于node_modules/@vue/cli-service/lib/config),开发者可通过新增vue.config.js添加webpack配置。
index.html被放到了public文件夹下
webpack配置的书写使用webpack-chain 风格
建议阅读本文时,参照你的本地文件,以加深理解。

1.入口文件的概述
在vue cli构建的项目中,main.js是项目的入口文件,定义了vue实例,并引入根组件app.vue,将其挂载到index.html中id为‘app’的节点上。


image.png
main.js:
import Vue from 'vue'
import App from './App'

/* eslint-disable no-new */
new Vue({
  el: '#app', //挂载点
  components: { App }, // 根组件
  template: '<App/>'
})

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

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

app.vue:

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

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

main.js为什么叫入口文件,什么是“入口文件”?
在运行npm run dev后,若不做特殊设置,index.html实际页面中仅挂载了app.js一个脚本,所有组件去哪儿了,app.js是如何形成的?
vue实例化在main.js中,但在index.html中并没有引入main.js,main.js与index.html是如何产生关联的?
3.答案:Webpack
vue cli搭建的项目本质是一个集成预设置的webpack项目。是webpack驱动着项目的打包,热重载和本地运行。
而上述问题都是由webpack逐一处理的:

入口文件是一个webpack概念;入口文件是webpack构建内部依赖图的起点。
app.js是由webpack打包生成的输出文件。
而将app.js挂载到index.html这一过程是由webpack的一个插件——html-webpack-plugin完成的。
3.1什么是webpack
webpack 是JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,然后将应用程序所需的所有模块打包成一个或多个 bundle。

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


image.png

3.2 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"
  }

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

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

 entry: {
    app: './src/main.js'
  },

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

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

如果你想要封装自己的UI库,那么在入口部分的设置,你可以参考以下这篇文章。(这篇文章的其它部分并不是最佳实践,可行但仅供参考!以后有空再详述组件化)

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

3.4 输出文件配置
配置中还定义了项目的输出设定。
在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仅存在于内存中。

3.5 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'
    })

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


image.png

————————————————
版权声明:本文为CSDN博主「MGsniper」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36145914/article/details/86497123

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容