如何在 React Native 中使用 CSS Modules

有些前端工程师希望也能像开发 web 应用那样,使用 CSS Modules 来开发 React Native。本文将介绍如何在 React Native 中使用 CSS Modules。

安装依赖和配置

首先安装 react-native-sass-transformeropen in new window 使得我们可以在 React Native 应用中使用 sass 样式。

yarn add react-native-sass-transformer sass -D

参考如下配置,修改 metro.config.js 文件

const { getDefaultConfig } = require('metro-config')

module.exports = (async () => {
  const {
    resolver: { sourceExts },
  } = await getDefaultConfig()
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-sass-transformer'),
    },
    resolver: {
      sourceExts: [...sourceExts, 'scss', 'sass'],
    },
  }
})()

我们还需要安装另外两个依赖

yarn add babel-plugin-react-native-classname-to-style \
  babel-plugin-react-native-platform-specific-extensions -D

修改 babel.config.js 文件,配置刚刚安装的两个插件

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    'react-native-classname-to-style',
    [
      'react-native-platform-specific-extensions',
      {
        extensions: ['scss', 'sass'],
      },
    ],
  ],
}

因为我们的项目使用了 Typescript,为了避免类型警告,在项目中添加一个 global.d.ts 文件,内容如下

declare module '*.scss'

使用

React Native CSS Modules 支持 $变量属性嵌套@mixin@include@extend%占位符 等操作

// App.scss
@import './theme/font.scss';

.welcome {
  font-family: $primary-font;
  font-size: 17px;
  text-align: center;
}

@mixin lightFontStyle($fontColor: rgb(0, 0, 0)) {
  font-size: 22px;
  font-family: $sencodary-font-light;
  letter-spacing: 0.96px;
  color: $fontColor;
}

.input {
  @include lightFontStyle($fontColor: rgb(39, 39, 39));
  padding: 12px 20px 40px;
  flex: 1;
}

.disabled {
  @extend .input;
  color: rgb(99, 99, 99);
}

CSS Modules 也可以很好的和 StyleSheet 一起工作,发挥各自所长。

//App.tsx
import React from 'react'
import { Text, StyleSheet } from 'react-native'
import scss from './App.scss'

function Welcome(props: Props) {
  return <Text style={[scss.welcome, styles.text]}>Hello {props.name}!</Text>
}

const styles = StyleSheet.create({
  text: {
    backgroundColor: 'transparent',
    margin: 8,
  },
})

示例

这里有一个示例open in new window,供你参考。

上次更新: