本篇文章为大家展示了怎么在webpack中实现样式加载,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
一,样式打包
1.安装css-loader,style-loader
npm install css-loader style-loader --save-dev
2.修改webpack.config.js增加一个一级子节点
module:{
rules:[{
test:/\.css$/,
use: ['style-loader', 'css-loader'],
}]
},
test的正则会匹配.css的文件。use中的执行顺序是从右到左。loader的执行是连续的,就像管道一样,先到css-loader再到style-loader。loaders: ['style-loader', 'css-loader'] 可以理解为:styleloader(cssloader(input)) 。
3.添加样式
app/mian.css
body {
background: cornsilk;
}
然后在index.js中引入
import './main.css';
再运行npm start,在http://localhost:8080/中打开
这时候页面出现了背景色,而且发现样式写入了header中,这个时候你改变颜色,界面也会无刷新的更新,这正是上一节HMR的效果。
样式也是通过webpackHotUpdate方法进行更新。
二、加载less
再看一下如何加载less,先安装less-loader
npm install less less-loader --save-dev
再修改配置文件:
module:{
rules:[{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
}]
},
然后建立一个less文件。less.less
@base: #f938ab;
.box-shadow(@style, @c) when (iscolor(@c)) {
-webkit-box-shadow: @style @c;
box-shadow: @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
.box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box {
color: saturate(@base, 5%);
border-color: lighten(@base, 30%);
div { .box-shadow(0 0 5px, 30%) }
}
body {
background: cornsilk;
}
修改index.js
import './less.less';
import component from './component';
var ele=document.createElement("div");
ele.innerHTML="this is an box";
ele.className="box";
document.body.appendChild(ele);
let demoComponent=component();
document.body.appendChild(demoComponent);
得到效果:
可以看见编译成功,要注意的是,再使用less的时候import只能是less文件,这个时候再import main.css会报错。这一节对less就做一个简单的演示,其他样式预处理器同理,下面的内容还是继续基于css。
三、理解css作用域和css 模块
一般来说css的作用域都是全局的,我们常在母版页里面添加了多个样式文件,后面的样式文件会覆盖前面的样式文件,常常给我们的调试带来麻烦。而CSS Modules通过import引入了本地作用域。这样能够避免命名空间冲突。webpack的css-loader是支持CSS Modules的,怎么理解呢,先看几个例子。我们先在配置中开启(先关掉HMR):
module:{
rules:[{
test:/\.css$/,
use: ['style-loader', {
loader: 'css-loader',
options: {
modules: true,//让css-loader支持Css Modules。
},
},],
然后定义一个新的样式(main.css):
body {
background: cornsilk;
}
.redButton {
background: red;color:yellow;
}
给component加一个样式,先引入main.css。
import styles from './main.css';
export default function () {
var element = document.createElement('h2');
element.className=styles.redButton;
element.innerHTML = 'Hello webpack';
return element;
}
这个时候我们看到界面已经变化了。
再看右边生成的样式,我们的样式名称已经发生了改变。回顾整个过程相当于main.css中的每一个类名成了一个模块,在js中可以像获取模块一样的获取。但是你可能想,为毛我不能直接给元素赋值,干嘛要import呢。这是个好问题,我们再新增一个样式
不同样式文件的同名类
other.css
.redButton {
background:rebeccapurple;color:snow;
}
它也有一个.redbutton的类(但效果是紫色的),然后在index.js中创建一个div元素并给它添加redbutton样式。
import './main.css';
import styles from './other.css';
import component from './component';
var ele=document.createElement("div");
ele.innerHTML="this is an other button";
ele.className=styles.redButton;
document.body.appendChild(ele);
let demoComponent=component();
document.body.appendChild(demoComponent);
再看效果
上面这个图说明了两问题,一个是我们在index.js中引入了2个样式文件,在index页面就输出了两个style,这让人有点不爽,但我们后面再解决。另外一个就是虽然两个样式文件中都有redButton这个类,但是这两者还是保持独立的。这样就避免了命名空间的相互干扰。如果你这个时候直接赋值
element.className="redButton";
这样是获取不到样式的。直接对元素的样式默认是全局的。
全局样式
如果想让某个样式是全局的。可以通过:global来包住。
other.css
:global(.redButton) {
background:rebeccapurple;color:snow;
border: 1px solid red;
}
main.css
:global(.redButton) {
background: red;color:yellow;
}
这个时候redbutton这两个样式就会合并。需要直接通过样式名来获取。
element.className="redButton";
组合样式
我们再修改other.css,创建一个shadowButton 样式,内部通过composes组合redbutton类。
.redButton {
background:rebeccapurple;color:snow;
border: 1px solid red;
}
.shadowButton{
composes:redButton;
box-shadow: 0 0 15px black;
}
修改index.js:
var ele=document.createElement("div");
ele.innerHTML="this is an shadowButton button";
console.log(styles);
ele.className=styles.shadowButton;
document.body.appendChild(ele);
看一下是什么效果:
日志打印出来的是styles对象,它包含了两个类名。可以看见shadowButton是由两个类名组合而成的。div的class和下面的对应。
四、输出样式文件
css嵌在页面里面不是我们想要的,我们希望能够分离,公共的部分能够分开。extracttextplugin 可以将多个css合成一个文件,但是它不支持HMR(直接注释掉hotOnly:true)。用在生产环境挺好的
npm install extract-text-webpack-plugin --save-dev
先安装extracttextplugin这个插件,然后再webpack.config.js中进行配置:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractTxtplugin = new ExtractTextPlugin({
filename: '[name].[contenthash:8].css',
});
const commonConfig={
entry: {
app: PATHS.app,
},
output: {
path: PATHS.build,
filename: '[name].js',
},
module:{
rules:[{
test:/\.css$/,
use:extractTxtplugin.extract({
use:'css-loader',
fallback: 'style-loader',
})
}]},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo',
}),
extractTxtplugin
],
}
一开始看到这个配置,让人有点懵。首先看fileName,表示最后输出的文件按照这个格式'[name].[contenthash:8].css',name默认是对应的文件夹名称(这里是app),contenthash会返回特定内容的hash值,而:8表示取前8位。当然你也可以按照其他的格式写,比如直接命名:
new ExtractTextPlugin('style.css')
而ExtractTextPlugin.extract本身是一个loader。fallback:'style-loader'的意思但有css没有被提取(外部的css)的时候就用style-loader来处理。注意到现在我们的index.js如下:
import './main.css';
import styles from './other.css';
import component from './component';
var ele=document.createElement("div");
ele.innerHTML="this is an box";
ele.className=styles.shadowButton;
document.body.appendChild(ele);
let demoComponent=component();
document.body.appendChild(demoComponent);
//HMR 接口
if(module.hot){
module.hot.accept('./component',()=>{
const nextComponent=component();
document.body.replaceChild(nextComponent,demoComponent);
demoComponent=nextComponent;
})
}
引入了两个css文件。
这个时候我们执行 npm run build
再看文件夹得到一个样式文件。(如果不想看到日志可以直接npm build)
但是我们在第三部分使用了CSS Modules,发现other.css的样式没有打包进来。所以,我们的webpack.config.js还要修改:
module:{
rules:[{
test:/\.css$/,
use:extractTxtplugin.extract({
use:[ {
loader: 'css-loader',
options: {
modules: true,
},
}],
fallback: 'style-loader',
})
}]},
再次build。
上述内容就是怎么在webpack中实现样式加载,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。