這篇會講
目錄
安裝 Webpack
存於單一專案:npm install --save-dev webpack
全域,存於本機:npm install -g webpack
按照需求擇一安裝即可,等待安裝的同時,來說說什麼是 Webpack。
為什麼要用 Webpack?
- 兼容 CommonJS & AMD & ES6 模組規範
- Bundle 效率高
- JS 擴充語法的編譯自動化 (JSX, Coffee Script, TypeScript…)
- 編譯 sass, less
- 將資源 (css, img, font…) 包入 JS 內
- JS 程式碼分散封裝
- 可用的擴充 plugin 很多
環境配置
webpack.config.js
首先,在 NPM 專案的根目錄建立一個名叫 webpack.config.js 的檔案,並輸入以下內容:
所有設定將打在 module.exports 中輸出。
entry
說明:Webpack 會將每個 entry 文件編譯打包。當然,其中 require 的文件 (js, css, img) 會一起被打包進來。
格式:字串或字串陣列 (一個檔案對應一個字串,為 JS 檔)
EX:
output
說明:打包後生成的檔案路徑。
格式:物件
屬性:
- path
說明:打包生成的目錄
格式:字串 - filename
說明:生成的 js 檔名
格式:字串 - publicPath
說明:CSS 打包時修改的引用檔案路徑
格式:字串
EX:
resolve
說明:require 相關設置。
格式:物件
屬性:
- root
說明:require 的根目錄 (模組的引用不受影響)
格式:字串或字串陣列 - extensions
說明:require 可省略的副檔名
格式:字串或字串陣列 - ailas
說明:屬性對應的值會形成 ailas 對應。ailas: { a:'b' }
=>require('a')
同於require('b')
格式:物件
EX:
module
格式:物件
屬性:
- loaders
說明:entry 及 require 到的檔都會依此轉換成 JS,anything to JS
格式:物件陣列(由下往上依序轉換)
屬性:- test
說明:指定目標檔案的檔名
格式:正則表達式 - loader
說明:指定使用的 loader
格式:字串或字串陣列 (loader 語法)(由右往左依序轉換) - include
說明:白名單,只處理的目錄
格式:字串或字串陣列 - exclude
說明:黑名單,忽略、不處理的目錄
格式:字串或字串陣列
- test
EX:
devtool
說明:設置 eval 或 SourceMap 屬性,debug 用
格式:字串
種類:
'eval'
'source-map'
'hidden-source-map'
'inline-source-map'
'eval-source-map'
'cheap-source-map'
'cheap-module-source-map'
可以混著用,個別的介紹請看這裡,我懶的打字
EX:
plugins
說明:插件配置
格式:物件或物件陣列,通常以 new webpack.XXXPlugin()
產生物件
EX:
嘛,大致上是這樣,如果對 Webpack 配置有興趣可看這裡。
推薦配置
loaders
懶人包,全裝下去 94 狂
npm install --save-dev babel-loader style-loader css-loader sass-loader less-loader url-loader
babel-loader
功能:自動編譯 JSX 或 JS 檔 (require 可載入 JSX 了)
安裝:npm install --save-dev babel-loader
示範:12345{test: /\.(js|jsx)$/,loader: 'babel',exclude: /node_modules/}style-loader
功能:自動將 CSS 檔的內容插入到頁面有 require CSS 的地方,並用 style 包住 (require 可載入 CSS 了)
安裝:npm install --save-dev style-loader
示範:見下面 css-loader 的示範css-loader
功能:自動處理 CSS 內的url
和@import
的路徑轉換,可以傳入 sourceMap 參數以便 debug
安裝:npm install --save-dev css-loader
示範:1234{test: /\.css$/,loader: 'style!css?sourceMap'}sass-loader
功能:自動編譯 sass 檔成 CSS (require 可載入 sass 了),可以傳入 sourceMap 參數以便 debug
安裝:npm install --save-dev sass-loader
示範:1234{test: /\.scss$/,loader: 'style!css?sourceMap!sass?sourceMap'}less-loader
功能:自動編譯 less 檔成 CSS (require 可載入 less 了),可以傳入 sourceMap 參數以便 debug
安裝:npm install --save-dev less-loader
示範:1234{test: /\.less$/,loader: 'style!css?sourceMap!less?sourceMap'}url-loader
功能:自動將圖片轉成 Data URL
安裝:npm install --save-dev url-loader
示範:1234{test: /\.(jpe?g|JPE?G|png|PNG|gif|GIF|svg|SVG|woff|woff2|eot|ttf)(\?v=\d+\.\d+\.\d+)?$/,loader: 'url?limit=1024&name=[sha512:hash:base64:7].[ext]'}
plugins
HotModuleReplacementPlugin
功能:Hot Module Replacement,詳細會在底下提到。
示範:1new webpack.HotModuleReplacementPlugin()ProvidePlugin
功能:幫你 require,new webpack.ProvidePlugin({a: 'b'})
=> 程式碼有找到 a 字串就載入 b module,就不用手動 require
示範:12345new webpack.ProvidePlugin({$: 'jquery',React: 'react',ReactDOM:'react-dom'})
兼容 IE
說到 IE,一堆工程師的頭都痛了。
但 eventsource-polyfill 可以讓 Webpack 兼容 IE!
修改 webpack.config.js 的 entry:
webpack.config.js 配置範例
|
|
Webpack + Express
什麼是 Express?
Express 是最小又靈活的 Node.js Web 應用程式架構,為 Web 與行動式應用程式提供一組健全的特性。
– 仁自 Express 官網
簡而言之,Express 是目前使用上最穩定且最廣泛的輕量級開發框架,而且是 Node.js 官方唯一推薦的框架。
因為 webpack 本身只是 bundle 工具,沒有 server 功能,需要一個 server。
然而,要將 webpack 跟 Express 結合,需要使用 webpack-dev-middleware 或 webpack-dev-server。不然只能同時開兩個 terminal,一個跑 webpack,一個跑 Express server
不想使用 Express 的話可以跳過。
什麼是 webpack-dev-middleware & webpack-dev-server?
webpack-dev-middleware 可讓 webpack 被 Express app 或是其他可使用 middleware 的框架所使用。
webpack-dev-server 本身就是小型的 Express server,簡單來說整合了 Express 和 webpack-dev-middleware。
webpack-dev-server 方便架設,但彈性較少,無法跟現有的 Express app 結合,且只能用 Express。
所以我採用了 Express + webpack-dev-middleware。想用 webpack-dev-server 的話可以參考下這裡。
安裝 Express & webpack-dev-middleware
npm install --save express
npm install --save-dev webpack-dev-middleware
使用配置
裝好之後要用 Express 寫個 server,套用 webpack-dev-middleware。
首先,在專案根目錄建一個 server.js (檔名隨意)
Hot Module Replacement
這是神馬?
中文稱為熱置換,意思是你修改任意一個檔案並儲存後就會自行編譯打包 (webpack –watch),然後更新瀏覽器畫面 (Browsersync),而且只會 reload 更新的一部份而不會全部 reload,全部 reload 效率低,且會導致狀態的遺失。
webpack –watch + Browsersync 還是無法避免全部 reload,無法做到 HMR,所以,我們得用 react-hot-loader 或 webpack-hot-middleware。
react-hot-loader 是 webpack-dev-server 的衍生套件,webpack-hot-middleware 則是 webpack-dev-middleware 的衍生套件。請依環境選裝。
安裝
二選一
npm install --save-dev react-hot-loader
npm install --save-dev webpack-hot-middleware
配置
react-hot-loader
修改 webpack.config.js 的 entry:123456entry: [// 一定要在前面'webpack-dev-server/client?http://0.0.0.0:3000','webpack/hot/only-dev-server','./main.jsx',],webpack-hot-middleware
修改 webpack.config.js 的 entry:12345entry: [// 一定要在前面'webpack-hot-middleware/client','./main.jsx',],
並在 server.js 中載入 webpack-dev-middleware 的後面再加一段:
無論用哪個都別忘了在 webpack.config.dev 加 new webpack.HotModuleReplacementPlugin()
才有 HMR 的效果喔~
牛刀小試
Webpack 搞了這麼久,趕快體驗一下他帶來的方便吧!
不過接下來至少還要改兩個檔才能開始測試 webpack。
這邊接序第二篇的環境建置,忘記的可以回去看一下。
index.html
這個檔必須是你用的 server 能讀取到的檔案
(若你是用 Express + webpack-dev-middleware 並實作了 server.js,那應該可在 server.js 內看到 sendFile 的對象,像我剛剛是在 server.js 中打 index.html)
有沒有覺得 compiled.js
這路徑很熟悉?
沒錯,它就是 webpack.config.js 中 output 設定的 bundle 輸出路徑。也就是說,載入這個 js 就好啦!
第七行 div 是讓 JSX 插入用的,id 可以自取。
main.jsx
有沒有覺得 main.jsx
這路徑也很熟悉?
沒錯,它就是 webpack.config.js 中 entry 設定的 bundle 進入點。
可以開始寫 JSX 囉。
以下只是範例:
document.getElementById(‘root’) 的 id 必須和 index.html 中 div 的 id 一致。
webpack 建置
如果你是用 Express + webpack-dev-middleware 並實作了 server.js:
node server.js
如果是用 webpack-dev-server:
webpack-dev-server
如果都沒用,只用 webpack:
webpack --watch
PS. 至少要找一個 server 並啟動它喔 ~
然後只要讓瀏覽器連到 index.html 就可以看到 JSX 自動編譯,即時變更網頁內容了!
總結
環境配置懶人包
npm install --save-dev webpack babel-loader css-loader style-loader sass-loader less-loader url-loader express webpack-dev-middleware webpack-hot-middleware
npm install --save-dev babel-loader css-loader style-loader sass-loader less-loader url-loader
loadersnpm install --save express
Expressnpm install --save-dev webpack-dev-middleware
webpack-dev-middlewarenpm install --save-dev webpack-hot-middleware
HMR - webpack-dev-middlewarenpm install --save-dev react-hot-loader
HMR - webpack-dev-server
Webpack 篇就這樣告一段落囉,下篇 講的是 React Router 以及 Redux 框架。如果有興趣可以繼續收看~
這篇會不定期更新,如果有打錯或有任何疑問都歡迎留言告知喔~
我們下篇再見~