目錄
什麼是webpack
本質上,webpack
是一個現代 JavaScript
應用程序的靜態模塊打包器(module bundler
)。當 webpack
處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph
),其中包含應用程序需要的每個模塊,然後將所有這些模塊打包成一個或多個 bundle
。
webpack可以做什麼
- 代碼轉換
把es6轉成es5,把sass,less轉成css; - 文件優化
壓縮代碼體積,合併文件 - 代碼分割
公共模塊分離,懶加載 - 模塊合併
按照功能,把多個模塊合併成一個模塊 - 自動刷新
自動啓動服務,代碼變更後頁面也跟着變更,熱更新 - 代碼校驗
校驗代碼是否符合規範 - 自動發佈
把打包後的結果發佈到服務器上
學習webpack的前提
- 需要node基礎,npm的使用
- 掌握es6語法
webpack安裝
前提:需要node.js環境(安裝配置node.js環境)
本地安裝webpack命令如下:
npm install webpack webpack-cli -D
webpack學習
1. webpack基礎配置
// a.js
module.exports = 'hello'
// index.js
let str = require('./a.js')
console.log(str)
文件webpack.config.js
是webpack的配置文件,
webpack是node寫出來的,因此用node的寫法
// webpack.config.js 內容
let path = require('path')
module.exports = {
mode:'development', // 模式 默認兩種:production development
entry:'./src/index.js', // 入口
output:{
filename:'bundle.js', // 打包後的文件名
path: path.resolve(__dirname, 'dist'), // 路徑必須是一個絕對路徑
}
}
上面基礎配置含義爲:
在開發模式下(文件不壓縮),根據入口文件./src/index.js
的內容,構建內部依賴圖並處理,最後輸出到出口文件當前目錄下的dist文件中的文件名爲bundle.js的文件上
mode
屬性設置webpack的模式
production
生產模式,打包後的代碼是壓縮的development
開發模式, 打包後的代碼是不壓縮的
相關屬性:
entry
設置打包入口
- 入口起點(entry point)指示 webpack 應該使用哪個模塊,來作爲構建其內部依賴圖的開始。
- 進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。
- 每個依賴項隨即被處理,最後輸出到
output
屬性設置的文件中
output
設置打包出口
- output屬性告訴webpack在哪裏輸出它所打包創建的文件
如果你不想使用webpack默認配置文件名webpack.config.js
,而是想使用myConfig.js
這樣的文件名
只需要在執行webpack時,在命令後面追加文件名即可
例如:
默認文件名執行命令
npx webpack
設置文件名執行命令
npx webpack --config myConfig.js
一般情況下,我們可以在package.json
裏寫一些腳本來處理如上情況:
"scripts": {
"build": "webpack --config myConfig.js"
},
這個時候只需在命令行裏輸入npm run build
命令,即可執行webpack --config myConfig.js
2. html插件
前面我們用webpack打包生成了bundle.js文件;要執行該文件,我們可以在dist文件下創建index.html
在裏面用script
導入bundle.js
文件
<body>
<script src="bundle.js"></script>
</body>
右鍵打開瀏覽器,即可執行該頁面
如果我們想要開啓服務,地址爲localhost
這樣來訪問,要如何設置?
安裝webpack-dev-server
npm i webpack-dev-server -D
配置webpack.config.js
devServer:{ // 開發服務器的配置
port:3000, // 修改端口號
progress:true,
contentBase:'./dist'
},
如果dist
文件裏沒有html文件,需要我們生成到dist
文件下,該如何做?
首先,src
源代碼文件下有個模板文件index.html
安裝html-webpack-plugin
插件
npm i html-webpack-plugin -D
在webpack.config.js
裏配置:
plugins:[ // 數組 放置所有的webpack插件
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html',
minify:{
removeAttributeQuotes:true, // 刪除文件裏的雙引號
collapseWhitespace:true, // 文件壓縮爲一行
},
hash:true // 生成hash戳,會在script引入的文件名後追加hash值
})
]
執行npm run build
後,就會在dist
文件裏生成bundle.js
和index.html
給文件名生成hash值,防止緩存
webpack.config.js
裏設置:
output:{
filename:'bundle.[hash].js',
path:path.resolve(__dirname,'dist')
},
生成8位hash值:
output:{
filename:'bundle.[hash:8].js',
path:path.resolve(__dirname,'dist')
},
3. 樣式處理
安裝css-loader
和style-loader
npm i css-loader style-loader -D
webpack.config.js
裏配置
module:{ // 模塊
rules:[ // 規則
// css-loader 解析 @import這種語法
// style-loader 把css插入到head的標籤中
// loader的特點,希望單一
// loader的用法,一個loader 用字符串
// 多個loader 用[]
// loader的順序,默認從右向左執行(從下到上)
// loader還可以寫成對象,好處是裏面還可以傳參數
{
test: /\.css$/,
use:[
{
loader: 'style-loader',
},
'css-loader'
]
},
]
}
如果要處理less
文件
首先安裝:
npm i less less-loader -D
webpack.config.js
->module
->rules
裏配置:
{
test: /\.less$/,
use:[
{
loader: 'style-loader',
},
'css-loader',
'less-loader' // 把less 轉成css
]
},
其他文件sass
stylus
配置類似
上面是把樣式放到style
標籤裏,那麼如何用link
標籤來引入樣式呢?
首先安裝插件:
npm i mini-css-extract-plugin -D
webpack.config.js
裏配置:
引入mini-css-extract-plugin
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
plugins
裏配置
new MiniCssExtractPlugin({
filename:'main.css' // 抽離出的文件名
})
module
裏配置:
module:{ // 模塊
rules:[ // 規則
{
test: /\.css$/,
use:[
MiniCssExtractPlugin.loader,// css文件用link引入
'css-loader'
]
},
{
test: /\.less$/,
use:[
{
loader: 'style-loader',
},
'css-loader',
'less-loader' // 把less 轉成css
]
},
]
}
爲了瀏覽器兼容,我們需要給一些css屬性加上前綴,例如-webkit-
安裝:
npm i postcss-loader autoprefixer -D
webpack.config.js
裏配置:
module:{ // 模塊
rules:[ // 規則
{
test: /\.css$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader', // 添加前綴
]
},
{
test: /\.less$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader' // 把less 轉成css
]
},
]
}
需要創建postcss.config.js
文件
文件內容:
module.exports = {
plugins : [
require('autoprefixer')({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
//'last 10 versions', // 所有主流瀏覽器最近10版本用
],
grid: true
})
]
}
如上配置好後,運行代碼,CSS屬性就會自動加上前綴了。
CSS壓縮打包
安裝插件optimize-css-assets-webpack-plugin
,因爲使用了這個插件,css雖然壓縮了,可js卻變爲不壓縮了。因此還需要安裝插件terser-webpack-plugin
npm i optimize-css-assets-webpack-plugin terser-webpack-plugin -D
webpack.config.js
裏配置:
導入插件:
let TerserJSPlugin = require('terser-webpack-plugin')
let OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
配置:
optimization: { // 優化項
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
這樣子,打包出來的js和css都爲壓縮格式了。
4. 將ES6,ES7等高級語法轉化爲瀏覽器可識別的ES5語法
瀏覽器對一些高級語法的支持性並不是非常好,因此我們需要使用Babel來做一些轉化
支持例如:let fn = () => {}
es6的箭頭函數語法
安裝:
npm i babel-loader @babel/core @babel/preset-env -D
支持例如:
es7語法
class People{
constructor(name){
this.name = name
}
}
安裝:
npm i @babel/plugin-proposal-class-properties -D
webpack.config.js
->module
->rules
裏配置:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/ // 排除node_modules中的文件
},
根目錄下創建.babelrc
文件:
// .babelrc
{
"presets": ["@babel/preset-env"],
"plugins":[
"@babel/plugin-proposal-class-properties"
]
}
如果想使用裝飾器例如@log
,配置如下:
安裝:
npm install --save-dev @babel/plugin-proposal-decorators
.babelrc
裏配置:
{
"presets": ["@babel/preset-env"],
"plugins":[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
如果要使用generators
, async
等函數,需要安裝:
開發依賴
npm install --save-dev @babel/plugin-transform-runtime
生產依賴
npm install --save @babel/runtime
.babelrc
裏配置:
{
"presets": ["@babel/preset-env"],
"plugins":[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }],
["@babel/plugin-transform-runtime"] // 添加
]
}
如果要使用更高級的語法例如'abc'.includes('a')
babel只會轉換E6語法,而不會轉換新的api,讓新的api生效的方法是使用傳統的polyfill,爲此需要引入這個模塊
安裝:
npm i @babel/polyfill
使用:
require('@babel/polyfill')
'abc'.includes('a')
JS校驗怎麼弄?
安裝:
npm i eslint eslint-loader
webpack.config.js
->module
->rules
裏配置:
因爲loader
默認 從右向左/從下到上 執行,校驗肯定要在最前面的,因此需要加個enforce
屬性
{
test:/\.js$/,
use:{
loader:'eslint-loader',
options:{
enforce:'pre' // previous 強制先執行
}
}
},
另外還需要.eslintrc.json
文件,裏面是一些校驗規則
你可以在eslint
官網上進行校驗規則勾選,然後下載文件,把它放入項目根目錄中:
注意,文件名爲.eslintrc.json
,前面有個點;
最後,運行代碼,就能檢查出你的語法是否規範;