Vue運行時全解析 - Vue的引入(二)

Vue Runtime Full Analysis - Import Vue Module

回顧系列文章之《VueCLI3上手》

上一節 《Vue運行時全解析 - VueCLI3上手(一)》中介紹了VueCLI3的一些信息,包括如下幾點:html

  • 官方主推VueCLI3的緣由
  • CLI3的核心概念
  • CLI3的安裝
  • CLI3簡單建立一個項目
  • Vue ui的使用介紹
  • 使用CLI3按照舊版方式建立項目的方法
  • 安裝插件vuex,router方法
  • 修改項目配置的方式
  • 使用VueCLI3的serve命令 打開一個vue文件

閱讀本節你能學到什麼?

  • 查看項目的配置文件的2種方法vue

    • vue inspect 命令方式
    • vue ui 可視化方式
  • 在腳手架項目中引入vue的方式node

    • 腳手架項目入口文件的位置
    • Webpack 引入模塊的機制
    • vue 編譯後的文件的用途
  • 引入的vue作了哪些前置工做

導出配置文件

開始分析以前,咱們先把項目配置文件先導出來,以作分析備用,在VueCLI3配置的文檔中能夠找到倆中方式找到配置內容:webpack

  • inspect命令:經過下面命令將項目的默認配置導出到文件中,這裏命名爲preset-default-vue-cli-3.jsgit

    yanyue$ vue inspect > preset-default-vue-cli-3.js
  • vue ui 的inspect面板,點擊運行能夠獲取到。

    能夠經過 vue ui 啓動可視化配置界面 以下圖,在這裏能夠看到 task(任務) 面板,task面板有4個task, 選擇 inspect 面板可以看到 run(運行按鈕) ,點擊後,便可以查看到輸出的配置信息,在這裏查看到的是文本方式查看,因爲內容較多,像我此次要分析,須要摺疊代碼看到這個配置的總體信息,通常狀況,咱們不會全部配置都去修改,在這裏查閱很是方便,並且運行一次,下次切換過來這個內容還在。es6

    就僅僅配置文件足有1000+行... 從這裏看vue也是花了大功夫把各類工具的配置文件都進行了優化整合,並提供統一的修改方式,以後咱們會講到如何在項目中修改配置。github

clipboard.png

項目引入vue的方式

要知道項目是怎麼引入vue框架的,咱們先從最開始瞭解一下的程序入口main.js文件,由於vue的引入時在這個文件中,那咱們先看看這個文件被引入的過程是怎麼工做的?web

main.js

src/main.js是整個程序的入口文件,在上面導出的配置文件中咱們搜索entry這個關鍵字,能夠看到下圖的配置信息:vuex

entry: {
    app: [
        './src/main.js'
    ]
}

VueCLI3項目的入口文件就是經過該配置字段來定義輸入給 webpack 的,最後經過 HtmlWebpackPlugin 插件將打包好的腳本注入進根據public中的index.html模板生成的新的html文件中, 以下面配置中插件中的template選項:vue-cli

new HtmlWebpackPlugin({
    templateParameters: function () { /* omitted long function */ },
    template: 'path/to/project-root/public/index.html'
})

將vue引入項目

第一行代碼

import Vue from 'vue'

使用了ES2015的語法將vue的運行時做爲依賴模塊引入程序。

咱們關注一下模塊細節

使用VueCLI3安裝的項目,項目的基本依賴(包括babel, vue等)已經被安裝好了,咱們去node_modules目錄中找到vue模塊目錄,從目錄下package.json文件可以看到以下圖:

clipboard.png

從圖中能看到 vue對多種引入方式以不一樣文件提供支持,包括符合CommonJS模塊規範的 vue.runtime.common.js 、符合ES Module模塊規範的vue.runtime.esm.js和符合UMD模塊規範的 vue.js以及支持TypeScript的類型定義文件index.d.ts

咱們的項目使用webpack打包各個模塊,webpack優先會選取ES模塊方式引入包(緣由:webpack中的處理 參考:roollup相關的解釋)

在web環境中,webpack會依據resolve下的mainFields字段中配置的屬性所指定的位置讀取文件,而當前版本的vue項目配置中配置了pkg.module和pkg.main這倆個位置,因此webpack優先讀取了module指向的dist/vue.runtime.esm.js文件,忽略了pkg.main字段指向的位置文件。

編譯後的文件

上面說到了vue.runtime.esm.js這個文件被webpack做爲vue項目提供的vue模塊引入到咱們的項目中,可是從安裝的vue模塊目錄的dist下卻發現了好幾個文件,以下圖:

clipboard.png

如下大多參考官方文檔內容,並作了簡單解釋性翻譯:

解釋編譯後的文件

Explanation of Build Files

UMD CommonJS ES Module
Full vue.js vue.common.js vue.esm.js
Runtime-only vue.runtime.js vue.runtime.common.js vue.runtime.esm.js
Full (production) vue.min.js
Runtime-only (production) vue.runtime.min.js

名詞解釋(Terms)

  • Full: builds that contains both the compiler and the runtime.

    • 完整版,包含 compiler 和 runtime
  • Compiler: code that is responsible for compiling template strings into JavaScript render functions.

    • Compiler : 負責將模板字符串編譯成render函數
    • 注意: 請留意後面會講到的render函數
  • Runtime: code that is responsible for creating Vue instances, rendering and patching virtual DOM, etc. Basically everything minus the compiler.

    • runtime: 負責建立vue實例, 渲染和調整虛擬DOM等,基本上等效於除去compiler的全部一切。
  • UMD: UMD builds can be used directly in the browser via a <script> tag. The default file from Unpkg CDN at https://unpkg.com/vue is the Runtime + Compiler UMD build (vue.js).

    • UMD文件可使用script標籤直接引入html文件,默認從Unpkg CDN獲取的文件就是 Runtime + Compiler版本的vue.js文件
  • CommonJS: CommonJS builds are intended for use with older bundlers like browserify or webpack 1. The default file for these bundlers (pkg.main) is the Runtime only CommonJS build (vue.runtime.common.js).

    • CommonJS版本爲了那些還在使用browserify和webpack1的bundler提供的,默認main入口提供了僅包含Runtime的符合CommonJS規範的版本
  • ES Module: ES module builds are intended for use with modern bundlers like webpack 2 or rollup. The default file for these bundlers (pkg.module) is the Runtime only ES Module build (vue.runtime.esm.js).

    • ES模塊版本是爲了那些現代打包工具像 webpack2+ 或者 rollup,默認module入口提供了僅包含Runtime的符合ES Module規範的版本。

運行時 + 編譯器 與 僅有編譯器 的比較

Runtime + Compiler vs. Runtime-only

If you need to compile templates on the fly (e.g. passing a string to the template option, or mounting to an element using its in-DOM HTML as the template), you will need the compiler and thus the full build.

若是你須要在運行時處理以前編譯templates(例如, 有一個template選項,或者掛載到一個元素上,而你又將元素內的DOM元素做爲模板來處理,這時候就須要編譯器這部分進行完整編譯。

When using vue-loader or vueify, templates inside *.vue files are compiled into JavaScript at build time. You don't really need the compiler in the final bundle, and can therefore use the runtime-only build.

若是你打包的時候是用vue-loader 或者 vueify,將`*.vue文件內的templates編譯成JavaScript代碼, 你就不須要compiler, 可使用 runtime-only版本編譯。

Since the runtime-only builds are roughly 30% lighter-weight than their full-build counterparts, you should use it whenever you can. If you wish to use the full build instead, you need to configure an alias in your bundler.

由於僅僅包含運行時編譯比完整版少30%的代碼體積, 若是你須要使用完整包也是能夠的,你須要調整配置。

顯式的改變運行時引用包

Webpack
module.exports = {
  // ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
    }
  }
}
Rollup
const alias = require('rollup-plugin-alias')

rollup({
  // ...
  plugins: [
    alias({
      'vue': 'vue/dist/vue.esm.js'
    })
  ]
})
Browserify

Add to your project's package.json:

{
  // ...
  "browser": {
    "vue": "vue/dist/vue.common.js"
  }
}

vue模塊在引入時作了什麼?

看完了這幾個文件的用途以後咱們再來看看vue引入的時候作了什麼? 帶着這個疑問咱們繼續探索。

咱們打開vue.runtime.js文件,文件內容有些多,咱們先不關注這些細節,咱們先看有哪幾大塊功能?

  • 工廠函數,支持不一樣規範的方式導出文件

    clipboard.png

  • 類型檢測定義

    clipboard.png

  • 瀏覽器環境檢測 Browser environment sniffing

    clipboard.png

  • 虛擬DOM的實現定義
  • globals MessageChannel
  • 初始化數據方法定義

    • initState
    • initProps
    • initData
    • initComputed
    • initMethods
    • initWatch
    • initRender
    • initMixin
  • 初始化調用

    • initMixin(Vue);
    • stateMixin(Vue);
    • eventsMixin(Vue);
    • lifecycleMixin(Vue);
    • renderMixin(Vue);
  • 這一步vue作了不少的前期準備工做,咱們在後面章節還會細化...

本節結束

這一節咱們只關注最基礎的這一塊,下一節,咱們將繼續關注細節。

相關文章
相關標籤/搜索