# [Webpack] 安裝說明
###### tags: `Webpack`

### Webpack是那位?
* webpack幫我們做的事情很簡單,就是幫我們編譯我們的Preprocess成瀏覽器看得懂的內容然後打包成一包的完成檔案然後拿去server上傳上去。
* webpack 把「任何資源」都視成一個模組。圖片是模組,所以你可以 import Image from './assets/banner.png';CSS 是模組,你可以 import styles from'style.css',只要是任何資源都可以 import 進來使用。
* 使用模組化,避免載入順序引發錯誤的訊息
* 如使用框架開發,如Vue、react,仍建議使用原框架的CLI
* 相依性高才建議使用webpack模組化,例如在開發SPA就很適用,則js都是獨立時不太建議使用。
### 專案結構
一般我們的專案會有兩個很重要的資料夾src與dist
* src : 專門放我們Preprocess的檔案,包括es6、pug、sass、vue、jsx等檔案,這個資料夾不會丟上去server部署。
* dist : 經過 webpack 編譯打包後,產生出瀏覽器看得懂的html、css、js,要部署也是這個資料夾去部署。
## 安裝 webpack 相關套件
#### 1. 使用npm來安裝webpack,完成後便會自動生成package.json檔案
```
npm init //package.json (node.js 相關套件)
npm install webpack webpack-cli --save //install webpack
```
---
#### 2. 新增 webpack.config.js 設定檔,並匯入進入點
* 連結:https://www.webpackjs.com/concepts/
```
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js', //進入點
output: {
path: path.resolve(__dirname, 'dist'), //dist資料夾
filename: 'my-first-webpack.bundle.js' //輸出檔名
}
};
```
指向自定義的進入點檔案,及output的檔案名稱
```
const path = require('path'); // node.js套件:指向路徑
modele.exports = {
entry: // 命名:src/main.js
output: // 命名:dist/main.bundle.js
}
```
---
#### 3. 在package.json新增build指令
當終端機執行npm build便會執行內容
```
//npm指令
"svripts":{
"build": "webpack" //執行webpack: npm run build(development or production 環境設定)
}
```
#### 4. 執行npm build後便會生成main.bundle.js檔案
---
#### 5. 載入需要轉譯的程式(Scss為案例)
載入css/sass loader等套件並連結main.js便可完成打包串接
```
npm install --save css-loader //install css-loader
npm install --save style-loader //install style-loader
```
搜尋需導入的語言並查詢css loader,再依照指示安裝至webpack.config.js (也就是進入點與打包後的位置,還有導入需轉譯的語言都是在webpack.config.js執行)
```
modele.exports = {
module: { //new module 功能
rules: [ //規則
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'], //install style-loader
},
],
},
}
```
新增src/all.css
```
body{
background-color: red;
}
```
導入main.js,即可套上css色系
```
import './all.css';
```
---
#### 6. 設定watch即時監控 or 選擇webserver
### 1. watch即時監控
###
- 優點:
- 使用watch在每次修改後,立刻同步替換程式碼
- 即時監控 main.js 與其關聯檔案,瀏覽器即時刷新
- 與 main.bundle.js 無關連(刪掉無影響)
```
//Script裡加入了3個指令
"scripts": {
"watch": "webpack --mode development --watch",
"start": "webpack --mode development",
"build": "webpack --mode production"
},
```
* watch : 執行編譯然後不中斷,設定成 development 版本。
* start : 執行一次性編譯(無壓縮),設定成 development 版本。
* build : 執行一次性編譯,設定成 production 版本,執行壓縮及其他動作,編譯速度較慢。
### 2. 導入web server
###
* npm套件:https://www.npmjs.com/package/webpack-dev-server
* 設定宣告檔
```
"start": "webpack-dev-server --open",
```
* webpack.config.js檔裡,輸入下方語法開啟伺服器本地端的 port:9000
```
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
},
```
執行步驟:輸入npm run start就會彈跳視窗,兼具監視的功能,六角推薦此為開發好物。
---
### @統整
**大綱**:原理就是將所有的語言套件,經由build實現包含壓縮、轉成網頁三語言,然後吐給伺服器。
**步驟**:main.js先搜集好需要轉換三語言的套件,然後在bundle輸出轉換完成版,外部的html再將bundle的內容導入,因而完整看到畫面
**套件下載**:npm需要的套件,文件內會提供將rule規則導入到webpack.config.js的內容,將其rule導入後完成
**dist區域**
* bundle.js 打包後的出口,壓縮轉換後的檔案位置
**src區域**
* main.js 將所有A、B、C多個軟件 import 到此檔案。
* index.html 網頁內容,要寫上script連結dist裡的bundle檔案
## @ 載入 Vue Router
邏輯:
* Html的id=#app位置會與 index.js串連
* 而index.js裡會將App.vue載入
* App.vue內容有router-view是會自動呼叫到router.js裡去載入多元件
範例:
* Component1: 名:hello
* Component2: 名:xxxx
* 主父層App.vue:名:index.vue,放置router-view位置
* Router檔案:導入元件內容
* Index.js(webpack入口): 導入主頁面A,及套件宣告
結論:
從上述所言,所有套件需要進行npm下載、在webpack設定進入點,出口點,並引用套件即可,而vue router難度較複雜,上述步驟完成後,需新增父層 App.vue(最外層),以及 router.js (需路由連結的子元件頁面)。
1. HTML 內容引入打包後的 bundle.js
1. webpack 內容將index.js 打包到 bundle.js
1. index.js 內容有 App.vue
1. App.vue 內容有 router-view
1. router.js 內容有子元件,對應 App.vue 裡的 router-view
---
#### 參考資料:
* [什麼是Webpack? 能吃嗎?](https://medium.com/i-am-mike/%E4%BB%80%E9%BA%BC%E6%98%AFwebpack-%E4%BD%A0%E9%9C%80%E8%A6%81webpack%E5%97%8E-2d8f9658241d)
* [認識 Webpack 一點都不難](https://paper.dropbox.com/doc/Webpack-Gulp-fX7pK28W0iXWxAqv9Lfq8)
* [webpack 新手教學之淺談模組化與 snowpack
](https://blog.huli.tw/2020/01/21/webpack-newbie-tutorial/)
* [webpack監聽](https://medium.com/i-am-mike/webpack%E6%95%99%E5%AD%B8-%E5%9B%9B-javascript-%E8%88%87-babel-1d7acd911e63)
* [webpack官方網站](https://webpack.js.org/configuration/dev-server/#root)