--- tags: webpack, disqus: hackmd --- # webpack(1) 基本設定筆記 ## 環境預設為已安裝好npm , 還沒安裝的可以去看[NVM (Node Version Manager) 在mac上的安裝](https://hackmd.io/GAlzyOv1T3qnC5ZALDXq1g) [這裡先附上mac terminal常用指令](http://aweiho2015.pixnet.net/blog/post/15628178-macbook%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4) [webpack中文文檔(簡體)](https://webpack.docschina.org/concepts/) [學習Webpack 4 2019](https://github.com/wilkersoh/Tutorial-Webpack4-2019?fbclid=IwAR3B0hJaxwiei5n4o9laRAWICwyYJ0y4oC8LJGFvh7kvOB5nYiOtvmqc16M) [react一步一腳印(裡面第二章開始也有提到webpack)](https://ithelp.ithome.com.tw/articles/10200195) --- ## 第一步 安裝webpack 首先在專案資料夾底下,打開你的terminal( windows的就是『命令提示字元』 ) 如果你使用vscode 那就按下 control + ~ (windows = ctrl + ~) 接著確認你現在路徑在你的專案資料夾 如果沒有 可以用 cd 進到你的目標路徑 然後輸入 ``` HTML= npm init ``` 接著他就會問你一些問題 基本上可以先都按enter 先使用默認的配置 ![](https://i.imgur.com/oeQFsoh.png) ok後就會看到資料夾裡多了這隻 **package.json**</br></br> **package.json是什麼** 基本上就是可以在這裡寫上 名稱、版本、描述、關鍵字、相依套件這些的 接著可以再輸入(這裡目前我是先按照課程教我的打 之後等認識的多點再來修改) ``` HTML= npm install webpack webpack-cli --save-dev ``` 那其實我是同時安裝了 webpack 跟 webpack-cli ![](https://i.imgur.com/kLev30i.png) ok後就會看到資料夾裡多了這 **package-lock.json**跟**node_modules** **package-lock.json** 紀錄目前的 **依賴(dependency)** 各版本的詳細資訊 **node_modules** 則是目前我裝了webpack後所會用到的dependency或者說是套件 --- ## 第二步 webpack.config.js 接下來我們要建立一個設定檔 ![](https://i.imgur.com/kHRviMR.png) 上面這張圖是從webpack中文文檔(簡體)截圖來的 他的意思大致為就算沒有webpack.config.js這隻 webpack也是可以正常運作 , 只要把你的檔案放在一個資料夾叫src的裡面 這樣他也是可以幫你打包並且輸出到dist資料夾裡面 不過如果你想要做更多的設置 , 那就需要建立一支webpack.config.js ### *起手式* ``` HTML= module.exports = { entry: './index.js', output: { filename: 'index-bundle.js', } } ``` entry就是入口點 這裡要填上檔案的路徑 output的filname是輸出的檔案名稱 簡單說就是在執行後產出的檔案名稱會是 index-bundle.js #### 先試跑看看 建立一個index.js , 並且在裡面打上一段console.log('hello world') 入口點的檔案有了 , 接著呢?? 打開你的package.json , 然後把scripts底下改成start: 'webpack' ![](https://i.imgur.com/gdnk0fX.png) 然後打開你的terminal 輸入 ``` HTML= npm run start ``` ![](https://i.imgur.com/yodFLTX.png) 可以看到專案資料夾下面多了一個 dist的資料夾 裡面就有一隻index-bundle.js 打開並且拉到最後就可以看到你剛剛在index.js裡打的console.log('hello world') --- #### 進階一點 ``` HTML= var path = require('path'); module.exports = { context: path.resolve(__dirname, './src'), entry: './index.js', output: { path: path.resolve(__dirname, './dist'), filename: 'index-bundle.js', } } ``` **path.resolve()** 可以將相對路徑或路徑片段解析成絕對路徑 ``` HTML= path.resolve(目前路徑, 目標路徑) path.resolve(__dirname, 目標路徑) ``` __dirname 在node.js裡面代表的一個特殊的變數 , 指的是當前執行文件所在目錄的完整目錄位置 指定輸出路徑位置 path: path.resolve(__dirname, './dist') 最後記得要有一個src的資料夾 裡面要有一隻index.js的檔案 不然一執行下去會噴錯喔 --- ## 第三步 npm scripts 在打包的時候有分兩種 "development"跟"production" 可以注意到每次在跑打包的時候 , terminal會出現黃黃的警告 ![](https://i.imgur.com/EYgbhFi.png) 基本上就是告訴你 你沒有設置mode "development"開發時候使用 "production"要上線發佈使用 ##### 那怎麼設置?? 打開你的package.json 然後把scripts改成下面這樣 ``` HTML= "scripts": { "start": "webpack --mode development", "deploy": "webpack --mode production" }, ``` 這樣只要在terminal 輸入npm run start他就會跑開發模式 輸入npm run deploy他就會跑產品模式 當然你也可以把start跟deploy改成其他的名字 那你要run的時候就要改成相對應的名字 ##### development跟production差異? development不會做一些優化跟壓縮的動作 所以在包的時候會比較快 production就是到要上線要發佈的時候才使用 可以去看看使用npm run start跟npm run deploy所產出的index-bundle.js有什麼不一樣 --- ## 第四步 NODE_ENV環境變數 for MAC ``` HTML= "scripts": { "start": "NODE_ENV=development webpack --mode development", "deploy": "NODE_ENV=production webpack --mode production" }, ``` for windows ``` HTML= "scripts": { "start": "cross-env NODE_ENV=development webpack --mode development", "deploy": "cross-env NODE_ENV=production webpack --mode production" }, ``` 為什麼windows的比MAC多了cross-env?? 因為windows本身沒有NODE_ENV這個變數 所以要格外安裝一個cross-env套件 ``` HTML= npm install cross-env --save-dev ``` _ ![](https://i.imgur.com/BrK2llC.png) 有了NODE_NEV後 在打包的時候就會看到terminal這裡會顯示他現在是什麼版本</br></br> 這行指令主要是在webpack讀取NODE_ENV ``` HTML= process.env.NODE_ENV ``` --- ## 第五步 watch 知道了要打包的時候只要輸入npm run start就可以 可是如果我今天在寫一個專案的時候通常都會一直更改東西吧 難道每次都要在terminal輸入npm run start? #### 可以用watch ``` HTML= "scripts": { "watch": "NODE_ENV=development webpack --mode development --watch", "start": "NODE_ENV=development webpack --mode development", "deploy": "NODE_ENV=production webpack --mode production" }, ``` 可以看到除了start跟depoly現在還多了一個watch 這個watch的功能就是能夠不斷的監聽只要你的index.js變動完一儲存 他就會自動幫你編譯 , 這樣就不用一直在那npm run start #### 怎麼停止watch? 在terminal按下 control + c 就可以了 --- ## 第六步 多個entry #### 今天我有複數檔案需要打包怎麼辦?? ``` HTML= module.exports = { context: path.resolve(__dirname, './src'), entry: { index: './index.js', about: './about.js' }, output: { path: path.resolve(__dirname, './dist'), filename: '[name].js', } } ``` 可以把我們的entry改寫成上面這樣 #### filename怎麼變得不一樣了 原因是剛剛我們是直接指定他轉出來的檔案名稱叫index-bundle.js 但是現在的檔案變多了所以寫成[name].js 這樣子打包後在src裡面就會有about.js跟index.js #### 那麼[name].js的name到底是什麼?? 就是entry這個物件底下的屬性名稱 如果我改成 app: './index.js' 這樣去編譯出來的不會是index.js 而會是app.js