當執行import vue from ‘vue‘ 或其它import xxx from ‘xxx‘ 時發生了什麼?

小也同學發表於2020-12-24

使用vue.js開發專案是,要用到

import Vue from 'vue'
import App from './App';
import router from './router';

上面的程式碼等同於:

import Vue from "../node_modules/vue/dist/vue.js";
import App from './App.vue';
import router from './router/index.js';

優先順序的演算法
在 nodejs 中,執行 import 就相當於執行了 require,而 require 被呼叫會用到 require.resolve 這個函式來查詢包的路徑,這個函式在 nodejs 中會有一個關於優先順序的演算法。

那 import Vue from ‘vue’ 這一句做了什麼呢?

  1. import Vue from ‘vue’ 解析為 const Vue = require(‘vue’)。
  2. require 判斷 vue 是否未 node.js 核心包,如我們常用的:path,fs 等,是則直接匯入,否則繼續往下走。
  3. vue 非 nodejs 核心包,判斷 vue 是否未 ‘/’ 根目錄開頭,顯然不是,繼續往下走。
  4. vue 是否為 ‘./’、’/’ 或者 ‘…/’ 開頭,顯然不是,繼續往下走。
  5. 以上條件都不符合,讀取專案目錄下 node_modules 包裡的包。
  6. 到此為止,import Vue from 'vue’這一句 就找到了 vue 所在的實際位置了。

但是,在node_modules 下的 vue 是一個資料夾,而引入的 Vue 是一個 javascript 物件,那它是怎麼取到這個物件呢?

事實上,對於一個 npm 包,內部還有一個檔案輸出的規則,下圖為 node_modules 下的 vue 結構
在這裡插入圖片描述
vue.js 在 dist 資料夾中
在這裡插入圖片描述

  1. 查詢 package.json 下是否定義了 main 欄位,是則讀取 main 欄位下定義的入口。
  2. 如果沒有 package.json 檔案,則讀取資料夾下的 index.js 或者 index.node。
  3. 如果都 package.json、index.js、index.node 都找不到,丟擲錯誤 Error: Cannot find module ‘some-library’。

在 vue 的 package.json 檔案有這麼一句:

"main": "dist/vue.runtime.common.js"

因此,import vue from ‘vue’; 會轉換成

const vue = require('./node_modules/vue/dist/vue.runtime.common.js');

vue.runtime.common.js 檔案的最後一行是:
module.exports = Vue;,就正好跟我們平時使用時的 new Vue({}) 是一致的,這就是 import vue from ‘vue’ 的過程了。

何時需要import Vue from ‘vue’
在使用vue-router、vuex這類vue核心外掛前,要先匯入vue,再安裝。
因為Vue-router並沒有將Vue打包進自己的外掛,所以註冊時使用的是外部Vue引入的方式。

小結

1.import…from…的from命令後面可以跟很多路徑格式,若只給出vue,axios這樣的包名,則會自動到node_modules中載入;若給出相對路徑及檔案字首,則到指定位置尋找。
2.可以載入各種各樣的檔案:.js、.vue、.less等等。
3.可以省略掉from直接引入。

相關文章