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 2891 Strange Way to Express Integers【扩展中国剩余定理】
扩展中国剩余定理板子 #include<iostream> #include<cstdio> using namespace std; const int N=100005; ...
- Ubuntu开机之后报错结局方法
sudo gedit /etc/default/apport 把里面的enabled=1改成enabled=,保存 201. 就是下雨也去.202. 我马上拿来.203. 孙英开飞机.204. 国华来 ...
- hdu1232 畅通工程 基础并查集
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> ...
- new delete 创建回收细节
- [HNOI2018]毒瘤
Description 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(比如区间加一个数,或者区间开平方),并支持询问区间和 ...
- Educational Codeforces Round 18 D
Description T is a complete binary tree consisting of n vertices. It means that exactly one vertex i ...
- Folding UVA - 1630
题目 ans[i][j]表示由原串第i个字符到第j个字符组成的子串的最短折叠长度如果从i到j本身可以折叠,长度就是本身长度或折叠后的长度的最小值***此处参考:http://blog.csdn.net ...
- 167 Two Sum II - Input array is sorted 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数.函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2.请注意,返回的下标值(i ...
- Nginx缓存[proxy cache、memcache]
nginx自带缓存 nginx自己有单独的进程来对磁盘上的缓存文件进行扫描,在内存中建立缓存索引.并且有管理进程来对缓存进行过期判断,更新等操作 定义:只能在http段中使用 proxy_cache_ ...
- Asp.net 字符(一)
1.字母大小写处理 private string GetChangedStr(string oldStr, strType type) { string newStr = ""; ...