Webpack 入門指南 - 2.模塊

這一次我們談?wù)勀K問題。

通常我們希望這個(gè)項(xiàng)目可以分為多個(gè)獨(dú)立的模塊,比如,上一次提高的 hello 函數(shù),如果我們定義為一個(gè)模塊,其它模塊引用之后,直接調(diào)用就好了。在前端怎么使用模塊呢?這可說(shuō)來(lái)話長(zhǎng)了。

如果我們把 hello 函數(shù)定義在文件 hello.js 中,內(nèi)容如下:

function hello(){
    alert("Hello, Webpack!");
}

然后把主入口函數(shù) index.js 的內(nèi)容寫成下面的內(nèi)容,你應(yīng)該會(huì)得到一個(gè)錯(cuò)誤信息。

require("./hello");

hello();

對(duì)話框是彈不出來(lái)的。錯(cuò)誤信息如下:

Uncaught ReferenceError: hello is not defined, 明明定義了 hello 函數(shù),卻偏偏說(shuō)找不到。

1. CommonJs 模塊

CommonJs 是目前比較流行,也是出現(xiàn)較早的模塊技術(shù),它誕生于 NodeJs,使用起來(lái)其實(shí)比較簡(jiǎn)單。

首先,它把一個(gè)獨(dú)立的文件看成一個(gè)模塊,比如上面的 hello.js 文件,就可以當(dāng)成一個(gè)模塊。模塊的名稱就是文件名稱,但是可以不用提供擴(kuò)展名 .js,直接使用文件名就可以。

在導(dǎo)入一個(gè)模塊的時(shí)候,使用 require 函數(shù),注意是函數(shù),并不是關(guān)鍵字,JavaScript 并沒有提供這個(gè)關(guān)鍵字。函數(shù)的參數(shù)就是模塊名稱,不過(guò),要注意模塊分為兩種,自定義的模塊和系統(tǒng)模塊。

自定義的模塊必須使用 . 或者 .. 開頭的相對(duì)路徑,如果都在同一個(gè)目錄下,也需要使用 . 來(lái)表示當(dāng)前路徑,比如上面用到的 require("./hello")。

不是使用 . 或者 .. 開始的相對(duì)路徑的,都稱為系統(tǒng)模塊,系統(tǒng)模塊的路徑其實(shí)在 node_modules 文件夾中,每個(gè)子文件夾就是一個(gè)系統(tǒng)模塊。

require 函數(shù)的返回結(jié)果就是模塊導(dǎo)出的內(nèi)容。

我們的模塊沒有導(dǎo)出任何內(nèi)容。所以,雖然被 index 引用了,但是在 index 中卻是無(wú)法訪問的。這也說(shuō)明模塊中定義的函數(shù)其實(shí)是局部函數(shù),并不是通常意義上的全局函數(shù)了。

我們要在模塊中導(dǎo)出內(nèi)容怎么辦呢,CommonJs 提供了 exports 對(duì)象。

在 CommonJs 模塊中,希望導(dǎo)出的內(nèi)容必須通過(guò) exports 對(duì)象,這是 CommonJs 系統(tǒng)提供的系統(tǒng)對(duì)象,我們可以直接使用。導(dǎo)出的內(nèi)容以鍵值對(duì)的形式定義到這個(gè)對(duì)象上,鍵就是導(dǎo)出的名稱,值就是準(zhǔn)備導(dǎo)出的內(nèi)容。

比如,我們希望將 hello 函數(shù)導(dǎo)出為名為函數(shù)的函數(shù),好像挺繞的,其實(shí)很簡(jiǎn)單。