# Vue.js -- Webpack
## 網頁中引入的靜態資源多了之後有什麼問題???
1. 網頁加載速度慢, 由於 咱們要發起不少的二次請求;
2. 要處理錯綜複雜的依賴關係
## 如何解決上述兩個問題
1. 合併、壓縮、精靈圖、圖片的Base64編碼
2. 可使用以前學過的requireJS、也可使用webpack能夠解決各個包之間的複雜依賴關係;
## 什麼是webpack?
webpack 是前端的一個項目構建工具,它是基於 Node.js 開發出來的一個前端工具;
## 如何完美實現上述的2種解決方案
1. 使用Gulp, 是基於 task 任務的;
2. 使用Webpack, 是基於整個項目進行構建的;
+ 藉助於webpack這個前端自動化構建工具,能夠完美實現資源的合併、打包、壓縮、混淆等諸多功能。
+ 根據官網的圖片介紹webpack打包的過程
+ [webpack官網](http://webpack.github.io/)
## webpack安裝的兩種方式
1. 運行`npm i webpack -g`全局安裝webpack,這樣就能在全局使用webpack的命令
2. 在項目根目錄中運行`npm i webpack --save-dev`安裝到項目依賴中
## 初步使用webpack打包構建列表隔行變色案例
1. 運行`npm init`初始化項目,使用npm管理項目中的依賴包
2. 建立項目基本的目錄結構
3. 使用`cnpm i jquery --save`安裝jquery類庫
4. 建立`main.js`並書寫各行變色的代碼邏輯:
```
// 導入jquery類庫
import $ from 'jquery'
// 設置偶數行背景色,索引從0開始,0是偶數
$('#list li:even').css('backgroundColor','lightblue');
// 設置奇數行背景色
$('#list li:odd').css('backgroundColor','pink');
```
5. 直接在頁面上引用`main.js`會報錯,由於瀏覽器不認識`import`這種高級的JS語法,須要使用webpack進行處理,webpack默認會把這種高級的語法轉換爲低級的瀏覽器能識別的語法;
6. 運行`webpack 入口文件路徑 輸出文件路徑`對`main.js`進行處理:
```
webpack src/js/main.js dist/bundle.js
```
## 使用webpack的配置文件簡化打包時候的命令
1. 在項目根目錄中建立`webpack.config.js`
2. 因爲運行webpack命令的時候,webpack須要指定入口文件和輸出文件的路徑,因此,咱們須要在`webpack.config.js`中配置這兩個路徑:
```
// 導入處理路徑的模塊
var path = require('path');
// 導出一個配置對象,未來webpack在啓動的時候,會默認來查找webpack.config.js,並讀取這個文件中導出的配置對象,來進行打包處理
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
output: { // 配置輸出選項
path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
filename: 'bundle.js' // 配置輸出的文件名
}
}
```
## 實現webpack的實時打包構建
1. 因爲每次從新修改代碼以後,都須要手動運行webpack打包的命令,比較麻煩,因此使用`webpack-dev-server`來實現代碼實時打包編譯,當修改代碼以後,會自動進行打包構建。
2. 運行`cnpm i webpack-dev-server --save-dev`安裝到開發依賴
3. 安裝完成以後,在命令行直接運行`webpack-dev-server`來進行打包,發現報錯,此時須要藉助於`package.json`文件中的指令,來進行運行`webpack-dev-server`命令,在`scripts`節點下新增`"dev": "webpack-dev-server"`指令,發現能夠進行實時打包,可是dist目錄下並無生成`bundle.js`文件,這是由於`webpack-dev-server`將打包好的文件放在了內存中
+ 把`bundle.js`放在內存中的好處是:因爲須要實時打包編譯,因此放在內存中速度會很是快
+ 這個時候訪問webpack-dev-server啓動的`http://localhost:8080/`網站,發現是一個文件夾的面板,須要點擊到src目錄下,才能打開咱們的index首頁,此時引用不到bundle.js文件,須要修改index.html中script的src屬性爲:`<script src="../bundle.js"></script>`
+ 爲了能在訪問`http://localhost:8080/`的時候直接訪問到index首頁,可使用`--contentBase src`指令來修改dev指令,指定啓動的根目錄:
```
"dev": "webpack-dev-server --contentBase src"
```
同時修改index頁面中script的src屬性爲`<script src="bundle.js"></script>`
## 使用`html-webpack-plugin`插件配置啓動頁面
因爲使用`--contentBase`指令的過程比較繁瑣,須要指定啓動的目錄,同時還須要修改index.html中script標籤的src屬性,因此推薦你們使用`html-webpack-plugin`插件配置啓動頁面.
1. 運行`cnpm i html-webpack-plugin --save-dev`安裝到開發依賴
2. 修改`webpack.config.js`配置文件以下:
```
// 導入處理路徑的模塊
var path = require('path');
// 導入自動生成HTMl文件的插件
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
output: { // 配置輸出選項
path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
filename: 'bundle.js' // 配置輸出的文件名
},
plugins:[ // 添加plugins節點配置插件
new htmlWebpackPlugin({
template:path.resolve(__dirname, 'src/index.html'),//模板路徑
filename:'index.html'//自動生成的HTML文件的名稱
})
]
}
```
3. 修改`package.json`中`script`節點中的dev指令以下:
```
"dev": "webpack-dev-server"
```
4. 將index.html中script標籤註釋掉,由於`html-webpack-plugin`插件會自動把bundle.js注入到index.html頁面中!
## 實現自動打開瀏覽器、熱更新和配置瀏覽器的默認端口號
**注意:熱更新在JS中表現的不明顯,能夠從一下子要講到的CSS身上進行介紹說明!**
### 方式1:
+ 修改`package.json`的script節點以下,其中`--open`表示自動打開瀏覽器,`--port 4321`表示打開的端口號爲4321,`--hot`表示啓用瀏覽器熱更新:
```
"dev": "webpack-dev-server --hot --port 4321 --open"
```
### 方式2:
1. 修改`webpack.config.js`文件,新增`devServer`節點以下:
```
devServer:{
hot:true,
open:true,
port:4321
}
```
2. 在頭部引入`webpack`模塊:
```
var webpack = require('webpack');
```
3. 在`plugins`節點下新增:
```
new webpack.HotModuleReplacementPlugin()
```
## 使用webpack打包css文件
1. 運行`cnpm i style-loader css-loader --save-dev`
2. 修改`webpack.config.js`這個配置文件:
```
module: { // 用來配置第三方loader模塊的
rules: [ // 文件的匹配規則
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }//處理css文件的規則
]
}
```
3. 注意:`use`表示使用哪些模塊來處理`test`所匹配到的文件;`use`中相關loader模塊的調用順序是從後向前調用的;
## 使用webpack打包less文件
1. 運行`cnpm i less-loader less -D`
2. 修改`webpack.config.js`這個配置文件:
```
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
```
## 使用webpack打包sass文件
1. 運行`cnpm i sass-loader node-sass --save-dev`
2. 在`webpack.config.js`中添加處理sass文件的loader模塊:
```
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
```
## 使用webpack處理css中的路徑
1. 運行`cnpm i url-loader file-loader --save-dev`
2. 在`webpack.config.js`中添加處理url路徑的loader模塊:
```
{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }
```
3. 能夠經過`limit`指定進行base64編碼的圖片大小;只有小於指定字節(byte)的圖片纔會進行base64編碼:
```
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },
```
## 使用babel處理高級JS語法
1. 運行`cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev`安裝babel的相關loader包
2. 運行`cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev`安裝babel轉換的語法
3. 在`webpack.config.js`中添加相關loader模塊,其中須要注意的是,必定要把`node_modules`文件夾添加到排除項:
```
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
```
4. 在項目根目錄中添加`.babelrc`文件,並修改這個配置文件以下:
```
{
"presets":["es2015", "stage-0"],
"plugins":["transform-runtime"]
}
```
5. **注意:語法插件`babel-preset-es2015`能夠更新爲`babel-preset-env`,它包含了全部的ES相關的語法;**
## 相關文章
[babel-preset-env:你須要的惟一Babel插件](https://segmentfault.com/p/1210000008466178)
[Runtime transform 運行時編譯es6](https://segmentfault.com/a/1190000009065987)