Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

220 lines (167 sloc) 4.85 KB

Setup CSS modules for React Native (with Less support)

Following libraries are needed:

Step 1: Install depencies to run React Native

Make sure that you have react-native-cli installed (npm install -g react-native-cli) and XCode (for iOS development) / Android Studio (for Android development) installed and working.

Step 2: Create a new React Native app and test that it works

e.g.

react-native init AwesomeProject
cd AwesomeProject

Start packager:

yarn start

Run project on iOS simulator:

react-native run-ios

Step 3: Install dependencies for React Native CSS modules

yarn add babel-plugin-react-native-classname-to-style babel-plugin-react-native-platform-specific-extensions react-native-less-transformer less --dev

Step 4: Setup Babel configuration

For React Native v0.57 or newer

.babelrc (or babel.config.js)

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    "react-native-classname-to-style",
    [
      "react-native-platform-specific-extensions",
      {
        "extensions": ["less"]
      }
    ]
  ]
}

For React Native v0.56 or older

.babelrc

{
  "presets": ["react-native"],
  "plugins": [
    "react-native-classname-to-style",
    [
      "react-native-platform-specific-extensions",
      {
        "extensions": ["less"]
      }
    ]
  ]
}

For Expo

babel.config.js (older Expo versions use .babelrc)

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      "react-native-classname-to-style",
      ["react-native-platform-specific-extensions", { extensions: ["less"] }]
    ]
  };
};

Step 5: Setup Metro bundler configuration

For React Native v0.57 or newer / Expo SDK v31.0.0 or newer

Add this to metro.config.js in your project's root (create the file if you don't have one already):

const { getDefaultConfig } = require("metro-config");

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

If you are using Expo, you also need to add this to app.json:

{
  "expo": {
    "packagerOpts": {
      "config": "metro.config.js"
    }
  }
}

For React Native v0.56 or older

If you are using React Native without Expo, add this to rn-cli.config.js in your project's root (create the file if you don't have one already):

module.exports = {
  getTransformModulePath() {
    return require.resolve("react-native-less-transformer");
  },
  getSourceExts() {
    return ["js", "jsx", "less"];
  }
};

For Expo SDK v30.0.0 or older

If you are using Expo, instead of adding the rn-cli.config.js file, you need to add this to app.json:

{
  "expo": {
    "packagerOpts": {
      "sourceExts": ["js", "jsx", "less"],
      "transformer": "node_modules/react-native-less-transformer/index.js"
    }
  }
}

Step 6: Add some Less to your project and use it inside a React component

styles.less:

.container {
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: #f5fcff;
}

.blue {
  color: blue;
  font-size: 30px;
}

Add style import and BlueText component to App.js:

import React, { Component } from "react";
import { Text, View } from "react-native";
import styles from "./styles.less";

const BlueText = () => {
  return <Text className={styles.blue}>Blue Text</Text>;
};

export default class App extends Component<{}> {
  render() {
    return (
      <View style={styles.container}>
        <BlueText />
      </View>
    );
  }
}

Step 7: Restart packager and clear cache

Restart React Native packager and clear it's cache (important) to see the styles that you added.

yarn start --reset-cache
You can’t perform that action at this time.