平時開發(fā)中病袄,經(jīng)常會用到這樣一個語句:
import Vue from 'vue';
由于瀏覽器兼容性問題搂赋,通常這個語法是在 webpack 的構(gòu)建流搭建的項目中執(zhí)行的,那么這個語句到底做了什么呢益缠?
其實在 nodejs 中脑奠,執(zhí)行 import
就相當(dāng)于執(zhí)行了 require
,而 require
被調(diào)用幅慌,其實會用到 require.resolve
這個函數(shù)來查找包的路徑宋欺,而這個函數(shù)在 nodejs 中會有一個關(guān)于優(yōu)先級的算法。先看一下 import Vue from 'vue'
這一句做了什么:
-
import Vue from 'vue'
解析為const Vue = require('vue')
胰伍。 -
require
判斷 vue 是否未 nodejs 核心包齿诞,如我們常用的:path,fs 等骂租,是則直接導(dǎo)入祷杈,否則繼續(xù)往下走。 - vue 非 nodejs 核心包渗饮,判斷 vue 是否未 '/' 根目錄開頭但汞,顯然不是,繼續(xù)往下走互站。
- vue 是否為 './'私蕾、'/' 或者 '../' 開頭,顯然不是胡桃,繼續(xù)往下走踩叭。
- 以上條件都不符合,讀取項目目錄下 node_modules 包里的包翠胰。
到了第五步懊纳,import Vue from 'vue'
就找到了 vue 所在的實際位置了,那么問題來了亡容,node_modules 下的 vue 是一個文件夾,而引入的 Vue 是一個 javascript 對象冤今,那它是怎么取到這個對象呢闺兢?
其實對于一個 npm 包,內(nèi)部還有一個文件輸出的規(guī)則,先看下 node_modules/vue 下的文件結(jié)構(gòu)是怎么樣的:
├── LICENSE
├── README.md
├── dist
├── package.json
├── src
└── types
是不是看起來很籠統(tǒng)屋谭,其實對于 npm 包脚囊,require
的規(guī)則是這樣的:
- 查找 package.json 下是否定義了 main 字段,是則讀取 main 字段下定義的入口桐磁。
- 如果沒有 package.json 文件悔耘,則讀取文件夾下的 index.js 或者 index.node。
- 如果都 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';
// 最后轉(zhuǎn)換為
const vue = require('./node_modules/vue/dist/vue.runtime.common.js');
而 vue.runtime.common.js 文件的最后一行是:module.exports = Vue;
看峻,就正好跟我們平時使用時的 new Vue({})
是一致的,這就是 import vue from 'vue'
的過程了衙吩。
當(dāng)然互妓,這個是我們平時使用得最多的導(dǎo)入方式,還有其他一些導(dǎo)入規(guī)則坤塞,都可以在 nodejs 的文檔 中找到冯勉。