webpack是一個很是實用的靜態模塊打包工具,它經過遞歸的方式構建一個包含應用程序須要的全部模塊的依賴圖,而後將這些文件打包成一個或多個bundle輸出javascript
早期的開發中都是將各類靜態文件(好比圖片,CSS等)手動引入到html中,而後直接在瀏覽器中運行html文件;在這個時期,遇到大型項目時要麼將全部的JS所有寫在一個文件中,要麼是引入多個腳本;前一種方式會致使代碼混亂;後一種方式會致使HTTP請求過多;css
隨着前端技術的發展,開始使用模塊化對代碼進行分割,讓代碼可以複用且更方便維護,但瀏覽器對模塊化的支持並不統一;html
webpack最核心的功能就是解決模塊之間的依賴問題,經過對webpack的簡單配置便可完成代碼轉換,壓縮,文件優化,模塊加載及打包等功能前端
npm install webpack webpack-cli -D
複製代碼
entry用於告訴webpack應該使用哪一個模塊作爲構建的開始;其默認值爲./src/index.js
java
module.exports = {
entry: './src/main.js'
}
複製代碼
output指定了webpack構建完成後的文件輸出位置以及輸出後的文件名等信息;node
const path = require('path') // nodeJs內置的path模塊
module.exports = {
entry: './src/main.js',
output: {
filename: 'main.[hash].js', // 輸出文件的文件名
path: path.resolve(__dirname, 'dist')
// path屬性用於指定輸出的文件路徑,它必須接收絕對路徑
// path.resolve()方法用於將相對路徑轉換成絕對路徑
}
}
複製代碼
[hash]
: [hash]用於解決靜態文件緩存問題;靜態文件內容更改而文件名不更改的狀況下,可能會由於瀏覽器緩存問題而獲取不到新的內容,經過hash可讓每一次打包的文件名不重複jquery
webpack會根據配置模式自動調用相應的內置優化項; 可選的配置模式有development
, production
, none
, 默認值爲production
webpack
配置模式能夠在webpack的配置文件中顯式的指定git
module.exports = {
mode: 'development'
}
複製代碼
在實際的項目開發中,更多的是經過腳本的方式執行CLI,經過CLI的參數傳遞github
<!-- package.json -->
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack-dev-server --mode=development"
}
複製代碼
loader用於對模塊中的源代碼進行轉換,webpack本質上只能理解JavaScript和JSON文件,若是要解析其餘代碼就須要對代碼進行轉換,好比將typeScript代碼轉換成javascript代碼;
test
: 使用正則篩選出須要使用loader的文件use
: 轉換時須要使用的loader,能夠同時使用多個loader;經過對象的方式能夠對loader進行個性化的配置include
: 指定loader必需要應用的文件夾exclude
: 指定loader須要排除不處理的文件夾loader的執行順序是從下往上,從右往左;也就是說,在代碼中越靠後的loader越先執行;在下面的例子中,css-loader比style-loader先執行
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', ''css-loader]
}
]
}
}
複製代碼
webpack的插件系統,經過插件能夠擴展webpack的功能
webpack解析時默認從webpack.config.js
文件提取配置,因此將webpack的相關配置都寫到這個文件中
<!-- webpack.config.js -->
const path = require('path')
module.exports = {
entry: './main.js',
output: {
filename: 'index.js',
path: path.resolve(_dirname, 'dist')
}
}
複製代碼
以上就是一個最基礎的webpack配置,以當前(webpack.config.js
所在的目錄)目錄下的main.js
爲入口開始構建,輸出到當前目錄下的dist文件夾中;
在單頁面應用開發中都須要使用一個html文件做爲模板;html-webpack-plugin用於指定一個html文件做爲模板,並以這個模板爲基礎引入打包後的js,css等文件,而後根據output的配置輸出
安裝
npm install html-webpack-plugin -D
複製代碼
配置
<!-- webpack.config.js -->
let HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 省略其餘代碼
plugins: [
template: './index.html', // 指定模板文件路徑
filename: 'index.html', // 指定打包後輸出的模板文件名
minify: { // 指定模板壓縮的規則
removeAttributeQuotes: true, // 刪除屬性的雙引號
collapseWhitespace: true, // 摺疊空行
},
hash: true, // 添加hash戳,hash能夠避免緩存問題
]
}
複製代碼
在上面的配置中,指定了模板的路徑(template
)以及打包完成後輸出的文件名稱(filename
), 同時指定了模板文件的壓縮規則(minify
), 爲解決緩存問題添加了hash
戳,輸出的模板文件都會帶上hash
值;更多html-webpack-plugin的配置能夠參考官方文檔
webpack-dev-server提供了一個本地的web開發服務和熱更新的能力;經過這個本地server直接訪問應用能夠更好的開發和調試
安裝
npm install webpack-dev-server -D
複製代碼
配置
module.exports = {
devServer: {
port: '8080', // 開發服務端口
host: 'localhost',
progress: true, // 配置打包進度條
contentBase: './dist', // 指定靜態服務的啓動文件夾
}
}
複製代碼
在package.json
文件中配置一個腳本,
<!-- package.json -->
"scripts": {
"dev": "webpack-dev-server --mode=development"
}
複製代碼
此時經過npm run dev
就能夠啓動一個本地開發服務了;更多關於webpack-dev-server的配置能夠參考官方文檔
webpack中css的解析主要依賴兩個loader來完成:css-loader,style-loader
css-loader
主要負責解析@import和url()
style-loader
的主要做用是將css經過style標籤的方式添加到模板文件中
安裝
npm install style-loader css-loader -D
複製代碼
配置
<!-- webpack.config.js -->
module.exports = {
// 省略其餘代碼
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
複製代碼
由於須要先解析css中的@import和url()語法,因此css-loader應該寫style-loader以後
less和sass的解析依賴於less-loader和 sass-loader;
使用這兩個loader以前須要安裝less和sass模塊
安裝
npm install less less-loader node-sass sass-loader -D
複製代碼
配置
<!-- webpack.config.js -->
module.exports = {
// 省略其餘代碼
module: {
rules: [
{
test: /\.less/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.scss/,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {}
}
]
}
]
}
}
複製代碼
個性化loader配置
: 在上面的配置中,scss-loader使用了對象語法進行配置,這種方式能夠經過options對象來對loader進行更多個性化的配置
因爲瀏覽器對css新屬性的兼容性不統一,因此一些新的css屬性在使用的時候須要爲不一樣的瀏覽器加上前綴
autoprefixer經過postcss配置後能夠爲自動爲css添加不一樣瀏覽器的前綴
安裝
npm install autoprefixer postcss-loader -D
複製代碼
配置
<!-- webpack.config.js -->
module.exports = {
// 省略其餘代碼
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','postcss-loader' 'css-loader']
}
]
}
}
複製代碼
接下來還須要經過postCSS配置autoprefixer才能自動添加前綴
<!-- postcss.config.js -->
const autoprefixer = require('autoprefixer')
module.exports = {
plugins: [autoprefixer]
}
複製代碼
經過前面的配置,已經能夠解析css而且將css經過style標籤的形式插入到模板中; 可是若是css內容過多,則會讓模板文件中的css顯得臃腫,這個時候就須要將css單獨抽離出一個文件,以link的方式引入模板
mini-css-extract-plugin插件用於將CSS提取到單獨的文件中
安裝
npm install mini-css-extract-plugin -D
複製代碼
配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// 省略其餘代碼
plugin: [
new MiniCssExtractPlugin({
filename: 'css/index.css'
})
]
}
複製代碼
filename
: 抽離以後的css文件名稱,若是使用路徑的方式則會將文件抽離到指定的路徑下,以上面的代碼爲例,index.css
會抽離到./dist/css/index.css
使用mini-css-extract-plugin插件以後,css將會抽離成單獨的文件,因此須要使用MiniCssExtractPlugin.loader替換原有的style-loader
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// 省略其餘代碼
plugin: [
new MiniCssExtractPlugin({
filename: 'index.css' // 抽離後的css文件名
})
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
}
}
複製代碼
因爲瀏覽器對新的ES語法支持並非一致,爲了保證代碼的兼容性,須要將新的ES語法(ES6,ES7,ES8等)轉換爲瀏覽器都支持ES5語法;在webpack中,這個轉換的功能主要經過babel來完成
安裝
npm install babel-loader @babel/core @babel/preset-env -D
複製代碼
配置
module.exports = {
// 省略其餘代碼
rules: [
{
test: '/\.js$/',
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
},
include: path.resolve(__dirname, 'src'), // 但願應用的文件夾
exclude: /node_modules/ // 須要排除的文件夾
}}
]
}
複製代碼
webpack中的文件壓縮經過配置optimization來完成
module.exports = {
// 省略其餘代碼
optimization: [
]
}
複製代碼
optimize-css-assets-webpack-plugin插件能夠用於css文件的壓縮
安裝
npm install optimize-css-assets-webpack-plugin -D
複製代碼
配置
const OptimizeCss = require('optimize-css-assets-webpack-plugin')
module.exports = {
// 省略其餘代碼
optimization: [
new OptimizeCss()
]
}
複製代碼
uglifyjs-webpack-plugin插件用於JS文件的壓縮
安裝
npm install uglifyjs-webpack-plugin -D
複製代碼
配置
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
// 省略其餘代碼
optimization: [
new UglifyJsPlugin({
parallel: true
})
]
}
複製代碼
webpack中的圖片配置可使用url-loader來完成,url-loader與file-loader功能類似;可是它能夠在圖片大小低於指定的限制時,將圖片轉換爲base64格式,以此減小HTTP請求
安裝
npm install url-loader -D
複製代碼
配置
module.exports = {
// 省略其餘代碼
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240, // 單位爲字節
outputPath: 'img/'
}
}
]
}
]
}
}
複製代碼
outputPath
: 指定圖片輸出路徑,已上面的配置爲例,圖片文件將輸出到./dist/img/
目錄下
當下前端開發的主流框架都是以數據驅動的,不多去操做DOM;可是若是項目業務特殊須要用到jQuery的話,爲了不每一次使用的時候都經過import去引入,可使用webpack配置一個全局變量
webpack全局變量的配置主要使用webpack的內置模塊(內置模塊不須要經過npm安裝,直接使用便可)ProvidePlugin來完成,詳細內容能夠參考官方文檔
配置
npm install jquery
module.exports = {
// 省略其餘代碼
plugins: [
new webpack.ProvidePlugin({
$: "jquery"
})
]
}
複製代碼
爲了不屢次打包後輸出目錄混亂(舉例:每次打包都輸出一個名稱帶hash的文件,屢次打包後就會產生多個文件在同一個目錄中,可是隻有最後一次輸出的文件纔有用)的問題,能夠經過clean-webpack-plugin插件,在每一次打包的時候都將輸出目錄清空,這樣,每一次打包後的輸出文件夾中都會比較乾淨
安裝
npm install clean-webpack-plugin -D
複製代碼
配置
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
// 省略其餘代碼
plugins: [
new CleanWebpackPlugin()
]
}
複製代碼
本文主要了解了webpack中的一些核心概念並介紹了一些經常使用配置所須要的插件,loader等,經過這些配置就已經能夠知足多數場景的基本開發需求了
本文所對應的配置源碼已提交到個人github
end