【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'],
}]
},
3.添加样式
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('h1');
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和下面的对应。
四、输出样式文件
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。

发现两个样式打包成了一个文件。只要内容发生了变化,样式的名称就会变化。更多配置可以移步https://www.npmjs.com/package/extract-text-webpack-plugin
参考:
https://www.npmjs.com/package/css-loader#local-scope
https://survivejs.com/webpack/styling/loading/
【webpack】-- 样式加载的更多相关文章
- Webpack模块加载器
一.介绍 Webpack是德国开发者 Tobias Koppers 开发的模块加载器,它能把所有的资源文件(JS.JSX.CSS.CoffeeScript.Less.Sass.Image等)都作为模块 ...
- Webpack的加载器
一.什么是加载器(loaders)loaders 用于转换应用程序的资源文件,他们是运行在nodejs下的函数 使用参数来获取一个资源的来源并且返回一个新的来源(资源的位置),例如:你可以使用load ...
- css样式加载顺序及覆盖顺序深入理解
注:内容转载 很多的新手朋友们对css样式加载顺序和覆盖顺序的理解有所偏差,下面用示例为大家详细的介绍下,感兴趣的朋友不要错过 { height: 100%; width: 200; position ...
- webpack常用加载器和插件
css文件加载器: style-loader,css-loader,sass-loader,less-loader //style和css加载器必须放在一起使用,且style必须放前面(style!c ...
- webpack中加载CSS
webpack强大之处在于可以将CSS当做一个资源模块进行管理和加载 基本使用: 安装webpack的加载插件style-loader和css-loader: npm install style-lo ...
- 使用webpack热加载,开发多页面web应用
我们一般使用webpack热加载开发SPA应用,但工作中难免会遇到一些多页面的demo或项目. 故参考 kingvid-chan 的代码,搭了一个使用HRM开发多页面web应用的脚手架,刚好也进一步学 ...
- css样式加载顺序
css样式加载顺序: A: id选择器指定的样式 > 类选择器指定的样式 > 元素类型选择器指定的样式 B: 如果要让某个样式的优先级变高,可以使用!important来指定: .clas ...
- Vue(基础七)_webpack(webpack异步加载原理)
---恢复内容开始--- 一.前言 1.webpack异步加载原理’ 2.webpack.ensure原理 ...
- 使用webpack loader加载器
了解webpack请移步webpack初识! 什么是loader loaders 用于转换应用程序的资源文件,他们是运行在nodejs下的函数 使用参数来获取一个资源的来源并且返回一个新的来源(资源的 ...
- django部署后样式加载不出来解决方案
django部署后样式加载不出来 1.html文件去掉<!DOCTYPE html> 2. location /static { alias /home/static/; } 3.STAT ...
随机推荐
- ubuntu vi编辑insert时上下左右建为ABCD
ubuntu 在vi编辑insert时上下左右建不能移动光标而是输出ABCD,backspace也不能起删除作用, 开始我退出insert模式就能够移动和删除了,不过这样太麻烦很不适应, 只要一次执 ...
- package.json 里 devDependencies和dependencies的区别
我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,比如: --save-dev --save 在 package.json 文件里面 ...
- php中二维数组如何使用
最近需要使用PHP中的二维数组,就用一个简单的例子来说明PHP中二数组是如何使用 <?php $a=array('a','b','c'); $c=array('a1','b1','c1'); $ ...
- ImageView及其子类(二)
实例:强大的图片按钮 下面的实例定义了多个图片按钮,并定义了两个ZoomButton.两个ZoomButton的android:src属性分别指定为@android:drawable/btn_minu ...
- 第二部分 条件控制执行语句、循环语句、switch语句、跳转语句和其它语句
条件控制执行语句: if语句 if....else....语句 循环语句: while语句 do....while语句 for语句 switch语句: 跳转语句: break; continue; r ...
- C# 程序只能执行一次
应用程序的主入口点. //每一个程序只能运行一个实例 bool isRun = false; System.Threading.Mutex m = new System.Threading.Mutex ...
- yum安装CDH5.5 Hadoop集群
1.环境说明 系统环境: 系统环境:centos6.7 Hadoop版本:CDH5.5 JDK运行版本:1.7.0_67 集群各节点组件分配: 2.准备工作 安装 Hadoop 集群前先做好下面的准备 ...
- [C#]为微软ASP.NET官方教学视频增加字幕
前言 Microsoft Virtual Academy提供了学习ASP.NET的大量视频材料.(注1) 由于视频服务器位于海外,国内浏览速度并不理想,幸好官方提供了视频的下载地址以及英文字幕文件. ...
- MySQL插入数据中文乱码问题的解决
一.使用语句 show variables like 'character%'; 来查看当前数据库的相关编码集. 1.启动cmd,登录mysql ①cd C:\Program Files\MySQL\ ...
- pwnable.kr-collision -Writeup
bof html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addres ...