css 模块实践
MuYunyun opened this issue · 0 comments
MuYunyun commented
css-loader
来看下面这一组 webpack 的配置项,
{
test: /\.less$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
modules: true, // 开启 css 模块化
importLoaders: 2,
},
},
{
loader: require.resolve('postcss-loader'),
options: {...},
},
{
loader: require.resolve('less-loader'),
options: {...},
},
],
},
它们执行顺序是 less-loader
、postcss-loader
、css-loader
、style-loader
。我们来理一下各 module 的作用:
- less-loader: 将 less 解析为 css
- postcss-loader: 将 css 兼容各浏览器加上相应前缀
- css-loader: 将 css 转化为 common.js 模块
- style-loader: 将 common.js 模块注入
style
标签中
实践代码如下所示
import 'styles' from 'index.less'
<Layout className={styles.containAll}>...</Layout>
.containAll {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
.github {...}
.author {...}
.white {...}
.menu {...}
.switch {...}
}
}
编译后结果为
<div class="_2xsOSdvdJbkVjqgjHOE58l">...</div>
<style type='text/css'>
._2xsOSdvdJbkVjqgjHOE58l {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
</style>
通过 _2xsOSdvdJbkVjqgjHOE58l
锁定作用域
但是这种方式有一个缺陷,因为 JavaScript 是不识别连接符的,所以如果类名必须写成驼峰式的。如下这样写它就会编译报错:
import 'styles' from 'index.less'
<Layout className={styles.contain-all}>...</Layout>
为了更大的普适性,我们来看下面一种方案:
react-css-modules
它的本质是一个高阶组件,目前文档上已经说明不再维护(因为影响了运行时的性能)。
babel-plugin-react-css-modules
目前在 less 中使用有 bug,参见 https://github.com/gajus/babel-plugin-react-css-modules/issues/165,正在跟进。
使用动态引入语法 import()
可以参考 压缩打包优化实践,使用这种方案,也做到了当前模块只展示相应引入的 css(本质也是 style)