webpack高階教程
1. Webpack
1.1. 網站中常見靜態資源有哪些
-
圖片
- jpg,png,gif,bmp
-
字型
- woff,woff2,eot,svg,ttf
-
JS
- js,coffee
-
css
- css,less,sass
-
模板檔案
- .vue, .jade
1.2. 大量靜態資原始檔引發的問題
- 發起大量的二次請求
- 需要維護元件之間的依賴關係
1.3. 以上問題的解決方案
-
發起大量的二次請求
- 解決方案:
- 圖片:精靈圖,壓縮圖片體積,base64編碼(能把圖轉換為字串)
- JS,CSS:程式碼壓縮,程式碼合併
-
需要維護元件之間的依賴關係:之前是程式設計師自己維護這種依賴關係的;【使用一些工具幫我們解決這種依賴關係】
1.4. webpack解決上述的問題
webpack的作用:合併檔案,壓縮檔案,處理檔案的依賴關係
1.5. 列表各行變色的案例
1.5.1. 安裝webpack
- 全域性安裝:執行
npm i webpack -g
- 專案安裝:
npm i webpack --save-dev
--save和--save-dev的區別
:--save-dev
的全稱:'save develop'- 拿jquery和webpack進行比較
1.6. 需求:
- 藉助於Jquery
- 奇數行一個顏色
-
偶數行一個顏色
-
使用
npm init
初始化專案,使用npm來管理專案中的包 - 新建HTML結構和main.js的邏輯程式碼
- 安裝webpack
cnpm i webpack --save-dev
- 執行
webpack src/js/main.js dist/bundle.js
進行打包構建,語法是:webpack 入口檔案 輸出檔案
1.7. webpack構建的過程
- 判斷使用者是否傳遞了入口和出口兩個路徑,如果沒有傳遞,那麼就從專案根目錄中查詢
webpack.config.js
這個配置檔案 - 如果找到了這個配置檔案,則根據配置檔案中匯出的配置物件,來進行打包構建!
-
注意:在配置檔案中不能使用ES6的語法!!!
// 1. 引入Path模組處理路徑問題 var path = require('path'); module.exports = { entry: path.resolve(__dirname, 'src/js/main.js'), // 配置打包的入口檔案 output:{ // 指定輸出檔案 path:path.resolve(__dirname, 'dist'), // 輸出檔案的路徑 filename:'bundle.js' // 輸出檔案的名稱 } }
1.8. 使用webpack-dev-server來實現監視程式碼實時打包,自動重新整理瀏覽器
- 執行
cnpm i webpack-dev-server --save-dev
安裝包 - 由於命令列不是別
webpck-dev-server
這個命令,所以需要在package.json
中配置一下命令 package.json
中,script節點下的命令,可以通過npm run 命令名稱
的形式去執行- 注意:webpack-dev-server打包好的bundle.js檔案,並沒有存放到實際的硬碟上,而是儲存到了記憶體中!!!放到記憶體中最主要的原因是快,非常快,太TM快了!
- 如何從記憶體中獲取打包好的bundle.js檔案呢???
- 修改
webpack-dev-server
託管的根目錄,通過--contentBase
指定託管的根目錄:"dev": "webpack-dev-server --contentBase src"
- 自動開啟瀏覽器和配置埠號,
--open
自動開啟瀏覽器,--port 4321
指定埠號:"dev": "webpack-dev-server --contentBase src --open --port 4321"
- 在配置檔案中設定自動開啟瀏覽器:
devServer:{ // 這裡的配置項會交給webpack-dev-server去讀取 //--contentBase src --open --port 4321 contentBase:path.resolve(__dirname, 'src'), // 配置啟動路徑 open:true, // 自動開啟瀏覽器 port:4321 // 指定埠號 }
1.9. 在記憶體中生成HTML頁面
自動在記憶體中根據指定的模板,生成index頁面,同時自動注入打包好的bundle.js檔案
- 執行
cnpm i html-webpack-plugin --save-dev
- 匯入模組:
// 2. 引用自動生成HTML頁面的模組 var htmlWebpackPlugin = require('html-webpack-plugin');
- 在配置檔案中新增
plugins
節點如下:plugins:[ // 外掛陣列 new htmlWebpackPlugin({ // 建立一個htmlWebpackPlugin外掛 template:path.resolve(__dirname, 'src/index.html'), // 指定模板頁面 filename:'index.html' // 指定在記憶體中生成的頁面的名稱 }) ]
1.10. 使用Webpack打包CSS檔案
- 執行
cnpm i style-loader css-loader --save-dev
- 在配置檔案中新增
module
節點如下:module:{ // 配置相關的loader模組 rules:[ // 配置相關檔案的匹配規則 {test:/\.css$/, use:['style-loader', 'css-loader']}, // 處理CSS檔案的loader配置 ] }
1.11. 使用webpack打包sass檔案
- 執行
cnpm i sass-loader node-sass --save-dev
,sass-loader依賴於node-sass - 新增rules規則如下:
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }// 處理sass檔案的loader配置
1.12. 實現熱更新
- 修改
package.json
中的命令,新增--hot
指令即可:"dev": "webpack-dev-server --hot"
- 第二種實現熱更新的方式:
- 第一種方式:修改配置檔案的devServer節點:
devServer: { // 這裡的配置項會交給webpack-dev-server去讀取 //--contentBase src --open --port 4321 contentBase: path.resolve(__dirname, 'src'), // 配置啟動路徑 open: true, // 自動開啟瀏覽器 port: 4321, // 指定埠號 hot:true // 啟用熱更新 },
- 修改plugins節點:
plugins: [ // 外掛陣列 new htmlWebpackPlugin({ // 建立一個htmlWebpackPlugin外掛 template: path.resolve(__dirname, 'src/index.html'), // 指定模板頁面 filename: 'index.html' // 指定在記憶體中生成的頁面的名稱 }), new webpack.HotModuleReplacementPlugin() // 使用webpack下面的.HotModuleReplacementPlugin()實現熱更新 ]
- 第一種方式:修改配置檔案的devServer節點:
1.13. 實現處理圖片路徑
- 執行
cnpm i url-loader file-loader --save-dev
- 新增loader配置項:
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader' } // 處理URL路徑的loader
- url-loader預設能幫我們把圖片轉為base64編碼;
- 預設URL中的圖片路徑是經過雜湊求值的,目的是為了防止兩張一模一樣的圖片出現;
limit
引數的作用:給定一個圖片的大小,當圖片超過給定值的時候:就證明你是一張大圖片,不用進行base64編碼;否則:是小圖片,需要進行base64編碼;- 計算機中儲存的單位:Bit,Byte,KB,MB,GB,TB
limit=1000
中單位是Byte,只要當圖片小於給定值的時候,才會進行base64的編碼!
1.14. ES6中的class關鍵字
- 靜態屬性和例項屬性的區別:
- 靜態屬性:直接通過類名就可以訪問到,不需要建立類的例項;
- 例項屬性:必須先通過new關鍵字,建立一個類的例項,然後,在這個例項上通過點號訪問的屬性,叫做例項屬性;
- 由於webpack不識別靜態屬性static這個關鍵字,所以,需要藉助於
babel-loader
來處理這個高階ES6語法!
1.15. 在webpack中配置babel-loader
- 執行
npm i cnpm -g
- 執行
cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev
- 執行
cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev
- 新增相關loader模組:
{test:/\.js$/, use:'babel-loader', exclude:/node_modules/} // 最重要的一點:要把node_modules資料夾,新增到排除項,通過exclude排除這個資料夾【注意:一定要排除否則會報錯!!!】
- 在專案根目錄中新建
.babelrc
配置檔案,將來babel-loader執行的時候,會檢查這個配置檔案,並讀取相關的語法和外掛配置:{ "presets":["es2015", "stage-0"], "plugins":["transform-runtime"] }
1.16. Webpack釋出策略
- 開發期間的配置:實時重新整理瀏覽器,實時編譯,熱更新,index.html,bundle.js;
- 在開發期間:測試檔案、測試資料、測試相關的工具(好處:方便快速開發除錯)
- 部署期間:剔除(測試檔案、測試資料、測試相關的工具)這些檔案,目的:減少部署檔案的體積;方便使用者安裝;
- 在部署時候,我們也需要一個webpack的配置檔案,只是這個配置檔案中,刪除了開發時候的一些工具;
- 在專案中新建
webpack.publish.config.js
// 刪除devServer選項: devServer: { // 這裡的配置項會交給webpack-dev-server去讀取 //--contentBase src --open --port 4321 contentBase: path.resolve(__dirname, 'src'), // 配置啟動路徑 open: true, // 自動開啟瀏覽器 port: 4321, // 指定埠號 hot: true // 啟用熱更新 },
// 刪除熱更新 new webpack.HotModuleReplacementPlugin() // 使用webpack下面的.HotModuleReplacementPlugin()實現熱更新
// 改造URL-loader { test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=43959&name=images/imgs-[hash:7].[ext]' }, // 處理URL路徑的loader
1.17. 每次重新發布的時候,自動刪除dist目錄
- 執行
cnpm i clean-webpack-plugin
- 在部署的配置檔案中匯入這個外掛:
var cleanWebpackPlugin = require('clean-webpack-plugin');
- 在plugins節點下,建立這個麼一個外掛,把需要刪除的目錄通過陣列傳遞進去:
new cleanWebpackPlugin(['dist']) // 建立一個刪除資料夾的外掛,把dist目錄傳遞進去
1.18. 分離第三方包
目的:將公共的第三方包,抽離為一個單獨的包檔案,這樣防止重複打包!
- 改造entry:
entry: { app:path.resolve(__dirname, 'src/js/main.js'), // 自己的程式碼入口檔案 vendors:['jquery'] // 第三方包的入口 }, // 配置打包的入口檔案
- 改造plugins:
new webpack.optimize.CommonsChunkPlugin({ name:'vendors', // 指定抽取公共模組的名稱 filename:'vendors.js' // 指定抽取出來的檔案真實名稱 })
1.19. 壓縮JS程式碼
在Plugins下面新增:
new webpack.optimize.UglifyJsPlugin({ // 優化壓縮JS
compress:{
warnings:false // 移除警告
}
}),
new webpack.DefinePlugin({ // 設定為產品上線環境,進一步壓縮JS程式碼
'process.env':{
'NODE_ENV':JSON.stringify('production')
}
})
1.20. 抽取CSS檔案到單獨的樣式表
- 執行
cnpm install --save-dev extract-text-webpack-plugin
- 引入外掛:
var ExtractTextPlugin = require("extract-text-webpack-plugin");
- 修改sass和css的loader如下:
{ test: /\.css$/, use: ExtractTextPlugin.extract({// 使用外掛來處理CSS樣式 fallback: "style-loader", use: "css-loader" }) }, // 處理CSS檔案的loader配置 { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'sass-loader'] }) },// 處理sass檔案的loader配置
- 在plugins下面新增新外掛:
new ExtractTextPlugin("styles.css") // 抽離CSS樣式名稱
1.21. 壓縮抽取出來的CSS 樣式表
- 執行
cnpm i optimize-css-assets-webpack-plugin --save-dev
安裝外掛 - 匯入外掛:
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
- 在plugins節點下new上面匯入的外掛即可:
new OptimizeCssAssetsPlugin() // 建立一個壓縮CSS檔案的外掛
1.22. 壓縮HTML頁面
- 修改plugins節點下面的htmlWebpackPlugin這個外掛,新增
minify
屬性;new htmlWebpackPlugin({ // 建立一個htmlWebpackPlugin外掛 template: path.resolve(__dirname, 'src/index.html'), // 指定模板頁面 filename: 'index.html', // 指定在記憶體中生成的頁面的名稱 minify:{ // 壓縮優化HTML頁面 collapseWhitespace:true, // 合併空白字元 removeComments:true, // 移除註釋 removeAttributeQuotes:true // 移除屬性上的引號 } })
- 詳細的配置可以參考html-minifier https://github.com/kangax/html-minifier#options-quick-reference
相關文章
- 值得了解的webpack高階技能Web
- MySQL 高階特性篇教程MySql
- MarkDown 的常用高階教程
- 高階Web開發教程Web
- Pandas高階教程之:window操作
- Pandas高階教程之:GroupBy用法
- ZeroMQ 教程 002 : 高階技巧MQ
- asp.net高階教程 (轉)ASP.NET
- Angular 17+ 高階教程 – AnimationAngular
- Webpack揭祕——走向高階前端的必經之路Web前端
- web前端高階webpack - 初識webpack 的安裝執行及核心概念Web前端
- PowerJob高階特效-容器部署完整教程特效
- Pandas高階教程之:統計方法
- Kotlin教程(八)高階函式Kotlin函式
- Encoding/Decoding 高階教程 [生肉]Encoding
- asp.net高階教程(續) (轉)ASP.NET
- Usenet下載教程(高階篇)SENet
- Angular Material 17+ 高階教程 – ObserversAngularServer
- Angular Material 17+ 高階教程 – OverlayAngular
- Angular 17+ 高階教程 – LibraryAngular
- Python Django進階教程(三)(模型的高階用法)PythonDjango模型
- 一看就懂之webpack高階配置與優化Web優化
- hyperf 教程之 hyperf-auth 高階用法
- Java高階教程 - 建立和銷燬物件Java物件
- Pandas高階教程之:Dataframe的合併
- Pandas高階教程之:自定義選項
- Pandas高階教程之:時間處理
- Angular Material 17+ 高階教程 – Material RippleAngular
- Angular 17+ 高階教程 – 學以致用Angular
- 自媒體教程(含高階教程+教材+自媒體工具)
- webpack教程(一)Web
- webpack教程(二)Web
- 尚矽谷《MySQL高階特性篇》教程釋出MySql
- Pandas高階教程之:category資料型別Go資料型別
- Pandas高階教程之:處理text資料
- Pandas高階教程之:處理缺失資料
- Pandas高階教程之:稀疏資料結構資料結構
- Pandas高階教程之:plot畫圖詳解