打包css資源
使用loader
webpack可以使用各種不同loader來預處理不同格式的資源。
- 在專案目錄下新增檔案:
// src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<div class="box"></div>
</body>
</html>
複製程式碼
// src/css/style.css
.box{
width:50px;
height: 50px;
background-color: pink;
}
複製程式碼
- 安裝
css-loader
和style-loader
css-loader
負責讀取css檔案,然後使用style-loader
將css內容注入到js裡面去,最終是以style標籤的形式嵌入到Html程式碼中
npm i -D css-loader style-loader
- 更改配置檔案
module:
{
test: /\.css$/,
use: [
{
loader:'style-loader', //以style標籤的形式嵌入到html中
options:{
insertAt:top //嵌入位置,top指頂部,不會覆蓋掉html自帶的style樣式
}
}
'css-loader' //解析css檔案
]
},
複製程式碼
module使用方法:
rules
:一個陣列,存放各種Loadertest
:正規表示式,用來匹配不同的檔名字尾loader
:有多種使用方法
{
test:/\.js$/,
loader:'babel-loader' //只有一個loader時
}
{
test:/\.css$/,
use:['style-loader','css-loader'] //多個loader,從右往左載入
}
{
test:/\.css$/,
use:[
'style-loader', //多個loader混合使用
{ //loader要設定相關引數時可以使用物件
loader:'css-loader',
options:{
minimize:true
}
}
]
}
複製程式碼
使用外掛MiniCssExtractPlugin
使用css-loader
+style-loader
的方式是將樣式打包進js
檔案,然後以style
標籤的形式嵌入頁面。css
樣式與js
檔案混在一起可能導致一些樣式混亂,所以使用外掛將css
樣式統一打包進一個cs
s檔案,然後以link
標籤的形式嵌入頁面進行資源請求。
webpack3
通常使用的是ExtractWebpackPlugin
,但在webpack4中已不再支援,官方推薦使用MiniCssExtractPlugin
進行替代。
首先安裝 :
npm i -D mini-css-extract-plugin
修改配置檔案
const miniCssExtractPlugin=require('mini-css-extract-plugin');
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
path: path.join(__dirname, 'dist'),
filename:'bundle.js',
},
module: {
rules:[
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader
},
'css-loader'
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template:'./src/index.html'
}),
new miniCssExtractPlugin({
filename:'[name].css' //輸出的css檔名,放置在dist目錄下
})
]
}
複製程式碼
開啟dist/index.html,可以看到以link形式引入了css樣式。
自動新增字首
我們希望可以給css自動新增瀏覽器字首,可以使用外掛autoprefixer
.
- 首先安裝,
npm i -D postcss-loader autoprefixer
postcss-loader
需要一個配置檔案,在根目錄下新建postcss.config.js
檔案,寫入:
module.exports={
plugins:[require('autoprefixer')]
}
複製程式碼
- 配置loader
// webpack.config.js
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader //抽離成一個css檔案
},
'css-loader', //解析css
'postcss-loader' //先新增字首
]
}
複製程式碼
- 編寫css測試程式碼
// src/css/style.css
.box{
width:50px;
height: 50px;
background-color: pink;
transform: rotateX(30deg);
}
複製程式碼
- 打包
npm run build
後,開啟dist/main.css
,可以看到tranform已經加上了webkit字首。
壓縮css/js程式碼
使用optimize-css-assets-webpack-plugin
外掛來壓縮css程式碼。
- 安裝
npm i -D optimize-css-assets-webpack-plugin
- 修改配置檔案
// webpack.config.js
const opimizeCss=require('optimize-css-assets-webpack-plugin');
module.exports = {
optimization:{
minimizer:[
new opimizeCss()
]
},
mode:'production'
....
}
複製程式碼
- npm run build以後開啟main.css發現已經被壓縮,但是在預設環境為production時自動壓縮的js程式碼卻不再壓縮了,我們使用
uglifyjs-webpack-plugin
來壓縮js程式碼。 - 安裝
npm i -D uglifyjs-webpack-plugin
- 修改配置檔案
//webpack.config.js
const uglifyJsWebpackPlugin=require('uglifyjs-webpack-plugin')
module.exports = {
optimization:{
minimizer:[
new uglifyJsWebpackPlugin({
cache:true, //是否快取
parallel:true, //是否併發打包,同時打包多個檔案
sourceMap:true //打包後的程式碼與原始碼的對映,方便除錯
})
...
]
...
}
複製程式碼
es6轉es5
webpack裡面使用了大量的es6語法,我們需要轉換為es5,使用babel來完成此功能。
- 安裝babel
npm i -D babel-loader @babel/core @babel/preset-env
- 配置loader
{
test:/\.js$/,
use:[
{
loader:'babel-loader',
options:{
presets:[
`@babel/preset-env` //es6轉es5
]
}
}
]
}
複製程式碼
打包圖片資源
在js中建立圖片引入
(1)引入的圖片需要在入口的js檔案中import進去
// index.js
import img from './img/big.jpg'; //file-loader將該圖片放入到dist下,同時返回圖片的地址
var imgElement = document.createElement('img');
imgElement.src = img;
document.body.appendChild(imgElement);
複製程式碼
(2)安裝file-loader
並配置 npm i -D file-loader
// webpack.config.js
{
test: /\.(png|jpg|gif|svg|jpeg)$/,
loader: 'file-loader',
}
複製程式碼
在css中中引入背景圖片
與js引入圖片用法相同,不過比起file-loader
,更常用的是url-loader
,可以將小圖片直接base64編碼,減少http請求。
(1)安裝url-loader
並配置 npm i -D url-loader
// webpack.config.js
{
test: /\.(png|jpg|jpeg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 1024, //小於該值的圖片會使用base64編碼
name: '[name].[hash:8].[ext]' //打包後的圖片名稱 [ext]指圖片格式
}
}
複製程式碼
直接在html寫入標籤
// src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<div class="box"></div>
<img src="./img/big.png">
</body>
</html>
複製程式碼
打包後發現該圖片的地址是寫死的,並不會相對於dist,導致無法找到該圖片,使用html-withimg-loader
來處理html中的圖片。
安裝並配置
npm i -D html-withimg-loader
// webpack.config.js
{
test:/\.html$/,
loader:'html-withimg-loader'
}
複製程式碼
再次打包執行後發現可以正確載入圖片了。
配置不同的資源路徑
現在這種配置下,所有的資源都放置在dist目錄下,看起來很混亂,我們希望js在js資料夾下,css在css資料夾下,圖片在img資料夾下,修改相關配置。
//webpack.config.js
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
path: path.join(__dirname, 'dist'),
filename:'js/bundle.js', //給打包輸出的js新增一層目錄
},
module: {
rules:[
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader
},
'css-loader',
'postcss-loader'
]
},
{
test:/\.js$/, //最後會打包進輸出的js的檔案,所以不需要配置路徑
use:[
{
loader:'babel-loader',
options:{
presets:[
`@babel/preset-env`
]
},
}
]
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:8].[ext]',
//不能通過名字新增路徑,因為背景圖片還會被css處理一次,會再新增上css的路徑
//最後就會變成 css/img/big.1763821.png
outputPath:'img/', //通過該屬性設定,打包輸出的路徑多一層
publicPath:'http://cdn.com' //圖片的訪問路徑為 http://cdn.com/img/big.561361.png
},
},
{
test:/\.html$/,
loader:'html-withimg-loader', //會加上url-loader裡的outputPath
}
]
},
plugins: [
new htmlWebpackPlugin({
template:'./src/index.html'
}),
new miniCssExtractPlugin({
filename:'css/[name].css' //通過名字新增一層路徑
}),
new cleanWebpackPlugin()
]
}
複製程式碼
最終npm run build後,就可以有不同的資料夾,同時index.html也正確處理了路徑。