css module
后面项目地址:https://github.com/947133297/lwj-webpack-demo
关键是打开这一行,表示开启loader的css module功能:
{ test: /\.css$/, loader: 'style-loader!css-loader?modules' },
style-loader :用于创建style标签
css-loader:使css文件用起来像组件一样,允许require css进来,还可以启用css module功能
局部作用域测试
border.css
body {
border: 10px solid darkmagenta;
}
.qwe{
border: 10px solid black;
}
#eee{
border: 10px solid green;
}
.outer .inner{
border: 10px solid red;
}
app.css
body {
background-color: blue;
}
:global(.qwe){
font-size: 40px;
}
#eee{
color: aqua;
}
.outer .inner{
font-weight:;
}
入口js文件
require('./app.css');
var other1 = require('./border.css');
// Cannot read property 'inner' of undefined
// var html1 = '<div class="'+other1.outer.inner+'">other1</div>';
var html1 = '<div class="'+other1.outer+'"><div class="'+other1.inner+'">border test1</div></div>';
var html2 = '<div class="'+other1.qwe+'">border test2</div>';
var html3 = '<div id='+other1.eee+'>border test id</div>';
document.write(html1);
document.write(html2);
document.write(html3);
打包后的文件中有两段这样的代码(导出的标识符是base64生成的,转换前的字符串与路径和文件名相关):
exports.locals = {
"eee": "_3omJ4gpO6T45EFo0ZOMzz3",
"outer": "_2R2TiJtwoE2Ka6dR0UXOk1",
"inner": "_2Zm3l9VFNoYdhD18zUhAsL"
};
//...
exports.locals = {
"qwe": "qhJc-oYXMZ34_XRr59Qtz",
"eee": "_2EWJ0p0M9i7zNLMpM4YhOW",
"outer": "_1wB3wnxbesTSl4WbD-h9aP",
"inner": "_136k_jaRt4SbXZzJIe6J6O"
};
运行效果:
<style type="text/css">
body {
background-color: blue;
}
.qwe{
font-size: 40px;
}
#_3omJ4gpO6T45EFo0ZOMzz3{
color: aqua;
}
._2R2TiJtwoE2Ka6dR0UXOk1 ._2Zm3l9VFNoYdhD18zUhAsL{
font-weight: 900;
}
</style>
<style type="text/css">
body {
border: 10px solid darkmagenta;
}
.qhJc-oYXMZ34_XRr59Qtz{
border: 10px solid black;
}
#_2EWJ0p0M9i7zNLMpM4YhOW{
border: 10px solid green;
}
._1wB3wnxbesTSl4WbD-h9aP ._136k_jaRt4SbXZzJIe6J6O{
border: 10px solid red;
}
</style>
<body>
<div class="_1wB3wnxbesTSl4WbD-h9aP">
<div class="_136k_jaRt4SbXZzJIe6J6O">border test1</div>
</div><div class="qhJc-oYXMZ34_XRr59Qtz">border test2</div>
<div id="_2EWJ0p0M9i7zNLMpM4YhOW">border test id</div>
<h1>Hello World</h1>
<span class="qwe">3333</span>
<span id="eee">4444</span>
<div class="outer">
<div class="inner">
bold
</div>
</div>
</body>
结论:
- 只要require了一个css,这个css会被预处理成css module(前提是打开了css-loader的module参数),然后添加由style-loader把处理后的内容到html中
- 预处理的过程会把css中所有自定义的标识符(除标签选择符、以及global修饰外),都进行编码处理成另一个一一对应的标识符(猜测编码的主体包括选择符和文件名),这样被添加进html之后,虽然都是全局作用的,但不同css module之间同名的选择符会被编码成不同的标识,也就互不影响,就达到了“作用域”的目的了
- 在js中使用的时候,可以通过导入的模块来获取转换后的标识符,从而为dom动态使用不同css module中样式
- 以组件的概念来理解这里的应用场景,一个组件依赖于css,对这个css进行module预处理后,然后在js中动态获取预处理后标识,应用组件中样式。这样一来,组件间的样式就不会互相影响了。可见,要达到这样的目的,必须要动态处理样式,因为html中的类、id等不会被进行预处理。
组合class
dep.css
.depclass{
color: darkmagenta;
}
combine.css
.red{
background-color: red;
}
.content{
composes: red;
composes: depclass from './dep.css';
border: 2px solid #000;
}
入口文件添加如下代码:
var c = require('./combine.css');
var html4 = '<div class="'+c.content+'">compose test</div>';
document.write(html4);
bundle.js有如下两段代码:
exports.locals = {
"depclass": "_3o2XDTxGMaBRvs2mRiV1es"
};
//...
exports.locals = {
"red": "_1KvM5G6-rmsDcUM_AatNkH",
"content": "_3oH95_iAzM0qUNDaF3GCxv _1KvM5G6-rmsDcUM_AatNkH " + __webpack_require__(2).locals["depclass"] + ""
};
运行结果
<style type="text/css">
._1KvM5G6-rmsDcUM_AatNkH{
background-color: red;
}
._3oH95_iAzM0qUNDaF3GCxv{
border: 2px solid #000;
}
</style>
<style type="text/css">
._3o2XDTxGMaBRvs2mRiV1es{
color: darkmagenta;
}
</style>
<div class="_3oH95_iAzM0qUNDaF3GCxv _1KvM5G6-rmsDcUM_AatNkH _3o2XDTxGMaBRvs2mRiV1es">compose test</div>
结论:
- 这次测试依赖了2个css,但运行的时候,发现只请求了一个bundle.js,而没有请求这两个css,是因为这两个css中的全部内容都打包到bundle.js中了。这就是webpack一个非常大的优点,组件化,减少网络请求次数
- 被间接依赖的css,虽然没有在入口文件中调用require,但它的内容也被处理进来了,可见被require的css,中依赖了其他的css,这一系列的css都会被处理进来
- compose提供一种简便的多个类的书写方式,支持组合当前文件中以及外部文件中的类;不用compose的话,自己在js中引用,然后拼接类名,再写到dom上也是没问题,如果要用到外部其他文件的话,还要自己去require,麻烦了些而已
- 被引用的不管是直接引用(require)或者间接引用(compose),都会把这个被引用的文件内容全部加载进来
scss
修改配置文件如下:
loaders:[
{ test: /\.s?css$/, loader: 'style-loader!css-loader?modules!sass-loader' },
]
1.scss:
$primaryColor: #333;
.s1{
background: $primaryColor;
composes: s1 from './2.scss';
}
2.scss:
$borderColor: red;
.s1{
border: 1px solid $borderColor;
}
入口文件:
var s = require('./scss/1.scss');
var html5 = '<div class="'+s.s1+'">scss test</div>';
document.write(html5);
打包:
exports.locals = {
"s1": "_2KqHQfE-Ms43DCsHA7wfbk"
};
exports.locals = {
"s1": "EhwNnMc7oenHygrKydr1t " + __webpack_require__(3).locals["s1"] + ""
};
运行结果:
<style type="text/css">
$borderColor: red;
._2KqHQfE-Ms43DCsHA7wfbk{
border: 1px solid $borderColor;
}
</style>
<style type="text/css">
.EhwNnMc7oenHygrKydr1t {
background: #333;
}
</style>
<div class="EhwNnMc7oenHygrKydr1t _2KqHQfE-Ms43DCsHA7wfbk">scss test</div>
结论:
compose进来的scss,并没有被scss-loader所处理。所以如果要实现相关的引入功能,就只能用scss中的引入语法了。compse仅仅支持css
link和import的区别:
- Link是标签、import是css提供的一种方式
- 兼容问题,link无兼容问题,import在IE5以上才支持
- 可以使用js去控制link(因为是标签),却控制不了import
- 页面中多个link标签可以并行下载,而 如果有 import,则阻塞其他样式表的下载,影响并行性,参考https://stackoverflow.com/questions/10036977/best-way-to-include-css-why-use-import
css module的更多相关文章
- Vue中scoped css和css module比较
scoped css 官方文档 scoped css可以直接在能跑起来的vue项目中使用. 使用方法: <style scoped> h1 { color: #f00; } </st ...
- 同时使用antd和css module
同时编译antd和css module,需要设置两次less识别. { test: /\.less$/, exclude: path.resolve(__dirname, './node_module ...
- webpack项目轻松混用css module
前言 本文讲述css-loader开启css模块功能之后,如何与引用的npm包中样式文件不产生冲突. 比如antd-mobilenpm包的引入.在不做特殊处理的前提下,样式文件将会被转译成css mo ...
- 如使用Typescript撸Vue(Vue2 + TS +TSX+CSS module)
Vue对TS的支持一致不太好,连Vue作者尤大也自嘲真香压错了宝.期待Vue3.0会用TS重构且会有较大改进.不过目前有一些第三方的库可以曲线优化对TS的支持.主要就介绍下过下面两个库来写Vue. 总 ...
- [React] {svg, css module, sass} support in Create React App 2.0
create-react-app version 2.0 added a lot of new features. One of the new features is added the svgr ...
- vue css module
步骤 module <style> -> <style module> class='header' -> :class='$style.header' <t ...
- create-react-app 构建的项目使用 css module 方式来书写 css
先 yarn eject 释放出来配置文件具体参见我之前写过相关的文章(这里不再重复), 找到 config 文件夹下的文件如下图所示: 找到如图所示的配置: 书写 css 的文件名例如(App.mo ...
- CSS Module解决全局或本地使用@keyframes无效问题
最近使用CSSModule开发react项目,遇到一个问题,使用@keyframes无效,问题如下 /** less + css module **/ :global { .effect-bottom ...
- React项目中 使用 CSS Module
安装react-app-rewired 由于新的 react-app-rewired@2.x 版本的关系,还需要安装 customize-cra.但是我们这里不需要安装 react-app-rewir ...
随机推荐
- poj 1186 方程的解数【折半dfs+hash】
折半搜索,map会T所以用hash表来存状态 #include<iostream> #include<cstdio> #include<map> using nam ...
- python高级函数
1 函数 1.1 函数即变量 函数定义:把一个函数体作为变量赋值给一个函数名,同时函数体存放到内存中. 函数调用:根据函数名去内存中寻找对用的函数体,找到了就执行. >>> def ...
- 模拟+位运算 HDOJ 5491 The Next
题目传送门 题意:意思很简单,找一个最接近D且比D大的数,满足它的二进制表示下的1的个数在[S1, S2]之间 分析:从D + 1开始,若个数小于S1,那么从低位向高位把0替换成1直到S1就是最小值, ...
- 145 Binary Tree Postorder Traversal 二叉树的后序遍历
给定一棵二叉树,返回其节点值的后序遍历.例如:给定二叉树 [1,null,2,3], 1 \ 2 / 3返回 [3,2,1].注意: 递归方法很简单,你可以使用迭代方法来解 ...
- 合理设置apache的连接数及进程工作方式
网站在线人数增多,访问时很慢.初步认为是服务器资源不足了,但经反复测试,一旦连接上,不断点击同一个页面上不同的链接,都能迅速打开,这种现象就是说明apache最大连接数已经满了,新的访客只能排队等待有 ...
- 【C#】将数据库读出的数据转换为DataTable类型集合
return View(ConverDataReaderToDataTable(reader)); // 静态方法public static DataTable ConverDataReaderToD ...
- AJPFX简述Context.startService()和Context.bindService
Context.startService()和Context.bindService 服务不能自己运行,需要通过调用Context.startService()或Context.bindService ...
- Koa--基于Node.js平台的下一代web开发框架的安装
koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架. 使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函 ...
- (四)docker创建私人仓库
(一) 简介 仓库(Repository)是集中存放镜像的地方.仓库可以 被认为是一个具体的项目或目录.例如对于仓库地址 docker.sina.com.cn/centos:centos63 来说,d ...
- Python3基础教程(十七)—— Virtualenv
虚拟的 Python 环境(简称 venv) 是一个能帮助你在本地目录安装不同版本的 Python 模块的 Python 环境,你可以不再需要在你系统中安装所有东西就能开发并测试你的代码. 安装Vir ...