寫了快一年的 Vue ,最近剛接觸 React ,我還挺中意這種架構跟撰寫方式的,所以順手研究了一下 Webpack。如果你在開發時是使用react-create-app 之類的手腳架,應該會跟 Vue 的 vue-cli 工具蠻類似的。但這類工具不太容易客製化的調整設定(有時候,你並不需要那麼多功能)。
所以為了讓自己能夠適應各種需求跟情況,我打算試試看打造一個適合自己做開發的 React 起始專案,方便之後進行任何需要 React 開發的時候使用。
適合閱讀對象
適合有至少接觸過手腳架工具或是 Gulp、Grunt 等 Task Runner 處理檔案的 Js 開發者,完全初學者建議先用手腳架練習即可,以免未入門先棄坑。
大綱
因為文章內容有點多,所以我預計分為三個部分來解說:
第一部分
- 配置說明
- webpack 緣由
- 安裝 webpack
- webpack.config.js 設定及說明
第二部分
- 使用 package.json 建立自己的 script 指令集
- webpack-dev-server
- 開始撰寫 JS 程式碼
第三部分
- 引入 React
- 搭配 Eslint 做檢查
- 延伸文章
配置說明
預計會使用到的工具如下 :
- webpack : 一定要的
- webpack-dev-server : 加速開發流程
- babel : 用來把專案裡的 JS 及 JSX 轉譯成為瀏覽器看得懂的程式碼
- sass : 方便做 CSS元件模組化,ㄧ樣需要轉譯成 CSS
- eslint : 檢查 JS 撰寫習慣必備
Webpack
什麼是 Webpack ?
Webpack 是一套非常完整的前端打包工具,他讓開發人員透過設定檔的方式很方便的去規劃專案架構。早期我們撰寫 Sass 的時候是透過 Grunt 或是 Gulp 等Task Runner來做轉譯,但以現在前端開發的規模,除了 Sass 轉譯,我們常常還需要處理其他事情,例如 minify、uglify 及 JS新舊版轉譯,當這些事情開始複雜起來的時候,相較於一個一個去撰寫 Task 的內容,有一個統一設置入口的 Webpack 就方便快速許多。
安裝 Webpack
Webpack 必須在 node 環境下執行,所以請注意你的系統是否有安裝 node ,如果沒有,我推薦你使用 nvm 安裝,除了可以方便的管理你的 node 版本,連 npm 都幫你裝好了。
Step1. 產生 package.json
你的專案目錄底下必須 package.json 檔案以紀錄你使用的套件,這邊可以使用指令:
npm init
來產生 package.json,輸入後會有一些關於設定的問題,如專案名稱或是版本號,請依照自己的意思輸入就好。
Step2. 用 npm 安裝webpack
webapck 只會在開發環境使用,所以安裝的時候請加上參數
npm install --save-dev webpack
Step3. 使用 webpack-cli
如果一開始不熟,想要快速產生設定檔模板的話,我找到了一個還不錯的工具: webpack-cli,它用起來就像上面 npm init ,使用互動介面來幫你產生設定檔。
npm i webpack-cli @webpack-cli/init
npx webpack-cli init
webpack-cli還有其他方便的指令,可以參考他的Github,但我後續還是比較習慣手動修改內容。
以上有幾個地方值得注意的:
-
第二個問題提到的「 entry file 」 指的是 Webpack 來抓取你來源檔,準備編譯輸出時,所「進入」的第一個檔案,你可以想成是進入點。
-
第三個提問:「what the location of the app…」指的是進入點檔案的確切位置(相對於專案根目錄)
-
第四個提問:「 which folder will your…」指的是 檔案打包處理完之後要輸出到哪裡。
最後一個提問由於我還是比較習慣 使用sass,所以我選擇它。
webpack.config.js 設定及說明
產生完 config 檔之後,你會在裡面最先看到的應該有 module 、 entry 、 output 、plugins 四個設定,而這也是我們在調整的時候最長會需要注意的四個設定,以下將一一簡單介紹。
( 使用 webpack-cli 所產生的 config 似乎不會產生entry設定,但沒關係,你可以之後再補上,而且 webpack 也會有預設值,所以不用擔心會有問題。 )
entry :
進入點,你可以直接給一個路徑字串,但他其實還可以用物件跟陣列來表示,這邊先不詳細說明。
entry: './app.js',
output
輸出點,表示檔案被處理完之後要放的位置,最常被使用的名稱是「 dist 」。
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
},
module
用來定義不同種類的檔案(模塊)是如何被處理的,會根據不同的副檔名套用不同的 rule ,也是最主要告訴 webpack 檔案如何被處理的設定,舉例來說,剛剛在 cli 設定的時候,最後的預處理我選擇了 sass ,他就在模板裡幫我產生了下面的內容 :
module: {
rules: [
{
test: /\.(scss|css)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
}
]
},
以上設定的意思是「只要是.scss 或是 .css結尾的檔案,就幫我使用下列的處理方式。」,loader在 webpack 裡面主要是用來做轉譯處理的模組,所以記得在使用你想要的 loader前,要先使用 npm 安裝喔~
這邊要注意的是,當使用多個 loader 處理檔案時,loader 是從最後面開始被載入的(bottom-up),知道這點之後應該就可以理解上面的意思:
- 先透過 sass-loader 將 sass 檔案轉成 css 後
- 然後透過 css-loader ,讓我在 js 檔裡可以直接引入
- 最後透過 style-loader ,以在 <head> 內插入 <style> 標籤的方式,讓我剛剛在 js 檔裡引入的 css 內容順利生效」
plugin
除了上述 module 的處理,如果還有一些功能想要達成,還可以透過 webpack 的擴充套件來處理,例如我想要在把我 bundle 完的 js 檔案自動的插入某個 html 檔,讓我少做一些雜事,就可以使用 HtmlWebpackPlugin,官方還有推出許多的 Plugin 以便符合不同使用情境,可以參考這裡。
plugins: [
new HtmlWebpackPlugin({
template: './static/index.html'
}),
],
處理前的 html 模板(static/index.html):
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
處理後的 index.html:
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<body>
<div id="app"></div>
<script type="text/javascript" src="/bundle.js">
</script>
</body>
</html>
可以看到 Webpack 幫我們把需要的 js 跟 css 資源載進來了。
先寫到這裡,在這個部分我只針對設定的屬性功能做說明,還沒有確切說到如何使用 Webpack 進行打包處理,下個章節開始會有更多實作的部分,所以請你消化吸收關於這些設定的方法之後,繼續前進吧!