[Webpack]No.1 模組化 JavaScript 的方法

前言

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

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

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

前置作業

  • 準備一支 index.html ,並且引入兩支檔案

  • math.js 內容如下

  • all.js 內容如下

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

使用 ES5 export 與 require

接著我們使用 ES5 module.exportsrequire 試著將 math.js 模組化…。

你會發現根本不能運行,因為 module.exports 與 require 只有 node.js 環境下才可以使用

不管是 ES5 module.exportsrequire 或 ES6 importexport ,如果想在瀏覽器環境使用模組化 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 內配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var math = '我是全域變數,會影響到其他人';

    function double(num){
    return num*2;
    }

    function triple(num){
    return num*3;
    }

    module.exports = {
    double: double,
    triple: triple,
    };
  • all.js 內配置

    1
    2
    3
    4
    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 的語法,目前 exportimport 支援的程度如下:

嗯…好像還是紅紅的,所以要使用之前還是得先查一下支援程度,或者就乾脆使用 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 才能進行,還很納悶的想說語法都沒錯怎麼不能跑。

0%