css
在html
中常用的引入方式有兩種,即通過<link>
和<style>
兩種標籤在html
頭部引入樣式,現在結合webpack
來實現上述功能。
1、style
標籤引入樣式
第一步:安裝css-loader
和style-loader
,webpack
不知道如何提取解析樣式文件,需要這些加載器來告訴它
css-loader
:主要用於加載css
文件,並處理css
中的依賴,例如@import
和url()
等引用外部文件的聲明
參考:https://github.com/webpack-contrib/css-loader
style-loader
:會將css-loader
解析的結果轉變成JS
代碼,運行時動態插入style
標籤來讓CSS
代碼生效。
第二步:更改配置文件
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: {
main: './css-handle/app.js'
},
output: {
path: path.resolve(__dirname, 'build'), // 打包文件的輸出目錄
filename: '[name].bundle.js', // 代碼打包後的文件名
publicPath: './', // 引用的路徑或者 CDN 地址
chunkFilename: '[name].js' // 代碼拆分後的文件名
},
module: {
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}]
}]
},
// 拆分代碼配置項
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
common: {
name: 'common',
minSize: 0, //表示在壓縮前的最小模塊大小,默認值是 30kb,如果沒設置爲0,common模塊就不會抽離爲公共模塊,因爲原始大小小於30kb
minChunks: 2, // 最小公用次數
priority: 5, // 優先級
reuseExistingChunk: true // 公共模塊必開啓
},
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
},
plugins: [
new CleanWebpackPlugin(), // 會刪除上次構建的文件,然後重新構建
new BundleAnalyzerPlugin(),
new HtmlWebpackPlugin({
// 打包輸出HTML
title: '自動生成 HTML',
minify: {
// 壓縮 HTML 文件
removeComments: true, // 移除 HTML 中的註釋
collapseWhitespace: true, // 刪除空白符與換行符
minifyCSS: true // 壓縮內聯 css
},
filename: 'index.html', // 生成後的文件名
template: path.resolve(__dirname, 'index.html'), // 根據此模版生成 HTML 文件
chunks: ['main'] // entry中的 main 入口才會被打包
})
]
}
注意:module.rules.use 數組中,loader 的位置。根據 webpack 規則:放在最後的 loader 首先被執行,從上往下寫的話是下面先執行,從左往右寫的話是右邊先執行。
這裏css-loader應該先於style-loader執行,先加載css文件然後再樣式插入到DOM中。
第三步:打包測試
// a.js
console.log('A')
export default 'A'
// app.js
import '../assets/css/base.css'
import(/* webpackChunkName: 'a'*/ './a').then((a) => {
console.log(a)
})
運行cnpm run dev
打包入口文件app.js
當base.css
文件中還引入其他樣式文件,我們也來打包看看
// style.css
html {
font-size: 16px;
}
// base.css
@import './style.css';
*, body {
margin: 0;
padding: 0;
}
html {
background-color: red;
}
// app.js
import '../assets/css/base.css'
import(/* webpackChunkName: 'a'*/ './a').then((a) => {
console.log(a)
})
可以看到每一個樣式文件都對應着一個style
標籤
我們可以看到生成的html
文件中並沒有引入樣式文件代碼,但是瀏覽器打開index.html
文件時是有引入樣式的,這是爲什麼呢?
這是因爲樣式文件base.css
和入口文件app.js
將會一起被打包到main.bundle.js
文件裏面,當瀏覽器加載index.html
文件時會動態執行腳本,把樣式使用style
標籤插入到DOM
中。
我們可以在main.bundle.js
中找到base.css
2、link
標籤引入樣式
style-loader
高版本已經不支持link
標籤插入文件樣式了,因爲如果在一個js
文件引入多個css
文件會生成多個link
標籤,而html
中每一個link
標籤都會發送一次網絡請求,所以這種方式慢慢就被棄用。
這裏我們僅僅拿來探索一下,知道有這種方式的存在就可以了。
首先,我們先把style-loade
r版本降到0.20.0
,然後更改配置
module: {
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader/url'
}, {
loader: 'file-loader'
}]
}]
},
然後打包