Vue --- Runtime + Compiler vs. Runtime-only

學(xué)習(xí)目標(biāo):
一绳慎、理解Runtime + Compiler vs. Runtime-only
二姨蝴、如何設(shè)置Runtime + Compiler 和Runtime-only環(huán)境
三鱼喉、理解源碼實現(xiàn)原理

理解Runtime + Compiler vs. Runtime-only

一虐秋、如果你需要在客戶端編譯模板 (比如傳入一個字符串給 template 選項窍帝,或掛載到一個元素上并以其 DOM 內(nèi)部的 HTML 作為模板)努潘,就將需要加上編譯器

// 需要編譯器
new Vue({
  template: '<div>{{ hi }}</div>'
})

二、vue-loader 或 vueify 的時候盯桦,*.vue 文件內(nèi)部的模板會在構(gòu)建時預(yù)編譯成 JavaScript慈俯,則不需要編譯器

// 不需要編譯器
new Vue({
  render (h) {
    return h('div', this.hi)
  }
})

環(huán)境設(shè)置

環(huán)境默認是 Runtime-only,vue指向的是'vue/dist/vue.runtime.esm.js'
如果想要用有編譯器的模式的話拥峦,操作如下:
1.在根目錄下增加一個vue.config.js
2.vue.config.js的內(nèi)容是:

module.exports = {
    runtimeCompiler:true
}

問題(理解源碼實現(xiàn)原理)

1.vue.config.js 為什么是這個文件名贴膘?
2.runtimeCompiler:true這個開關(guān)屬性是如何控制用編譯器文件的?


image.png

問題1:vue.config.js 為什么是這個文件名略号?

查看Service.js文件:
. 這里的loadUserOptions函數(shù)就是用來處理vue.config.js的對象屬性的
. 可以看到這個文件中用到vue.config.js或vue.config.cjs這個名字

  loadUserOptions () {
    // vue.config.c?js
    let fileConfig, pkgConfig, resolved, resolvedFrom
    const esm = this.pkg.type && this.pkg.type === 'module'

    const possibleConfigPaths = [
      process.env.VUE_CLI_SERVICE_CONFIG_PATH,
      './vue.config.js',
      './vue.config.cjs'
    ]
    let fileConfigPath
    for (const p of possibleConfigPaths) {
      const resolvedPath = p && path.resolve(this.context, p)
      if (resolvedPath && fs.existsSync(resolvedPath)) {
        fileConfigPath = resolvedPath
        break
      }
    }
......
return resolved
}

上面的return resolved的最后結(jié)果顯示為:

{runtimeCompiler:true}

問題2.runtimeCompiler:true這個開關(guān)屬性是如何控制用編譯器文件的刑峡?

打開文件base.js

      webpackConfig.resolve
        .alias
          .set(
            'vue$',
            options.runtimeCompiler
              ? 'vue/dist/vue.esm.js'
              : 'vue/dist/vue.runtime.esm.js'
          )

上面代碼可以看到options.runtimeCompiler如果為true,則用到的是有編輯器的文件'vue/dist/vue.esm.js'玄柠,否則用到的是runtime即'vue/dist/vue.runtime.esm.js'

問題

現(xiàn)在問題是如何確定options.runtimeCompiler中的options對象中的runtimeCompiler就是vue.config.js文件中的runtimeCompiler
1.查看Service.js

  init (mode = process.env.VUE_CLI_MODE) {
    ......
    // load user config
    const userOptions = this.loadUserOptions()

    this.projectOptions = defaultsDeep(userOptions, defaults())
    ......

    // apply plugins.
    this.plugins.forEach(({ id, apply }) => {
      if (this.pluginsToSkip.has(id)) return
      apply(new PluginAPI(id, this), this.projectOptions)
    })
  }

上面代碼我們知道loadUserOptions函數(shù)最后返回的就是vue.config.js中的對象

const { defaults, validate } = require('./options')

defaults得到的是./options中的返回對象值

this.projectOptions = defaultsDeep(userOptions, defaults())

this.projectOptions就是把vue.config.js+(./options.js的default)合并到一起的對象即是:

{ 
runtimeCompiler: true,
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: '',
  indexPath: 'index.html',
  filenameHashing: true,
  transpileDependencies: [],
  productionSourceMap: true,
  parallel: true,
  pages: undefined,
  crossorigin: undefined,
  integrity: false,
  css: {},
  lintOnSave: 'default',
  devServer: {} 
}
// apply plugins.
    this.plugins.forEach(({ id, apply }) => {
      if (this.pluginsToSkip.has(id)) return
      apply(new PluginAPI(id, this), this.projectOptions)
    })

其中apply(new PluginAPI(id, this), this.projectOptions)表示執(zhí)行this.plugins的函數(shù)突梦,其中就包含base.js的文件,參數(shù)一個是api,一個是options

module.exports = (api, options) => {
......
      webpackConfig.resolve
        .alias
          .set(
            'vue$',
            options.runtimeCompiler
              ? 'vue/dist/vue.esm.js'
              : 'vue/dist/vue.runtime.esm.js'
          )
.......
}

this.projectOptions也就是合并到一起的對象故這里的options.runtimeCompiler中的runtimeCompiler屬性也就是vue.config.js中的runtimeCompiler

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羽利,一起剝皮案震驚了整個濱河市宫患,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌这弧,老刑警劉巖娃闲,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匾浪,居然都是意外死亡皇帮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門蛋辈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來属拾,“玉大人,你說我怎么就攤上這事冷溶〗グ祝” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵逞频,是天一觀的道長礼预。 經(jīng)常有香客問我,道長虏劲,這世上最難降的妖魔是什么托酸? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任褒颈,我火速辦了婚禮,結(jié)果婚禮上励堡,老公的妹妹穿的比我還像新娘谷丸。我一直安慰自己,他們只是感情好应结,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布刨疼。 她就那樣靜靜地躺著,像睡著了一般鹅龄。 火紅的嫁衣襯著肌膚如雪揩慕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天扮休,我揣著相機與錄音迎卤,去河邊找鬼。 笑死玷坠,一個胖子當(dāng)著我的面吹牛蜗搔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播八堡,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼樟凄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了兄渺?” 一聲冷哼從身側(cè)響起缝龄,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挂谍,沒想到半個月后二拐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡凳兵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了企软。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庐扫。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仗哨,靈堂內(nèi)的尸體忽然破棺而出形庭,到底是詐尸還是另有隱情,我是刑警寧澤厌漂,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布萨醒,位于F島的核電站,受9級特大地震影響苇倡,放射性物質(zhì)發(fā)生泄漏富纸。R本人自食惡果不足惜囤踩,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晓褪。 院中可真熱鬧堵漱,春花似錦、人聲如沸涣仿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽好港。三九已至愉镰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钧汹,已是汗流浹背丈探。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留崭孤,地道東北人类嗤。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像辨宠,于是被迫代替她去往敵國和親遗锣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359