前言
你是否也是只會運用框架中集成好的Webpack配置呢?你明白每一項的意義么?你懂多少Webpack的個性化配置項呢?本篇文章為你講解Webpack中的各種配置項參數及作用!
文章目錄
- 了解Webpack相關
- 開啟項目
- 編譯打包應用
- 使用webpack配置文件
- 打包less資源
- js語法檢查
- js語法轉換
- js兼容性處理
- 打包樣式文件中的圖片資源
- 打包html文件
- 打包html中圖片資源
- 打包其他資源
- 自動編譯打包運行
- 熱模替換功能
- devtool
- 準備生產環境
- 清除打包文件目錄
- 提取css成單獨文件
- 添加css兼容
- 壓縮css
- 壓縮html
了解Webpack相關
什么是webpack
Webpack是一個模塊打包器(bundler)。
在Webpack看來, 前端的所有資源文件(js/json/css/img/less/…)都會作為模塊處理
它將根據模塊的依賴關系進行靜態分析,生成對應的靜態資源
五個核心概念
Entry:入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。
Output:output 屬性告訴 webpack 在哪里輸出它所創建的 bundles,以及如何命名這些文件,默認值為 ./dist。
Loader:loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript)。
Plugins:插件則可以用于執行范圍更廣的任務。插件的范圍包括,從打包優化和壓縮,一直到重新定義環境中的變量等。
Mode:模式,有生產模式production和開發模式development
理解Loader
Webpack 本身只能加載JS/JSON模塊,如果要加載其他類型的文件(模塊),就需要使用對應的loader 進行轉換/加載
Loader 本身也是運行在 node.js 環境中的 JavaScript 模塊
它本身是一個函數,接受源文件作為參數,返回轉換的結果
loader 一般以 xxx-loader 的方式命名,xxx 代表了這個 loader 要做的轉換功能,比如 json-loader。
理解Plugins
插件可以完成一些loader不能完成的功能。
插件的使用一般是在 webpack 的配置信息 plugins 選項中指定。
配置文件(默認)
webpack.config.js : 是一個node模塊,返回一個 json 格式的配置信息對象
開啟項目
初始化項目:
生成package.json文件
{"name": "webpack_test","version": "1.0.0"}
安裝webpack
npm install webpack webpack-cli -g //全局安裝,作為指令使用
npm install webpack webpack-cli -D //本地安裝,作為本地依賴使用
編譯打包應用
創建js文件
- src/js/app.js
- src/js/module1.js
- src/js/module2.js
- src/js/module3.js
創建json文件
src/json/data.json
創建主頁面:
src/index.html
運行指令
- 開發配置指令:webpack src/js/app.js -o dist/js/app.js --mode=development
- 功能: webpack能夠編譯打包js和json文件,并且能將es6的模塊化語法轉換成瀏覽器能識別的語法
- 生產配置指令:
webpack src/js/app.js -o dist/js/app.js --mode=production
- 功能: 在開發配置功能上加上一個壓縮代碼
結論:
- webpack能夠編譯打包js和json文件
- 能將es6的模塊化語法轉換成瀏覽器能識別的語法
- 能壓縮代碼
缺點:
- 不能編譯打包css、img等文件
- 不能將js的es6基本語法轉化為es5以下語法
改善: 使用webpack配置文件解決,自定義功能
使用webpack配置文件
目的:
在項目根目錄定義配置文件,通過自定義配置文件,還原以上功能
文件名稱:
webpack.config.js
文件內容:
const { resolve } = require('path'); //node內置核心模塊,用來設置路徑。module.exports = {entry: './src/js/app.js', // 入口文件配置(簡寫)/*完整寫法:entry:{main:'./src/js/app.js'}*/output: { // 輸出配置filename: './js/built.js', // 輸出文件名path: resolve(__dirname, 'build') //輸出文件路徑配置},mode: 'development' //開發環境(二選一)mode: 'production' //生產環境(二選一)};
運行指令: webpack
打包less資源
概述:
less文件webpack不能解析,需要借助loader編譯解析
創建less文件
- src/less/test1.less
- src/less/test2.less
- 入口app.js文件
- 引入less資源
- 安裝loader
npm install css-loader style-loader less-loader less --save-dev
配置loader
{test: /\.less$/, // 檢查文件是否以.less結尾(檢查是否是less文件)use: [ // 數組中loader執行是從下到上,從右到左順序執行'style-loader', // 創建style標簽,添加上js中的css代碼'css-loader', // 將css以commonjs方式整合到js文件中'less-loader' // 將less文件解析成css文件]},
運行指令: webpack
js語法檢查
概述:
對js基本語法錯誤/隱患,進行提前檢查
安裝loader
- npm install eslint-loader eslint --save-dev
- 備注1:在:eslint.org網站 -> userGuide -> Configuring ESLint 查看如何配置
- 備注2:在:eslint.org網站 -> userGuide -> Rules 查看所有規則
配置loader
module: {rules: [{test: /\.js$/, //只檢測js文件exclude: /node_modules/, //排除node_modules文件夾enforce: "pre", //提前加載使用use: { //使用eslint-loader解析loader: "eslint-loader" }} ]}
加粗樣式
"eslintConfig": {"parserOptions": {"ecmaVersion": 6, // 支持es6"sourceType": "module" // 使用es6模塊化},"env": { // 設置環境"browser": true, // 支持瀏覽器環境: 能夠使用window上的全局變量"node": true // 支持服務器環境: 能夠使用node上global的全局變量},"globals": { // 聲明使用的全局變量, 這樣即使沒有定義也不會報錯了"$": "readonly" // $ 只讀變量},"rules": { // eslint檢查的規則 0 忽略 1 警告 2 錯誤"no-console": 0, // 不檢查console"eqeqeq": 2, // 用==而不用===就報錯"no-alert": 2 // 不能使用alert},"extends": "eslint:recommended" // 使用eslint推薦的默認規則 https://cn.eslint.org/docs/rules/},
運行指令: webpack
js語法轉換
概述:
將瀏覽器不能識別的新語法轉換成原來識別的舊語法,做瀏覽器兼容性處理
安裝loader
npm install babel-loader @babel/core @babel/preset-env --save-dev
配置loader
module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: "babel-loader",options: {presets: ['@babel/preset-env']}}}]}
運行指令: webpack
js兼容性處理
第一種方法:使用經典的polyfill
安裝包
npm install @babel/polyfill
使用
app.js
import '@babel/polyfill'; // 包含ES6的高級語法的轉換
優點
解決babel只能轉換部分低級語法的問題(如:let/const/解構賦值…),引入polyfill可以轉換高級語法(如:Promise…)
缺點
將所有高級語法都進行了轉換,但實際上可能只使用一部分
解決
需要按需加載(使用了什么高級語法,就轉換什么,而其他的不轉換)
第二種方法:借助按需引入core-js按需引入
安裝包
npm install core-js
配置loader
{test: /\.js$/,exclude: /(node_modules)/,use: {loader: 'babel-loader',options: {presets: [['@babel/preset-env',{useBuiltIns: 'usage', // 按需引入需要使用polyfillcorejs: { version: 3 }, // 解決warntargets: { // 指定兼容性處理哪些瀏覽器"chrome": "58","ie": "9",}}]],cacheDirectory: true, // 開啟babel緩存}}},
打包樣式文件中的圖片資源
概述:圖片文件webpack不能解析,需要借助loader編譯解析
添加2張圖片:
- 小圖, 小于8kb: src/images/vue.png
- 大圖, 大于8kb: src/images/react.jpg
- 在less文件中通過背景圖的方式引入圖片
安裝loader
npm install file-loader url-loader --save-dev
補充
url-loader是對象file-loader的上層封裝,使用時需配合file-loader使用。
配置loader
{test: /\.(png|jpg|gif)$/,use: {loader: 'url-loader',options: {limit: 8192, // 8kb --> 8kb以下的圖片會base64處理outputPath: 'images', // 決定文件本地輸出路徑publicPath: '../build/images', // 決定圖片的url路徑name: '[hash:8].[ext]' // 修改文件名稱 [hash:8] hash值取8位 [ext] 文件擴展名}}},
運行指令: webpack
打包html文件
概述:
html文件webpack不能解析,需要借助插件編譯解析
添加html文件
src/index.html
注意不要在html中引入任何css和js文件
安裝插件Plugins
npm install html-webpack-plugin --save-dev
在webpack.config.js中引入插件(插件都需要手動引入,而loader會自動加載)
const HtmlWebpackPlugin = require('html-webpack-plugin')
配置插件Plugins
plugins: [new HtmlWebpackPlugin({template: './src/index.html', // 以當前文件為模板創建新的HtML(1. 結構和原來一樣 2. 會自動引入打包的資源)}),]
運行指令: webpack
打包html中圖片資源
概述:
html中的圖片url-loader沒法處理,它只能處理js中引入的圖片 / 樣式中圖片,不能處理html中img標簽,需要引入其他html-loader處理。
添加圖片
在src/index.html添加兩個img標簽
安裝loader
npm install html-loader --save-dev
配置loader
{test: /\.(html)$/,use: {loader: 'html-loader'}}
運行指令: webpack
打包其他資源
概述:
其他資源webpack不能解析,需要借助loader編譯解析
添加字體文件
- src/media/iconfont.eot
- src/media/iconfont.svg
- src/media/iconfont.ttf
- src/media/iconfont.woff
- src/media/iconfont.woff2
修改樣式
@font-face {font-family: 'iconfont';src: url('../media/iconfont.eot');src: url('../media/iconfont.eot?#iefix') format('embedded-opentype'),url('../media/iconfont.woff2') format('woff2'),url('../media/iconfont.woff') format('woff'),url('../media/iconfont.ttf') format('truetype'),url('../media/iconfont.svg#iconfont') format('svg');}.iconfont {font-family: "iconfont" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
配置loader
{test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/, // 處理其他資源loader: 'file-loader',options: {outputPath: 'media',name: '[hash:8].[ext]'}}
運行指令: webpack
自動編譯打包運行
安裝loader
npm install webpack-dev-server --save-dev
詳細配置見官網:指南 -> 開發環境 -> 使用webpack-dev-server
修改webpack配置對象(注意不是loader中)
devServer: {open: true, // 自動打開瀏覽器compress: true, // 啟動gzip壓縮port: 3000, // 端口號}
修改url-loader部分配置
- 因為構建工具以build為根目錄,不用再找build了
publicPath: '../build/images/'
-->publicPath: 'images/'
修改package.json中scripts指令
"start": "webpack-dev-server",
運行指令: npm run start
注意webpack-dev-server
指令才能啟動devServer配置,然后配置到package.json中才行
熱模替換功能
概述:
熱模塊替換(HMR)是webpack提供的最有用的功能之一。它允許在運行時更新所有類型的模塊,而無需完全刷新(只更新變化的模塊,不變的模塊不更新)。
詳細配置見官網:指南 -> 模塊熱替換
修改devServer配置
devServer: {contentBase: resolve(__dirname, 'build'), // 運行項目的目錄open: true, // 自動打開瀏覽器compress: true, // 啟動gzip壓縮port: 3000, // 端口號hot: true // 開啟熱模替換功能 HMR}
問題: html文件無法自動更新了,需要增加一個入口
entry: ['./src/js/app.js','./src/index.html']
devtool
概述:
一種將壓縮/編譯文件中的代碼映射回源文件中的原始位置的技術,讓我們調試代碼不在困難
詳細配置見官網:配置 -> devtool
介紹
cheap 只保留行, 編譯速度快
eval webpack生成的代碼(每個模塊彼此分開,并使用模塊名稱進行注釋), 編譯速度快
inline 以base64方式將source-map嵌入到代碼中,缺點造成編譯后代碼體積很大
推薦使用:
開發環境: cheap-module-eval-source-map
生產環境: cheap-module-source-map
以上就是webpack開發環境的配置,可以在內存中自動打包所有類型文件并有自動編譯運行、熱更新等功能。
準備生產環境
創建文件夾config
將webpack.config.js復制兩份
- ./config/webpack.dev.js
- ./config/webpack.prod.js
- 修改webpack.prod.js配置,刪除webpack-dev-server配置
// / 代表根路徑(等價于這個:http://localhost:5000/),以后項目上線所有路徑都以當前網址為根路徑出發module.exports = {output: {path: resolve(__dirname, '../build'), // 文件輸出目錄filename: './js/built.js', // 文件輸出名稱publicPath: '/' // 所有輸出資源在引入時的公共路徑,若loader中也指定了publicPath,會以loader的為準。},module: {rules: [{test: /\.(png|jpg|gif)$/,use: {loader: 'url-loader',options: {limit: 8192, outputPath: 'images', publicPath: '/images', // 重寫publicPath,需要在路徑前面加上 /name: '[hash:8].[ext]' }}}, ]},mode: 'production', //修改為生產環境devtool: 'cheap-module-source-map' // 修改為生產環境的錯誤提示// 刪除devServer}
修改package.json的指令
“start”: “webpack-dev-server --config ./config/webpack.dev.js”
“dev”: “webpack-dev-server --config ./config/webpack.dev.js”
“build”: “webpack --config ./config/webpack.prod.js”
開發環境指令
npm start
npm run dev
生產環境指令
npm run build
注意: 生產環境代碼需要部署到服務器上才能運行 (serve這個庫能幫助我們快速搭建一個靜態資源服務器)
npm i serve -g
serve -s build -p 5000
清除打包文件目錄
概述:
每次打包生成了文件,都需要手動刪除,引入插件幫助我們自動刪除上一次的文件
安裝插件
npm install clean-webpack-plugin --save-dev
引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');// 注意要解構賦值!!!
配置插件
new CleanWebpackPlugin() // 自動清除output.path目錄下的文件
運行指令: npm run build
提取css成單獨文件
安裝插件
npm install mini-css-extract-plugin --save-dev
引入插件
const MiniCssExtractPlugin = require(“mini-css-extract-plugin”);
配置loader
{test: /\.less$/,use: [MiniCssExtractPlugin.loader,'css-loader','less-loader',]}
配置插件
new MiniCssExtractPlugin({filename: "css/[name].css",})
運行指令
npm run build
serve -s build
添加css兼容
安裝loader
npm install postcss-loader postcss-flexbugs-fixes postcss-preset-env postcss-normalize autoprefixer --save-dev
配置loader
{test: /\.less$/,use: [MiniCssExtractPlugin.loader,'css-loader',{loader: 'postcss-loader',options: {ident: 'postcss',plugins: () => [require('postcss-flexbugs-fixes'),require('postcss-preset-env')({autoprefixer: {flexbox: 'no-2009',},stage: 3,}),require('postcss-normalize')(),],sourceMap: true,},},'less-loader',]}
添加配置文件: .browserslistrc
last 1 version> 1%IE 10 # sorry
運行指令:
npm run build
serve -s build
壓縮css
安裝插件
npm install optimize-css-assets-webpack-plugin --save-dev
引入插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
配置插件
new OptimizeCssAssetsPlugin({cssProcessorPluginOptions: {preset: ['default', { discardComments: { removeAll: true } }],},cssProcessorOptions: { // 解決沒有source map問題map: {inline: false,annotation: true,}}})
運行指令:
npm run build
serve -s build
壓縮html
修改插件配置
new HtmlWebpackPlugin({template: './src/index.html',minify: {removeComments: true,collapseWhitespace: true,removeRedundantAttributes: true,useShortDoctype: true,removeEmptyAttributes: true,removeStyleLinkTypeAttributes: true,keepClosingSlash: true,minifyJS: true,minifyCSS: true,minifyURLs: true,}})
運行指令:
npm run build
serve -s dist
以上就是webpack生產環境的配置,可以生成打包后的文件。
本期推薦
最近幾年Vue越來越火熱,BAT等互聯網大廠都在前端職位招聘中加入了精通Vue.js框架的要求,就連餓了么公司的技術團隊也專門為Vue.js設計了UI框架體系。本書的實操案例都是筆者獨立完成的實際項目,有著對標市場實際需求的參考價值,同時本書提供的框架模式可以讓讀者應用于其他項目,從而提高開發效率,減少開發彎路。
本書從Vue.js框架技術的基礎概念出發,逐步深入Vue.js進階實戰,并在最后配合一個網站項目和一個后臺系統開發實戰案例,重點介紹了使用Vue.js+axios+ElementUI+wangEditor進行前端開發和使用組件進行Vue單頁面網頁復用,讓讀者不但可以系統地學習Vue.js前端開發框架的相關知識,而且還能對業務邏輯的分析思路、實際應用開發有更為深入的理解。
本書語言平實,用詞詼諧,案例豐富,實用性強,特別適合剛入社會的職場新人、Vue.js框架的初級讀者和進階讀者閱讀,也適合希望從后臺開發轉型做前端的程序員等其他編程愛好者閱讀。另外,本書也適合作為相關培訓機構的教材使用。