Flow
-
認(rèn)識 Flow
JavaScript 靜態(tài)類型檢查器肤无,vue 源碼利用 Flow 做靜態(tài)類型檢查
-
為什么用 Flow
js 動態(tài)類型語言春叫,類型檢查發(fā)展趨勢酱塔,在編譯期盡早發(fā)現(xiàn) bug,不影響代碼運(yùn)行改鲫,使編寫 js 有強(qiáng)類型語言的體驗(yàn)
-
FLow 工作方式
-
類型推斷:通過變量的使用上下文推斷變量類型,更具推斷來檢查類型
// Flow function split(str) { return str.split('') } split(11) // Flow檢查報(bào)錯(cuò),split期待的參數(shù)使字符串铭拧,而不是數(shù)字
-
類型注釋:事先注釋好期待的類型,F(xiàn)low 會基于這些注釋來判斷
// Flow function add(x: number, y: number): number { return x + y } add('Hello', 11) // 類型推斷不需要編寫類型注釋 特定場景需要類型注釋提供更明確的檢查
-
-
Flow 在 Vue.js 源碼的應(yīng)用
第三方庫或自定義類型 Flow 并不認(rèn)識恃锉,檢查時(shí)報(bào)錯(cuò)搀菩,因此 FLow 提出 libdef 用來識別,在 Vue.js 主目錄下有.flowconfig 文件破托,這里的[libs]配置的是 flow肪跋,表示指定的庫定義都在 flow 文件夾內(nèi),閱讀源碼時(shí)土砂,遇到某個(gè)類型可以在這里查看數(shù)據(jù)結(jié)構(gòu)的定義
Vue 源碼目錄
src
├─compiler 編譯相關(guān)
├─core Vue 核心庫
├─platforms 平臺相關(guān)代碼
├─server SSR澎嚣,服務(wù)端渲染
├─sfc .vue 文件編譯為 js 對象
└─shared 公共的代碼
-
compiler
包含 Vue.js 所有編譯相關(guān)的代碼,將模板解析為 ast 語法樹瘟芝,ast 語法樹優(yōu)化易桃,代碼生成等
編譯工作推薦在構(gòu)建時(shí)做(借助 webPack、vue-loader 等輔助插件)
-
core
Vue.js 核心代碼锌俱,包括內(nèi)置組件晤郑、全局 API 封裝、Vue 實(shí)例化贸宏、觀察者造寝、虛擬 DOM、工具函數(shù)等
-
platform
Vue.js 是跨平臺的 MVVM 框架吭练,可在 web 和 native 客戶端上诫龙,platform 是 Vue.js 的入口,2 個(gè)目錄代表 2 個(gè)主要入口鲫咽,分別打包成運(yùn)行在 web 和 weex 上的 Vue.js
-
server
服務(wù)端渲染相關(guān)邏輯签赃,主要是泡在服務(wù)端的 node.js
-
sfc
將單文件組件解析冊成 javaScript 對象
-
shared
瀏覽器端和服務(wù)端所共享的工具方法
Vue 源碼調(diào)試設(shè)置
-
打包工具 Rollup
- Vue.js 源碼的打包工具使用的是 Rollup,比 Webpack 輕量
- Webpack 把所有文件當(dāng)做模塊分尸,Rollup 只處理 js 文件更適合在 Vue.js 這樣的庫中使用
- Rollup 打包不會生成冗余的代碼
-
安裝依賴
npm i
-
設(shè)置 sourcemap
package.json 文件中的 dev 腳本中添加參數(shù) --sourcemap
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:webfull-dev"
-
執(zhí)行 dev
npm run dev 執(zhí)行打包锦聊,用的是 rollup,-w(watcher) 參數(shù)是監(jiān)聽文件的變化箩绍,文件變化自動重新打打包孔庭,-c 設(shè)置配置文件,--environment 設(shè)置環(huán)境變量材蛛,根據(jù)環(huán)境變量打包成不同版本的 vue
在 dist 目錄中打包生成兩個(gè)文件
-
調(diào)試
examples示例中引入的 vue.min.js 改為 vue.js
打開 Chrome 的調(diào)試工具中的 source
Vue 的不同構(gòu)建版本
npm run build 重新打包所有文件
dist\README.md
-
不同版本
- 完整版:同時(shí)包含編譯器和運(yùn)行時(shí)的版本圆到。
- 編譯器:用來將模板字符串編譯成為 JavaScript 渲染函數(shù)的代碼怎抛,體積大、效率低芽淡。
- 運(yùn)行時(shí):用來創(chuàng)建 Vue 實(shí)例抽诉、渲染并處理虛擬 DOM 等的代碼,體積小吐绵、效率高迹淌。基本上就是除 去編譯器的代碼己单。
- UMD:UMD 版本通用的模塊版本唉窃,支持多種模塊方式。 vue.js 默認(rèn)文件就是運(yùn)行時(shí) + 編譯器的 UMD 版本
- CommonJS(cjs):CommonJS 版本用來配合老的打包工具比如 Browserify 或 webpack 1纹笼。
- ES Module:從 2.6 開始 Vue 會提供兩個(gè) ES Modules (ESM) 構(gòu)建文件纹份,為現(xiàn)代打包工具提供的 版本
- ESM 格式被設(shè)計(jì)為可以被靜態(tài)分析,所以打包工具可以利用這一點(diǎn)來進(jìn)行“tree-shaking”并 將用不到的代碼排除出最終的包
- ES6 模塊與 CommonJS 模塊的差異
-
Runtime + Compiler vs. Runtime-only
// Compiler // 需要編譯器廷痘,把 template 轉(zhuǎn)換成 render 函數(shù) // const vm = new Vue({ // el: "#app", // template: "<h1>{{ msg }}</h1>", // data: { // msg: "Hello Vue", // }, // }); // Runtime // 不需要編譯器 const vm = new Vue({ el: '#app', render(h) { return h('h1', this.msg) }, data: { msg: 'Hello Vue' } })
推薦使用運(yùn)行時(shí)版本蔓涧,因?yàn)檫\(yùn)行時(shí)版本相比完整版體積要小大約 30%
基于 Vue-CLI 創(chuàng)建的項(xiàng)目默認(rèn)使用的是 vue.runtime.esm.js
通過查看 webpack 的配置文件
vue inspect > output.js
image-20210304085010850.png
*.vue 文件中的模板是在構(gòu)建時(shí)預(yù)編譯的,最終打包后的結(jié)果不需要編譯器笋额,只需要運(yùn)行 時(shí)版本即可