vue框架使用了Flow做爲類型檢查,來保證項目的可讀性和維護性。vue.js的主目錄下有Flow的配置.flowconfig文件,還有flow目錄,指定了各類自定義類型。html
在學習源碼前能夠先看下Flow的語法 官方文檔vue
vue.js源碼主要在src下node
src ├── compiler # 編譯相關 ├── core # 核心代碼 ├── platforms # 不一樣平臺的支持 ├── server # 服務端渲染 ├── sfc # .vue 文件解析 ├── shared # 共享代碼
template的編譯webpack
core ├── components # 內置組件 ├── global-api # 全局 API 封裝 ├── instance # Vue 實例化,生命週期 ├── observer # 觀察者,響應式 ├── util # 工具函數 ├── vdom # virtual DOM
存放2個主要入口,分別打包運行在web和weex上的vue.jsweb
支持了服務端渲染npm
把.vue文件內容解析成js對象json
存放共享方法api
vue
是基於Rollup
構建的,相似於webpack
首先來看下package.json
文件,先看下script
字段:數組
{ "script":{ "build": "node scripts/build.js", "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer", "build:weex": "npm run build -- weex", } }
這3條都是構建vue的命令,後2條是根據需求添加對應環境參數。運行npm run build
時會執行node scripts/build.js
weex
構建過程比較複雜,這裏會簡化下構建過程,只分析主線流程
scripts/build.js
,// 從配置文件讀取配置,拿到全部構建的path let builds = require('./config').getAllBuilds() // 過濾builds build(builds)
再看下配置文件scripts.config.js
,
let builds= { 'web-runtime-esm': { entry: resolve('web/entry-runtime.js'), dest: resolve('dist/vue.runtime.esm.js'), format: 'es', banner }, }
entry
屬性表示構建的入口 JS 文件地址,dest
屬性表示構建後的 JS 文件地址。format
屬性表示構建的格式,cjs
表示構建出來的文件遵循 CommonJS 規範,es
表示構建出來的文件遵循 ES Module
規範。 umd
表示構建出來的文件遵循 UMD
規範。
看下 resovle
方法的定義
const resolve = p => { const base = p.split('/')[0] if (aliases[base]) { return path.resolve(aliases[base], p.slice(base.length + 1)) } else { return path.resolve(__dirname, '../', p) } }
用到了 path.resolve([... paths])
, path.resolve
是 node.js
提供的路徑解析方法,能夠看下官方文檔瞭解下,主要是從右到左處理給定的路徑序列,直到構造出絕對路徑.
用resolve('web/entry-runtime.js')
做分析, base
是 web
, 找到 aliases[base]
即真實路徑 '../src/platforms/web'
,
entry: resolve('web/entry-runtime.js')
因此最終入口路徑是 ../src/platforms/web/entry-runtime.js
,構建生成文件路徑是../dist/vue.runtime.esm.js
輸入builds前要先將builds轉換成rollup打包所對應的配置結構
if (process.env.TARGET) { module.exports = genConfig(process.env.TARGET) } else { exports.getBuild = genConfig // 返回config組成的數組 exports.getAllBuilds = () => Object.keys(builds).map(genConfig) }