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'
}]
}]
},
然后打包