將Webpack套用至現存的專案

網路上有不少手把手一步一步把Webpack專案建構起來的教學,但如果你是想要把手邊亂七八糟的專案導入 Webpack 呢?
0. 前言
webpack 有不少雷來自於版本的差異,如果你上網估狗做法之後剪剪貼貼,很有可能會因為版本更新了而無法使用。所以這件事情寫在最前面,以下分享的內容基於webpack 4.43.0 ,並預設您已裝好node.js以及npm,且具備基礎知識。
為什麼我要導入 Webpack
簡單提一下我的原始專案,他是一隻單一一個 html 檔的專案,不過他有好幾隻的 js 檔,為了對應不同的業務需求有時候要載入a.js、b.js,有時候卻載入a.js跟c.js,每次版本切換就要把某幾行註解掉,另外幾行取消註解,html 檔本身也有幾行要修改,久了就覺得我應該要用工具做掉這件事情,於是找上了 Webpack。
如果你是為了類似的需求才找到這篇文章,那應該會有點幫助。
1. 開新專案
先開個新資料夾再慢慢把檔案搬進來吧。
開好之後 cd 進去,然後開始初始化
1 | $ npm init |
然後在根目錄新增幾個資料夾,以下這些資料夾&檔案命名都隨便,但有些命名習慣可以遵守,不吃虧。
1 | ./src/ //放程式碼 |
接著新增兩個檔案
1 | ./index.js //程式的進入點 |
然後將建置用的指令放到package.json裡
1 | "scripts": { |
這樣,只要執行npm run build就會建置了 (但你現在執行會報錯就是,畢竟設定檔是空的)
所以來編輯一下webpack.conf.js吧
1 | const path = require("path"); |
這時候再建置一次,你的 dist 資料夾內就應該有個output.js檔,這樣就算是會動了。
2. 撰寫index.js
整理一堆 js 檔成為一個樹狀結構是這邊主要要做的事情。
由於有點複雜,我們先講結論:
- 梳理樹狀結構,找到相依樹的根當成
index.js - 其他被依賴的
js檔模組(module)化 - 掛載會直接被 html 呼叫的程式到全域變數
梳理結構
原始的 html 可能長這樣:
1 | <head> |
你要自行梳理出例如a才是主程式,並依賴於b跟c這樣的關係
這樣的例子中,你就可以把a.js的內容移植到index.js內
於是現在變成這樣:
1 | ./index.js //原本的a.js |
模組化
原本的b.js檔可能是扁平的
1 | const A = 0; |
反正這樣掛載到 html 上可以直接呼叫getA()使用,但透過 webpack 注入的話其他模組是無法呼叫到這些方法與變數的,所以要使用關鍵字export對外部公開
1 | //依然無法被外部存取 |
這時候可以在index.js透過以下方法使用
1 | import { getA } from "./src/b.js"; |
掛載全域變數
上述是模組的部分,但如果你的程式碼是會直接被 html 使用的呢?例如這樣
1 | <form onsubmit="start(); return false"></form> |
1 | function start() { |
這時候你可以把方法掛載到全域變數解決問題
1 | window.start = function () { |
3. 設定插件
搞定 javascript 的部分,那其他的檔案呢?
使用HtmlWebpackPlugin導入 html
首先要有一個概念是 webpack 是以打包 js 檔為主的工具,所以你要引入任何不是 js 檔的東西都要額外裝插件,這跟我們單純在寫網頁,是把各種東西引入到 html 檔內的思維不太一樣。
安裝
1 | $ npm i -D html-webpack-plugin |
然後在webpack.conf.js啟用插件
1 | const HtmlWebpackPlugin = require("html-webpack-plugin"); |
其中filename是輸出時的檔案名稱,而template則是你的原始 html 檔。
別忘了把你的 html 檔要被動態載入的資源清乾淨,包括js跟css,所有動態載入的東西最後會被自動放到body末端,像這樣:
1 | <html> |
也就是說,不希望動態載入的東西請留在 html 內
使用CopyWebpackPlugin複製靜態資源
前面提到不希望動態載入的東西要維持原狀,這些東西可以借助這個套件在建置的時候自動複製到/dist資料夾內
安裝
1 | $ npm i -D copy-webpack-plugin |
啟用
1 | const CopyWebpackPlugin = require('copy-webpack-plugin'); |
參數應該很好懂,從./static複製到./dist
使用SCSS
這年頭應該沒有人直接寫 css 檔吧?地圖砲
安裝相依
1 | $ npm i -D node-sass sass-loader style-loader |
啟用
1 | module.exports = { |
就這樣,然後就可以直接在index.js引入你的scss檔了
1 | import "./src/style.scss"; |
4. 其他可以考慮設定的東西
路徑別名
可以隨便指定一個符號當成根目錄,這樣可以解決惱人的相對路徑問題
1 | module.exports = { |
程式碼壓縮
網路上可能會查到UglifyJsPlugin之類的工具,但這東西已經被 webpack 棄用了,要改用以下方法:
安裝
1 | $ npm i -D terser-webpack-plugin |
設定
1 | const TerserPlugin = require("terser-webpack-plugin"); |
詳細設定: TerserWebpackPlugin
開發用伺服器dev-server
如果你不想改一行就要 build 一次,你會需要這東西
安裝
1 | $ npm i -D webpack-dev-server |
然後將的指令放到package.json裡
1 | "scripts": { |
這樣就可以透過npm run dev開啟一個開發用伺服器預覽效果,並支援 hot reload
後記
上面做了一大堆,其實我的原始需求: 根據業務需求自動載入我需要的某幾隻程式都還沒做 XD
這我最後是透過分別寫兩個webpack.conf.js檔並分開建置完成的
1 | $ webpack --config webpack.a.conf.js |
過去寫過好幾個用vue-cli建立起來的專案,雖然知道其是建立在 webpack 的基礎上完成,但實際從頭開一個 webpack 的專案才知道原來這麼多東西要設定…
因為我自己也還在一邊寫一邊學,以上內容如果有錯歡迎告知一下,謝謝:D