MuYunyun/reactSPA

css 模块实践

MuYunyun opened this issue · 0 comments

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-loaderpostcss-loadercss-loaderstyle-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)