0 Like
React 配置全局 Sass 和 CSS Module

React 配置全局 Sass 和 CSS Module

4 PV0 LikeReact
接下来的业余时间要做个人博客 Wap 端,这次打算尝试一下 TypeScript、持续集成、自动化等以前没有实践过的技术栈...当然大前提还是要把架子搭好,上次记录了一下 Vue 配置全局 Sass 变量的方法,这次把 React 的配置方法记录一下,显然比 Vue-cli 麻烦了一些。

前提

一开始本来打算用微软的TypeScript-React-Starter来创建脚手架,正好省了初始化TypeScript那一套,但是这个 CLI 貌似对CSS Mudule配置不是支持得很好,看了社区一些 hack 方法感觉也不太好用。遂还是用create-react-app创建一个 React 工程,然后把TypeScript-React-Starter的配置拷了过来。

以前用React-app-rewired去给 webpack 添加配置,但总有种隔靴搔痒的感觉,这次决定yarn eject这个工程。

src目录下创建assets文件夹,然后在assets文件夹里创建一个styles文件夹,添加一个 sass 文件叫_color.scss,里面先简单加几个颜色变量,以备测试:

$white: #fff;
$black: #000;
$gray: #666;

下面先说怎么做 CSS Module,然后再往全局 Sass 迁移。

CSS Module

安装配置

首先安装依赖:

yarn add node-sass

使用create-react-app默认会创建一个App.jsApp.css,我们需要将App.css重命名为App.module.css

这点非常关键,只要想做CSS Module,css 文件必须要改成*.module.css的形式。

然后打开App.js文件,引入App.module.css,可以发现引入 css 的方式也和以前不一样了,下面的styles名字随便起,看你个人喜好了:

import styles from './App.module.css';

这里我建议在 class 命名的时候,要以下划线的形式连接每个单词,比如App_common_logo,这也是鹅厂 aotu 实验室推荐的的命名方式,其实这样对使用 CSS Module 也有好处,一会儿会说到。

CSS Module使用图例
CSS Module使用图例

使用方法

关于使用方法,这里直接上图吧,实际上就是把以前的className="App_intro"变成了className={styles.App_intro}

我们回到上面 class 命名那个话题,如果你的类名叫做App-intro,那你就得写成className={styles['App-intro']},写多了项目也不清晰了。

我们再看一下 Dev Tool 的渲染情况:

渲染出来的类名
渲染出来的类名

这是 Webpack 的默认配置,默认就是模块名_类名__5位hash,好处一目了然,不会用重复的 class 了,我个人决定在开发环境直接使用 Webpack 的默认配置,在生产环境再做一些改变,打开config/webpack.config.prod.js文件,搜索关键字getLocalIndent,我个人打算 build 之后的类名直接是6位hash,所以配置如下图:

修改Webpack配置
修改Webpack配置

题外话

在使用 CSS Module 的过程中相信你一定会遇到其他的问题,比如一个标签如果有多个 class,以前可以写成className="App_icon App_select",但是 CSS Module 是不允许的,所以需要安装依赖yarn add classnames,使用方式如下:

import cs from 'classnames';

className={cs(styles.social_media_motto, styles.no_user_select)}

此外,如果你的模块里不得不操作 DOM,如果继续用className={styles.App_intro}的方式,document.querySelector('.App_intro')将不会如你所愿,因为此时的 Appintro 已经被被 hash 所“污染,因此你还是需要命名为`className="Appintro"这种形式`。

但是新的问题来了,你在App.mudule.css中给App_intro定义的任何样式将不会起作用,所以需要在 css 里做写文章:

:global(.App_intro) {
    outline: none;
    border-radius: 50%;
  }

Sass 全局变量、函数、Mixin...

如果定义了一个关于颜色变量的 Sass 文件,按以前的做法,那就得在每个模块的 Sass 文件中@import '../assets/styles/_color.scss',显然这种方式很不(e)科(xin)学。尤其在写移动端的时候,肯定得定义一些全局的函数,要是每个文件都要引一次,天啦噜...

首先安装依赖yarn add sass-resources-loader --dev,然后打开config/webpack.config.dev.js,注意是开发环境的 Webpack 配置文件。

检索关键词sass-loader,看下图:

配置全局Sass
配置全局Sass

下面把代码贴出来,注意一定是../src/assets/styles/_colors.scss',网上教程坑得一逼,全给写成./src/assets/styles/_colors.scss',结果一直报错。

use: [{
  loader: require.resolve('style-loader'),
},
{
  loader: require.resolve('css-loader'),
  options: {
    importLoaders: 2
  },
},
{
  loader: require.resolve('sass-loader'),
},
{
  loader: require.resolve('sass-resources-loader'),
  options: {
    resources: [path.resolve(__dirname, '../src/assets/styles/_colors.scss'), path.resolve(__dirname, '../src/assets/styles/_function.scss')],
  }
}],

因为我们做了 CSS Module,所以我们也要为 CSS Module 支持引入全局 Sass 变量。

为CSS Module配置全局Sass
为CSS Module配置全局Sass

这时我们将上面的App.mudule.css重命名为App.mudule.scss,然后随便找个 class 添加个颜色,发现生效了:

.App_header {
  display: flex;
  align-items: center;
  justify-content: center;
  color: $gray;
}

最后

在前几个月写 PC 端的博客前台时,已经用上了 CSS Module,但没去考虑全局 Sass 变量,这次也算是一次温故和知新吧。计划 Wap 端会用上 TypeScript,同构个 PWA 什么的,然后尝试用 Trvis 做持续集成和自动化部署,任重道远啊。

明天又要苦逼的加班去了,日了。

以上、よろしく。

聊一聊前端上传那些事

PREVIOUS POST

聊一聊前端上传那些事

React 单页应用添加 GA 埋点

NEXT POST

React 单页应用添加 GA 埋点

    Search by