模組化 JavaScript 的方法

pvt5r486
7 min readApr 30, 2019

--

如果網站的規模不大,可能單純寫一支 all.js 就能搞定了,但如果今天與別人合作或者網站規模比較大,這時若只單靠一支 all.js 肯定是落落長的程式碼,每次要修改就得找半天,這樣是非常辛苦的。所以我們需要把模組化 JavaScript ,這樣會方便很多,而模組化的好處遠不只這些,就不贅述了。

Photo by Nicole Honeywill on Unsplash

把檔案分開就好嗎 ? 這我以前就這麼做了!

這邊的模組化的意思並不是把程式碼拆成多支 .js 檔並且在 index.html 內引入,因為這麼做其實並不算真正的把檔案分開,在 JavaScript 內仍然把它們視為同一個檔案,只是堆疊在一起,就好比這樣:

前置作業

  • 準備一支 index.html ,並且引入兩支檔案
  • math.js 內容如下
  • all.js 內容如下

於是輸出結果,會發現 all.js 會把寫在 math.js 內的全域變數給印出來,這代表程式執行時它們會拼合成一支檔案,而透過觀察這麼做會產生 2 次的 request ,因為用了兩次的 script 標籤。

使用 ES5 export 與 require

接著我們使用 ES5 module.exports 與 require 試著將 math.js 模組化...。

你會發現根本不能運行。

因為 module.exports 與 require 只有 node.js 環境下才可以使用

不管是 ES5 module.exports 與 require 或 ES6 import 與 export,如果想在瀏覽器環境使用模組化 JavaScript 就必須透過 webpack 來搞定!

於是我們需要做一些事前準備:

  • 下載安裝 npm - 可以到 node.js 下載安裝包

打開 CLI 輸入 node -v ,若出現版本號代表安裝成功。

  • 切換到上個範例的資料夾內,輸入:
npm install webpack webpack-cli --save-dev
可以看到版本號代表成功安裝

接著可以到 webpack 官網看看如何起手

好的,我們要先在專案資料夾內建立一個叫做 webpack.config.js 的檔案,接著複製貼上這些程式碼,而這些程式碼的涵義也很簡單:

  • entry : 進入點,代表引用這些 modules 最主要的地方
  • path:檔案輸出的路徑
  • filename:檔名

都設置完之後,大致上長這個樣子:

接著回到 index.html ,引用我們打包後的 bundle.js 檔案

這樣事前準備就都完成了,終於可以進入使用 ES5 module.exports 與 require 的部分。

  • 首先在 math.js 內使用 module.exports 將函式匯出
  • 接著 all.js 把檔案 require 進來
  • 最後別忘了執行 .\node_modules\.bin\webpack 打包產生檔案

接著我們就可以到瀏覽器上觀察囉~

發現函式的確成功的呼叫了,而且並不會受到 math.js 內的全域變數干擾,而且也因為只有使用一次 script 標籤,因此 request 只有一次。

想匯出的不只一支函式?可以建立物件來達成!

  • math.js 內配置
var math = '我是全域變數,會影響到其他人';function double(num){
return num*2;
}
function triple(num){
return num*3;
}
module.exports = {
double: double,
triple: triple,
};
  • all.js 內配置
const myModule = require('./module/math');
console.log(myModule.double(10));
console.log(myModule.triple(10));
console.log(math);

因為匯出的東西是物件,所以我們也必須使用物件的方式來取用。

別忘了使用指令打包輸出,接著來看看結果:

蠻簡單的,對嗎?

使用 ES6 export 與 import

使用 ES6 比較尷尬的點是,有些流覽器並沒有完全支援 ES6 語法,因此必須使用 ES5 或者透過 Babel 來轉換 ES6 的語法,目前 export 與 import 支援的程度如下:

嗯...好像還是紅紅的,所以要使用之前還是得先查一下支援程度,或者就乾脆使用 Babel 搞定這一切。

怎麼使用

  • math.js 配置
  • all.js 配置

可以看出跟 ES5 的差別在哪裡:

  • 函式前面可以加上 export 代表匯出該函式
  • 使用 import {} 承接,{} 內變數名稱需與匯出的函式相同
  • 可以 export 的東西不只函式,變數也可以

除了這樣子寫以外,還有一些變化

  • import 可以使用 * 號配合 as 賦予別名

而這個 myModules 是什麼呢?

是個物件,所以可以像一般使用物件的方式一樣操作即可。

  • 不想每個函式都加上 export,可以這麼做

這邊要特別注意的是 export{ } 並不是物件

  • export 配合 default ,就可以 import 時不加 { } ,但只能有一個 default。

是不是覺得 import 沒有 { } 感覺比較順手呢?

心得

個人比較喜歡取 import * 號取別名配合 export{ } 的方式,感覺最順手。

ES6 雖然好用歸好用,不過這樣的方式似乎目前支援度還是蠻差的,還是得透過 Babel ,如果確定專案會用上 Babel 了,那就不用客氣的用吧!

如果不想使用 Babel 那就使用 ES5 的 require + module.exports 囉。

這邊撞了蠻多牆的,因為一開始很單蠢,不知道模組化必須得透過 Webpack 才能進行,還很納悶的想說語法都沒錯怎麼不能跑。

--

--