webpack的样式加载详解
这次给大家带来webpack的样式加载详解,webpack样式加载的注意事项有哪些,下面就是实战案例,一起来看一下。
加载css需要用到css-loader和style-loader css-loader将@import 和 url 处理成正规的ES6 import ,如果@import指向的是一个外部资源,css-loader会跳过,而只会对内部资源做处理。css-loader处理之后,style-loader会将输出的css注入到打包文件中。css默认是inline模式,且实现了HMR接口。但inline不太适用于生产环境(全部输出在页面上)。还需要用extracttextplugin生成一个单独的css文件,但先一步一步来。
一,样式打包
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%); p { .box-shadow(0 0 5px, 30%) }} body { background: cornsilk; }
修改index.js
import './less.less'; import component from './component';var ele=document.createElement("p"); 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中创建一个p元素并给它添加redbutton样式。
import './main.css';import styles from './other.css';import component from './component';var ele=document.createElement("p"); 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("p"); ele.innerHTML="this is an shadowButton button";console.log(styles); ele.className=styles.shadowButton; document.body.appendChild(ele);
看一下是什么效果:
日志打印出来的是styles对象,它包含了两个类名。可以看见shadowButton是由两个类名组合而成的。p的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("p"); 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; }) }
View Code
引入了两个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。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是webpack的样式加载详解的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Windows操作系统是全球最流行的操作系统之一,其新版本Win11备受瞩目。在Win11系统中,管理员权限的获取是一个重要的操作,管理员权限可以让用户对系统进行更多的操作和设置。本文将详细介绍在Win11系统中如何获取管理员权限,以及如何有效地管理权限。在Win11系统中,管理员权限分为本地管理员和域管理员两种。本地管理员是指具有对本地计算机的完全管理权限

OracleSQL中的除法运算详解在OracleSQL中,除法运算是一种常见且重要的数学运算操作,用于计算两个数相除的结果。除法在数据库查询中经常用到,因此了解OracleSQL中的除法运算及其用法是数据库开发人员必备的技能之一。本文将详细讨论OracleSQL中除法运算的相关知识,并提供具体的代码示例供读者参考。一、OracleSQL中的除法运算

PHP中的模运算符(%)是用来获取两个数值相除的余数的。在本文中,我们将详细讨论模运算符的作用及用法,并提供具体的代码示例来帮助读者更好地理解。1.模运算符的作用在数学中,当我们将一个整数除以另一个整数时,会得到一个商和一个余数。例如,当我们将10除以3时,商为3,余数为1。模运算符就是用来获取这个余数的。2.模运算符的用法在PHP中,使用%符号来表示模

Linux系统调用system()函数详解系统调用是Linux操作系统中非常重要的一部分,它提供了一种与系统内核进行交互的方式。其中,system()函数是一个常用的系统调用函数之一。本文将详细介绍system()函数的使用方法,并提供相应的代码示例。系统调用的基本概念系统调用是用户程序与操作系统内核交互的一种方式。用户程序通过调用系统调用函数来请求操作系统

C语言作为一门广泛应用在软件开发领域的编程语言,是很多程序员初学者的首选。学习C语言不仅可以帮助我们建立编程的基础知识,还可以提升我们解决问题和思考的能力。本文将详细介绍一条C语言学习的路线图,帮助初学者更好地规划自己的学习进程。1.学习基本语法在开始学习C语言之前,我们首先需要了解C语言的基本语法规则。这包括变量和数据类型、运算符、控制语句(如if语句、

Linux的curl命令详解摘要:curl是一种强大的命令行工具,用于与服务器进行数据通信。本文将介绍curl命令的基本用法,并提供实际的代码示例,帮助读者更好地理解和应用该命令。一、curl是什么?curl是一个命令行工具,用于发送和接收各种网络请求。它支持多种协议,如HTTP、FTP、TELNET等,并提供了丰富的功能,如文件上传、文件下载、数据传输、代

Cockpit是一个面向Linux服务器的基于Web的图形界面。它主要是为了使新用户/专家用户更容易管理Linux服务器。在本文中,我们将讨论Cockpit访问模式以及如何从CockpitWebUI切换Cockpit的管理访问。内容主题:驾驶舱进入模式查找当前驾驶舱访问模式从CockpitWebUI启用Cockpit的管理访问从CockpitWebUI禁用Cockpit的管理访问结论驾驶舱进入模式驾驶舱有两种访问模式:受限访问:这是驾驶舱的默认访问模式。在这种访问模式下,您不能从驾驶舱Web用户

Promise.resolve()详解,需要具体代码示例Promise是JavaScript中一种用于处理异步操作的机制。在实际开发中,经常需要处理一些需要按顺序执行的异步任务,而Promise.resolve()方法就是用来返回一个已经Fulfilled状态的Promise对象。Promise.resolve()是Promise类的一个静态方法,它接受一个
