Webpack 實作入門1:寫給 「非Node.js開發者」 的教學
| 2017/08/21 | 1 則迴響
會寫這篇純粹是想整理一個單純的 Webpack 教學 (給非 Node.js 開發者)
我自己的經驗是這樣的。
一開始想學習 Webpack 時,都會先在網路上找教學,但通常都是後端也使用 Node.js 的人或純前端工程師寫的教學,很容易會談太多範例是基於他們自己的開發流程,所以總是一開始就會提到像是 react, jsx … 等等,範例語法也常常出現 Node.js 的寫法,以至於很難理解單純的 Webpack 要怎麼應用在自己的(非node.js)專案上。
有鑑於此,我想自己邊摸索邊寫篇教學來記錄一下,基本上是寫給非 node.js 的開發者,像是 WordPress 的佈景開發者XD。
我的開發環境是 MAC OS,如果你用的是其他OS,概念上應該都是一樣的,但能不能成功就隨緣了~ XD
完整範例檔在:https://github.com/mrmu/webpack-tutorial-1-examples,但還是希望你手動自己建立自己的範例,這樣印象最深刻。
本篇教學只要求你有基本的 HTML + CSS + JavaScript/jQuery 編寫經驗就好了,然後你必須不害怕輸入超級簡單的命令列指令。
最好你有一點學習 webpack 或 node.js 失敗的經驗,這樣至少 NPM 和 Webpack 就不用再裝了XD。(對了,本篇就不寫 NPM 和 Webpack 的詳細安裝方法,因為別的教學都有寫,而且我相信你一定看得懂怎麼裝XD)
我覺得就先從單純的 HTML+CSS+JS 組成的簡單頁面開始來看,比方我們的專案目錄底下有這些靜態的檔案:
專案目錄名稱/ │ ├── index.html └── src/ ├── css/ │ ├── style.css │ └── buttons.css └── js/ ├── init.js └── main.js
分別看一下它們的內容吧。
index.html 長這樣:
<!-- index.html --> <!DOCTYPE html> <html lang="zh_TW"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>認識 Webpack</title> <!-- 載入 bootstrap --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous"> <!-- 載入自製的css --> <link rel="stylesheet" href="src/css/style.css"> <link rel="stylesheet" href="src/css/buttons.css"> </head> <body> <h1>認識 Webpack</h1> <button id="my-button">不是有很多其他教學嗎,幹嘛又寫?</button> <p id="my-desc">想單純認識 Webpack 嘛</p> <!-- 載入 jquery & bootstrap --> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script> <!-- 載入自製的js --> <script src="src/init.js"></script> <script src="src/main.js"></script> </body> </html>
其實很單純,除了載入 jQuery,還放進我慣用的 bootstrap (這個非必要)。
src/css/style.css 長這樣:
/* src/css/style.css - 定義基本的樣式 */ body { font-family: Helvetica, Arial, sans-serif; text-align: center; } h1 { font-size: 28px; margin: 20px; } p { border: 1px solid black; padding: 20px; margin: 30px auto; width: 50%; font-size: 18px; }
src/css/buttons.css 是這樣:
/* src/css/buttons/css - 定義一些按鈕的樣式 */ button { border: 1px solid black; background-color: white; padding: 8px; font: inherit; cursor: pointer; outline: none; } button:hover { background-color: #ccc; }
css 檔都很單純,隨便你寫都可以。
src/js/init.js 是:
/* src/js/init.js - 定義一些 DOM 變數 */ var myButton = $('#my-button'); var myDesc = $('#my-desc');
就只是很假掰地用來定義一些 dom 變數。
src/js/main.js 也很簡單:
/* src/js/main.js - 寫一些 jQuery 效果 */ myDesc.hide(); myButton.on('click', function(e){ myDesc.toggle(); });
簡單來說,就是我按了按鈕 myButton,就會去 show/hide 底下的描述區塊 myDesc。
你一定會發現 init.js 和 main.js 根本可以很直覺地寫在一起,但我在這裡刻意分離它們,除了裝逼外也是為了描述相依性所做的簡單配置。
init.js 和 main.js 有相依關係,就是指它們的載入順序不能隨便調換,因為 init.js 裡有定義 main.js 需要的變數,所以你在使用 main.js 前,一定要先載入 init.js,不然就會 GG。
到這裡,請先確定好你的 demo 頁是可以正常運作的 (按按鈕會show/hide下方描述)。
先這樣看待 Webpack
它是一個打包 “前端” 檔案的工具,它也是用 javascript 寫的,要使用 Webpack 不是在它身上點兩下,而是在命令列打指令執行,然後它就會將你網站目錄下某個「來源目錄」裡的前端檔案 (js, css/scss, 圖片檔…),做一些優化和打包,然後再另存到其他「目標目錄」下,而你的網頁只要載入這些處理後的目標檔案就好。
要安裝 Webpack 需要透過 NPM 來幫忙將它安裝在網站專案上。
安裝 NPM
NPM 是所謂套件管理工具,可以協助我們快速安裝 JavaScript 工具套件,我們需要它來幫忙安裝 Webpack,所以先下載安裝 NPM。(還沒裝的人快去 google 怎麼裝,我等你 ;D )
接著在專案目錄 (跟 index.html 同層) 下執行 npm init:
$npm init
之後會提示一些問題,像是專案名稱,這個隨你填,我是填 webpack-test,然後 license 我填 MIT…,完畢後你就會發現多了一個 package.json。
接著我們要用 NPM 安裝 Webpack,在專案目錄下執行 npm install webpack –save-dev:
$npm install webpack --save-dev
跑完了就會發現 webpack 開始安裝並且 package.json 裡的 devDependencies 屬性多了一個 webpack 的相依套件描述。
package.json 就是在紀錄你的專案用了哪些套件,邊裝邊紀錄,這樣對後續將網站專案部署到別的地方很有幫助,之後只要下 npm install 就會都裝好。來看一下 package.json 的內容:
{ "name": "webpack-test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", }, "author": "", "license": "MIT", "devDependencies": { "webpack": "^3.5.1" } }
開始試著使用 Webpack
一開始先修改一下 package.json,因為我們需要透過 NPM 來執行 Webpack,在 scripts 屬性描述的地方加上一段 build 指令:
{ "name": "webpack-test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack src/js/main.js dist/bundle.js", }, "author": "", "license": "MIT", "devDependencies": { "webpack": "^3.5.1" } }
這段 “build”: “webpack src/js/main.js dist/bundle.js” 就是指在執行 npm run build 後,會使用 webpack 將「來源檔案」 src/js/main.js 打包成「目標檔案」dist/bundle.js。
存檔後如果你直接在命令列執行 npm run build:
$npm run build
應該會出現一堆錯誤訊息,為什麼呢?因為 main.js 沒有「匯入」 init.js,我們是用 index.html 的方式載入 init.js 的,Webpack 沒那麼神,不知道要去載入 init.js。
JavaScript 的 Module 載入機制 – ES6 (ES2015)
js 可以 import 其他的 js,但要使用用 ES6 的 Module 語法,所以要用 export 和 import 的方式,讓 main.js 可以匯入 init.js 裡的變數定義。
src/js/init.js 改完後的內容:
/* src/js/init.js */ export var myButton = $('#my-button'); export var myDesc = $('#my-desc');
主要是前面加上 export,把定義匯出來給其他檔案使用。
src/js/main.js 改完後的內容:
/* src/js/main.js */ import {myButton, myDesc} from './init'; myDesc.hide(); myButton.on('click', function(e){ myDesc.toggle(); });
主要是第一行加上一段 import 描述,把 myButton 和 myDesc 兩個元件從 init.js 匯入使用。
改完以後,你會發現你的瀏覽器應該不支援這種寫法,所以現在直接開 DEMO 網頁,應該會GG。先不要太急,因為 Webpack 看得懂 ES6,先讓它 Build 看看,在網站專案目錄下執行 npm run build。
$npm run build
如果順利的話,Webpack 會提示成功打包到 dist/bundle.js 的訊息,然後你的專案目錄下就會多了一個 dist 的目標目錄,裡面就會有一個 bundle.js,它就是打包完的目標檔案。
將index.html 改為載入 dist/bundle.js
打包好的目標檔案一定是主流瀏覽器都看得懂的「優化後」的檔案,所以改成載入它就好:
...(略)... <!-- 載入自製的js --> <!--<script src="src/init.js"></script>--> <!--<script src="src/main.js"></script>--> <script src="dist/bundle.js"></script> ...(略)...
DEMO 網站應該回復正常運作了。
內建的JS最小化功能
打開 package.json,在 build 指令下再加一行: “build:prod”: “webpack src/js/main.js dist/bundle.js -p”
跟 build 很像,只是最後多加一個 -p。
在專案目錄下執行:
$npm run build:prod
此時 webpack 會幫忙把 bundle.js 以最小化的方式打包起來。
下集待續
第一集我們重點放在認識 Webpack 是一個什麼東西,然後簡單看一下它怎麼運作,不貪快。
現在你一定會覺得意猶未盡吧,看看那個 build 指令也太弱了吧,怎麼只能打包一個檔案呢?說好的打包一大堆檔案呢?
下一篇我們來談 webpack.config.js 設定,包含怎麼把 css/scss 也一起處理好再打包!
下一篇:https://audilu.com/2017/08/21/webpack-tutorial2-css-scss/
標籤:javascript, webpack
分類:JavaScript技巧, 網站設計
本文作者是Audi Lu
1 則留言
[…] 前篇教學在: https://audilu.com/2017/08/21/webpack-tutorial/範例檔在:https://github.com/mrmu/webpack-tutorial-1-examples […]