webpack4.0z中css相关配置
❝ 本篇文章介绍webpack中如何解析css模块,如果你错过了我之前的文章,可以到知乎专栏:LonJin的知乎专栏中阅读。
阅读完本文你可以学会如何模块化引入css、如何解析less
、如何抽离css、如何优化css资源。
❞
打包css
- 我们希望css也像模块一样去引入,像这样
require('./index.css')
,然而不做任何设置的情况下是不支持这种操作的,我们可以进行简单配置来实现这种功能。
准备
- 这里先看一下我的
/webpack.config.js
目前的配置:
let path=require('path');
let HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
mode:'development',//模式 默认两种 production(生产环境) development(开发环境)
entry:'./src/index.js',//入口文件
//output 出口文件
output:{
filename:'index.[hash:8].js',//打包后文件名
path:path.resolve(__dirname,'dist')//必须为绝对路径
},
plugins:[//数组,里面放着所有的webpack插件
new HtmlWebpackPlugin({
template:'./src/index.html',//指定文件
filename:'index.html',//输出文件名字
minify:{
removeAttributeQuotes:true,//删除双引号
collapseWhitespace:true,//折叠空行
},
hash:true//避免缓存
})
]
}
css-loader与style-loader
- 在
/src
目录下新建一个base.css
,然后写一些样式,如:
body{
color:red;
}
- 在
/src
目录下新建一个index.css
,然后写也写点样式,并使用css语法引入一下base.css
@import './base.css';
body,html{
background:#f8f8f8;
}
- 这时候我们希望在js中像引入模块一样的引入
css
文件,我们在src
目录下的index.js
中尝试引入一下:
require('./index.css')
- 然后打包;
npm run dev
,会发现报错:
- 看报错信息提示我们:翻译后:
您可能需要适当的加载程序来处理此文件类型,当前未配置任何加载程序来处理此文件
- 安装一下
css-loader
和style-loader
:
npm add css-loader style-loader -D
- 在
/webpack.config.js
进行module
模块配置:
module:{//模块
rules:[//规则
//css-loader 解析 @import这种语法
//style-loader 它是吧css插入到head的标签中
//loader的特点 希望单一
//loader的用法 只用一个loader字符串表示
//如果需要多个,则用数组[]
//loader顺序是从右到左,从下到上执行
//loader还可以用对象表示
{test:/.css$/,use:['style-loader','css-loader']}
]
}
rules
就是规则,然后test
就可以根据规则进行匹配,css-loader
负责解析@import
语法,style-loader
负责吧css插入到head标签中。loader顺序是从右到左,从下到上执行。所以css-loader
要放到后面去。- 然后重启启动一下项目,打开页面看下:
- 可以看到,首先解析的是
@import
引入进去的css,它被放在了最上面,其次才是index.css
。 - 新需求又来了,如果我在
/src/index.html
中的head
标签中写一些样式,编译后会在什么位置?
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
background: #000;
}
</style>
</head>
- 可以看到,我们写的是会在最上面的,有时候我们不希望自己写的样式被放在最上面而被覆盖,这时候我们可以再添加点配置即可,上面说了,可以写成对象形式,因为写成对象形式可以进行参数传递。
use:
[
{
loader: 'style-loader',
options: {
insert: function insertAtTop(element) {
var parent = document.querySelector('head');
// eslint-disable-next-lno-underscore-dangle
var lastInsertedElement = window._lastElementInsertedByStyleLoader;
if (!lastInsertedElement) {
parent.insertBefore(element, parfirstChild);
} else if (lastInsertedElement.nextSibling) {
parent.insertBefore(elemelastInsertedElement.nextSibling);
} else {
parent.appendChild(element);
}
// eslint-disable-next-lno-underscore-dangle
window._lastElementInsertedByStyleLoadeelement;
},
}
},
{loader:'css-loader'}
]
- 之前是通过配置
insertAt:'top'
来实现放到顶部,后来这个方法被废弃了,现在改成了insert
。
编译less
- 首先先在
/src/index.html
写点东西:
<div class="box">
<p>hello word</p>
</div>
- 然后在
/src
目录下建立一个less文件:index.less
.box{
width: 100px;
height: 100px;
margin: 0 auto;
p{
color:#ff6700;
}
}
- 在
/src/index.js
中引入一下:
require('./index.less')
- 最后配置一下,先匹配一下
less
,然后再最下面加上less-loader
即可。
{
test:/.less$/,
use:[
{
loader: 'style-loader',
options: {
insert: function insertAtTop(element) {
var parent = document.querySelector('head');
// eslint-disable-next-line no-underscore-dangle
var lastInsertedElement =
window._lastElementInsertedByStyleLoade
if (!lastInsertedElement) {
parent.insertBefore(element, parent.firstChild);
} else if (lastInsertedElement.nextSibling) {
parent.insertBefore(element, lastInsertedElement.nextSibling);
} else {
parent.appendChild(element);
// eslint-disable-next-line no-underscore-dangle
window._lastElementInsertedByStyleLoader = element;
},
}
},
{loader:'css-loader'},//解析@import语法
{loader:'less-loader'},//解析less
]
}
- 重新启动项目,就可以看到,我们的less被正常解析。
抽离css
- 有时候我们不希望把style样式放到head标签里面,而是希望link引入,这时候我们也可以借助一些插件来完成
- 安装:
npm add mini-css-extract-plugin -D
- 打开
webpack.config.js
,引入插件:
let MiniCssExtractPlugin=require('mini-css-extract-plugin');
- 然后在
plugins
中进行一下配置:
plugins:[
new MiniCssExtractPlugin({
filename:'main.css'
})
],
- 同时因为之配置了解析css相关模块,这时候可以再进行改造一下,解析完成再调用
MiniCssExtractPlugin.loader
module:{//模块
rules:[
{
test:/.css$/,
use:[
MiniCssExtractPlugin.loader,
{loader:'css-loader'},
]
},
{
test:/.less$/,
use:[
MiniCssExtractPlugin.loader,
{loader:'css-loader'},
{loader:'less-loader'},//解析less
]
}
]
}
- 然后执行一下打包:
npm run build
- 可以看到在
/dist
目录下生成了main.css - 如果需要打包成不同的文件,只需要声明多个,然后使用。
浏览器兼容
- 有时候我们需要css兼容各种浏览器,平时可能还得翻阅查看,比较麻烦,这里我们也可以使用
postcss-loader autoprefixer
首先在/src/index.css
中,给body元素添加点样式:
body,html{
transform: rotate(45deg);
}
- 安装一下插件:
npm add postcss-loader autoprefixer -D
- 在根目录下创建
postcss.config.js
,导入插件:
module.exports = {
plugins: [
require('autoprefixer')
]
};
- 然后配置
webpack.config.js
module:{
rules:[
{
test:/.css$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js' // 引入文件
}
}
},
]
},
{
test:/.less$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js' // 引入文件
}
}
},
'less-loader',
]
}
]
}
- 还可以在
package.json
中添加浏览器支持:
"browserslist": [
"defaults",
"not ie < 11",
"last 2 versions",
"> 1%",
"iOS 7",
"last 3 iOS versions"
]
- 重新启动打包
npm run build
- 打开
dest/main.css
,可以看到,已经帮我们加好了浏览器前缀。
优化css资源
- 首先安装
npm add optimize-css-assets-webpack-plugin -D
- 具体文档可以看这里 文档
- 然后打开
webpack.config.js
,导入模块,添加优化项
let optimizeCss=require('optimize-css-assets-webpack-plugin')
module.exports={
optimization:{//优化项
minimizer:[
new optimizeCss()
]
},
}
- 先执行打包看一下效果:
- 我们的css已经被压缩,但很奇怪,我们打开js文件看一下,发现我们的js文件没被压缩
- 因为一旦使用了这个插件,js就不会被压缩,这个还得安装一个插件进行处理
npm add uglifyjs-webpack-plugin -D
- 在
webpack.config.js
中引入并配置:
let uglifyjsPlugin=require('uglifyjs-webpack-plugin')
module.exports={
optimization:{//优化项
minimizer:[
new uglifyjsPlugin({
cache:true,//是否缓存
parallel:true,//是否并发打包
sourceMap:true
}),
new optimizeCss()
]
},
}
- 执行打包,会发现一个报错,如下
- 这里先挖一个坑,等后几篇文章说一下。如果想正常打包,可以把之前
src/index.js
文件里面的js清除一下 - 再次打包,可以看到,项目正常运行。
总结
❝ 本篇文章讲了如何模块化的引入css,css-loader
与style-loader
的使用,以及配置选项,其中style-loader中本来配置insertAt
来设置css文件放到哪里,结果发现有报错,后来查了一下,原来已经被废弃了,可以通过insert
来设置。
通过less-loader
可以进行解析,用法还是比较简单的。 通过mini-css-extract-plugin
可以抽离css。 通过postcss-loader autoprefixer
来进行自动填充浏览器前缀。 通过optimize-css-assets-webpack-plugin
来优化css资源。 写作不易,点赞收藏支持一下吧!
也可以关注我的专栏:LonJin的知乎专栏
❞
- 参考文档:style-loader