node.js api系統性學習1 require用法

先講講模塊加載機制

require() __filename,__dirname 實際上不是一個全部變量,而是每個模塊內部的。
我所講的是當前版本6.10的版本,比較穩定的
在node.js 模塊和文件是一一對應的,一個模塊就是一個文件

__filename是打印出當前文件所在的絕對路徑
__dirname是打印出當前文件所在的文件夾目錄

現在比方說在一個同目錄下叫node文件夾

b.js

let a = "我是b模塊"
console.log(a) 

a.js

 require("./b.js')  //我是b模塊

如果我們再換個方式想我們既然把b.js模塊加載進來了,我們也可以使用b.js里的a 變量
a.js

 require("./b.js')  
console.log(a) //會報一個錯,會報a is not defined

這是為什么呢?
這是因為模塊加載機制,模塊看似本地變量的全局變量但是在導入其它模塊中就是一個私有變量,在其它模塊是訪問不到的,除了你export出去等方法
這是因為在執行模塊代碼之前,Node.js 會使用一個如下的函數包裝器將其包裝:

(function (exports, require, module, __filename, __dirname) {
// 你的模塊代碼實際上在這里
});

它保持了頂層的變量(用 var、const 或 let 定義)作用在模塊范圍內,而不是全局對象。
它有助于提供一些看似全局的但實際上是模塊特定的變量,例如:
實現者可以使用 module 和 exports 對象從模塊中導出值。
快捷變量 __filename 和 __dirname 包含模塊的絕對文件名和目錄路徑。

如果在a模塊導入b模塊的方法
我們可以把所有方法掛在exports對象上面導入a模塊
b.js

exports.add = (a) => {
    console.log(a+1)
}

exports.reduce =(a) => {
    console.log(a-1)
}

a.js

const demo = require('./b.js')  //用demo這個變最去接收這個b.js文件導出來的export對象 
demo.add(1)    //2             用點來調用掛在上面的方法
demo.reduce(1) //0

如果你想導出一整個對象或者構造函數,你可以用module.exports來導出,是用來導出一整個對象
b.js

module.exports = (a)=>{
     return {
        add () {
            console.log(a+1)
        },
        reduce () {
            console.log(a-1)
        }
     }
}

因為函數也是對象,return出去一個對象,掛著add 和 reduce方法

a.js

const b = require('./b.js')

var demo = b(1) 
demo.add()  //2
demo.reduce() //0
訪問主模塊

還是前面的例子
require.main代表node運行的主模塊,想當于module === 主模塊
b.js

console.log(require.main === module)

運行node b.js 會發現 返回true 因為b.js是node運行的主模塊

a.js

require(./b.js)
console.log(require.main === module)

運行node a.js會發現 返回false ,true
因為第一個false是b.js打印出來的,因為此時主模塊已經變成了a.js
第二個true 是a.js打印出來的,因為此時主模塊已經是a.js了

前面說過每個文件都是一個模塊,也可以看作成一個對象,模塊自帶一個filename屬性,代表此模塊絕對路徑存放的地方

b.js

console.log( module.filename)

a.js

require(./b.js)
console.log( module.filename)

運行node a.js會發現 打印出來,這個是我存放文件或者模塊的絕對路徑
D:\node\b.js
D:\node\a.js

再來看看 require.mian.filename
這個代表模塊運行時候主模塊的絕對路徑,什么意思呢,不大好理解,我給大家演示一下

b.js

console.log(require.main.filename)

如果我先單獨運行node b.js會發現
D:\node\b.js 這個很顯然因為運行的主模塊是b.js所以此模塊運行時主模塊的絕對路徑就是自己

a.js

require(./b.js)
console.log( module.filename)

我們把b.js引入a.js中我們再node a.js運行一下看看什么結果
D:\node\a.js
D:\node\a.js
我們會發現無論是 b.js 還是 a.js模塊打印出來的都是 D:\node\a.js 因為現在node主入口運行的文件就是a.js所以 他里面所有引入的模塊都是從這個a.js主模塊的路徑進入的,所以b.js主模塊路徑也是D:\node\a.js,這個比較煩大家可以去試一下就明白了

模塊加載機制

  1. 如果 X 是一個文件,加載 X 作為 JavaScript 文本。結束
  2. 如果 X.js 是一個文件,加載 X.js 作為 JavaScript 文本。結束
  3. 如果 X.json 是一個文件,解析 X.json 成一個 JavaScript 對象。結束
  4. 如果 X.node 是一個文件,加載 X.node 作為二進制插件。結束

在Node.js中,可以使用require.resolve函數來查詢某個模塊文件的帶有完整絕對路徑的文件名,代碼如下所示。
b.js

let b = require.resolve("./b.js")
console.log(b) 

運行node b.js 會發現打印出來此時./b.js文件的絕對路徑
D:\node\b.js
注意不會加載此文件,只是返回此文件的絕對路徑

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 模塊 Node 有簡單的模塊加載系統。在 Node 里,文件和模塊是一一對應的。下面例子里,foo.js加載同一個...
    保川閱讀 611評論 0 0
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    Myselfyan閱讀 4,102評論 2 58
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,126評論 0 1
  • 個人入門學習用筆記、不過多作為參考依據。如有錯誤歡迎斧正 目錄 簡書好像不支持錨點、復制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,505評論 1 37
  • No.63 一天結束,表現一般,思考很多。 今天,參與了一場慶典活動,作為活動中重要的音響師,我卻在會議開始前5分...
    水淺_bling閱讀 368評論 3 1