LoginSignup
92
79

More than 5 years have passed since last update.

Vue.jsってどうやって動いてるんだろう? - Vue.jsを読み込むロジック

Last updated at Posted at 2019-04-13

最近、Vue.jsを利用する機会が増えてきました。概念もなんとなく理解してきましたが、「じゃあ実際どうやって動いているの?」と聞かれるとわからないですよね。

ということで、Vue.jsのファイルを読み解いてみようと思います。

今回は、CDNで提供されている、下記のソースを使います。

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

即時関数だ!

今回は全体の構造を眺めていきましょう。
スクリプトの出だしはこのようになっています。

vue.js
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.Vue = factory());
}(this, function () { 'use strict';
  // ...(省略)
}))

うお、長え!と思うかもしれませんが、単純化するとこうなっています。

単純化してみた
(function (global, factory){ 
  a===b && c!==d ? E : f===g && h ? I : (j=k || l, m=o)
}(this, function () {
   // ...(省略)
}))
(function(a, b){ 
  //  関数の中身 
})(c, d)

という形は即時関数の形式です。
http://analogic.jp/immediate-function/

vue.jsが読み込まれた際に function(a, b) が実行されます。そして、引数 a, b にはc, dがそれぞれ代入されます。

今回の場合、globalthis、そしてfactoryに1万行を超えるvue.jsの関数がそれぞれ代入されるわけですね!

ちなみに、thisにはブラウザで実行した場合、Windowオブジェクトが入ります。
image.png

条件分岐がたくさん

さて、ではglobal, factoryはそれぞれどのような処理がされるのでしょうか?

それが、次の三項演算子パラダイスの即時関数の中身です。

typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Vue = factory());

ここで、三項演算子を簡単におさらいしましょう。

(true or false) ? 'trueだった場合の処理' : 'falseだった場合の処理'

これに基づいて、分類をしてみます。

1 typeof exports === 'object' && typeof module !== 'undefined' 
2   ? module.exports = factory() 
3   : typeof define === 'function' && define.amd 
4      ? define(factory) 
5      : (global = global || self, global.Vue = factory());

1行目は丸々条件式です。
true になる条件は「 exports がオブジェクト型で、かつ module が存在する」です。

true だった場合、module.exports に factory()がセットされます。
つまり、Node上だったらモジュールとして機能する、ということですね!

falseだった場合、さらに条件分岐が続きます。

3行目がtrueになる条件は「defineが関数で、かつdefine.amdが存在するとき」です。

true だった場合、definefactoryがぶち込まれます。
これは、AMD(Asynchronous Module Definition)を使う際の処理です。

falseだった場合、
global には global, もしくは selfが代入されます。

この論理演算子 || についてはこちらを参照のこと。
https://qiita.com/Imamotty/items/bc659569239379dded55

globalthis, つまり windowオブジェクトのことでしたね。
そして最後に、そのglobalVuefactory()を突っ込んでいる、というわけです。

つまり、ここでの処理は、AMDかNodeJSかそれ以外(ブラウザ)かによって、factory()(Vueの本体)を読み込ませる処理の方法を分岐させていたんですね!

ちなみに、global, factoryを引数にもつ即時関数を用意し、内部でそれぞれの環境に応じて処理を分岐させる手法は、 UMD (Universal Module Definition) と呼ばれています!

ここら辺のリンクに詳細があります。
https://www.davidbcalhoun.com/2014/what-is-amd-commonjs-and-umd/
https://qiita.com/chuck0523/items/1868a4c04ab4d8cdfb23


今回はここまでにします。
メソッド単位でちょこちょこ記事が書けたらいいな、と思っています!

92
79
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
92
79