Why do we need Webpack?
在沒有打包工具以前, 一個網頁程式中包含多個CSS, HTML, JS, 而JS中有些可能是外部套件,有些可能會高度耦合, 導致import的順序不可輕易更動。後來有了Grunt和gulp, js可以被整合成一支檔案, 就不用擔心引入的順序問題, 可是這些工具無法判別哪些是套件。
Webpack可以判別哪些是額外使用的套件, 並且幫助我們打包程式碼, 不管是javascript, typescript, css, sass…, Webpack都可以幫我們把繁雜且交錯的程式碼整合成一份, 就不用再去擔心引入的順序問題
範例
在webpack之前
在還沒有引入webpack之前, 我們的專案會這樣寫
hello.js和index.js可以被當作是套件, 或是js模組。
在hello.js中定義一個function
hello.js
1 | function hello() { |
在index.js中呼叫
index.js
1 | hello(); |
這時打開瀏覽器, 會跳出錯誤:hello is not defined
問題並不在這兩支檔案的程式碼中,而是他們在index.html中引入的順序問題。
1 | <script src="./src/index.js"></script> |
呼叫hello的index比hello被定義的位置hello.js還要先被import和執行, 此時hello尚未產生。
正確的順序應該是這樣
1 | <script src="./src/hello.js"></script> |
這個例子說明了相依性(dependency)產生的問題
現在只有兩支檔案, 所以記憶他們的順序並不困難, 可是當引入的檔案多,且彼此的相依關係又很複雜的時候,就會要花很多心力。
這時可以使用Webpack幫助我們整合內部的模組和外部套件,打包成一支js,也只要在html中引入這一支js就好,這支檔案就是我們的入口檔案(entrypoint)
引入webpack
在終端機中使用npm init -y
來啟用npm,參數-y
代表默認預設配置, 就不用自己設定一堆有的沒的。
這個指令會產生一個package.json檔案
package.json
1 | { |
接著安裝webpack, 在終端機輸入以下指令npm install webpack webpack-cli --save-dev
安裝webpack和其command line interface, 指令介面工具, 就是可以在終端機中輸入webpack的指令啦
--save-dev
的意義可以見這裡
現在package.json會變這樣
1 | { |
此時工作目錄中新增了一個資料夾: node_modules, 套件的原始碼都會放在這裡
之後若是有人下載這份專案, 想要在自己的電腦上運作的話, 可以看這份檔案找套件的相關紀錄, 以及跑npm install
把需要的套件下載起來
webpack設定檔
在根目錄新增一支webpack.config.js
的檔案
這支檔案會是一個物件
webpack.config.js
1 | module.exports = { |
在package.json新增一個腳本
1 | "scripts": { |
我們可以把html中的script tag移除了, 改成引入剛剛設定的output檔
index.html
1 | <!-- 我們要引入的js是打包完的, 根據剛剛的設定, 它會在dist資料夾中 --> |
我們需要在剛剛設定的入口(entrypoint)檔案中import所有我們需要的東西, 打包會從這裡開始
./src/index.js
1 | import hello from './hello.js'; |
被引入的檔案要記得export
1 | function hello() { |
產生dist
設定完之後,可以來打包看看了。
跑npm run build
開始打包,沒想到跳錯
這個錯誤是說,我們的設定檔不符合webpack的api要求, 因為目前輸出的路徑是相對路徑, 而api要求絕對路徑
我們目前的輸出(output)路徑是這樣寫
1 | output: { |
要改成絕對路徑, 可以運用node.js底下的path改寫
1 | // 引入node.js中的path物件 |
可以看到根目錄底下產生一個名為dist的資料夾, 裡面放的是打包後的檔案, 檔名跟我們在設定檔中作的設定一致
js也能運作了