Nx: Question: how to integrate Tailwind in a React App?

Created on 6 Aug 2020  路  10Comments  路  Source: nrwl/nx

Description

I created a postcss.config.js with the following contents:

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

and in styles.scss :

@import "tailwindcss/base";

@import "tailwindcss/components";

@import "tailwindcss/utilities";

But the output is

@tailwind base;
@tailwind components;
@tailwind utilities;

and I tried some @apply statements but they don't work... any ideas?

react question / discussion

Most helpful comment

Right so I got the following to work for my React app, not sure if better than @nahue's solution but seems to do the trick.

Add a webpack-tailwind.config.js at the root of the repo, this will hold the rule to get postcss-loader to work.

const tailwindWebpackRule = {
  test: /\.scss$/,
  loader: 'postcss-loader',
};

exports.tailwindWebpackRule = tailwindWebpackRule;

Then also at the root, add a postcss.config.js with your postcss configuration. Here, you should import your tailwind config and any other postcss plugins.

const tailwindcss = require('tailwindcss');
module.exports = {
  plugins: [
    require('postcss-import'),
    tailwindcss('./tailwind.config.js'),
    require('autoprefixer'),
  ],
};

Then create a webpack.config.js at the root of your app and make sure you reuse all existing config and add yours on top of the existing nx rules.

const WebpackNotifierPlugin = require('webpack-notifier');
const nrwlConfig = require('@nrwl/react/plugins/webpack.js');
const webpackTailwindConfig = require('../../webpack-tailwind.config');

module.exports = (config, context) => {
  nrwlConfig(config);
  return {
    ...config,
    plugins: [
      ...config.plugins,
      new WebpackNotifierPlugin({ title: 'Readium build completed' }),
    ],
    module: {
      rules: [
        ...config.module.rules,
        webpackTailwindConfig.tailwindWebpackRule,
      ],
    },
  };
};

Lastly, point your workspace.json builder to the new custom config: "webpackConfig": "apps/<your-app>/webpack.config.js" and tailwind should build when you serve.

Any suggestions for improvement would be greatly appreciated but hopefully this helps those of you who are trying to figure out a way to get this to work 鈽猴笍

These references were helpful to me along the way:

All 10 comments

I created a custom webpack.ts file and added the following (but it feels to hacky)

```config.module.rules.forEach(rule => {
if (rule.test.toString().includes('scss')) {

  // Add PostCSS to modules.scss
  rule.oneOf[1].use = [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        importLoaders: 1,
        modules: true
      }
    },
    {
      loader: 'postcss-loader',
      options: {
        config: {
          path: './postcss.config.js'
        }
      }
    },
    'sass-loader'
  ]

  // Add PostCSS to scss
  rule.oneOf[7].use = [
    'style-loader',
    'css-loader',
    {
      loader: 'postcss-loader',
      options: {
        config: {
          path: './postcss.config.js'
        }
      }
    },
    'sass-loader'
  ]
}

})
```

@nahue I am also interested in this, did you find a better way. Did you get any input from Nrwl ?

I am also trying to set this up, just got started with nx yesterday. Will report back if I get things to work :)

Right so I got the following to work for my React app, not sure if better than @nahue's solution but seems to do the trick.

Add a webpack-tailwind.config.js at the root of the repo, this will hold the rule to get postcss-loader to work.

const tailwindWebpackRule = {
  test: /\.scss$/,
  loader: 'postcss-loader',
};

exports.tailwindWebpackRule = tailwindWebpackRule;

Then also at the root, add a postcss.config.js with your postcss configuration. Here, you should import your tailwind config and any other postcss plugins.

const tailwindcss = require('tailwindcss');
module.exports = {
  plugins: [
    require('postcss-import'),
    tailwindcss('./tailwind.config.js'),
    require('autoprefixer'),
  ],
};

Then create a webpack.config.js at the root of your app and make sure you reuse all existing config and add yours on top of the existing nx rules.

const WebpackNotifierPlugin = require('webpack-notifier');
const nrwlConfig = require('@nrwl/react/plugins/webpack.js');
const webpackTailwindConfig = require('../../webpack-tailwind.config');

module.exports = (config, context) => {
  nrwlConfig(config);
  return {
    ...config,
    plugins: [
      ...config.plugins,
      new WebpackNotifierPlugin({ title: 'Readium build completed' }),
    ],
    module: {
      rules: [
        ...config.module.rules,
        webpackTailwindConfig.tailwindWebpackRule,
      ],
    },
  };
};

Lastly, point your workspace.json builder to the new custom config: "webpackConfig": "apps/<your-app>/webpack.config.js" and tailwind should build when you serve.

Any suggestions for improvement would be greatly appreciated but hopefully this helps those of you who are trying to figure out a way to get this to work 鈽猴笍

These references were helpful to me along the way:

Hi @kiily,

First of all, thank you for taking the time to share with us how to integrate tailwindcss.

My project is set up with nx 10.4.1 and I've tried to follow your instructions.

I've created files postcss.config.js and webpack-tailwind.config.js at the root of the repo. Then I've created file webpack.config.js at the root of my app (apps/my-app/). And in workspace.json I've added the following

"customWebpackConfig": {
    "path": "./webpack.config.js"
},

To the options key on projects -> my-app -> architect -> build serve export

However, when I nx serve my-app I get this error:

Error: A PostCSS Plugin was passed as a function using require(), but it must be provided as a string.
Read more: https://err.sh/next.js/postcss-shape
Malformed PostCSS Configuration

PostCSS doesn't seem to accept requires.

I'm wondering why I'm getting this error. Any idea?

Thank you for your help

Here is the approach I use for tailwind with React (you can should be able to easily adapt for no using Nx)
https://kuccello.medium.com/nx-react-tailwind-css-made-simple-7ab71d39e678

thank you @kuccello, I'll take a look

For those who are still trying to configure Tailwind to work alongside Nx, this is what you need to do...

  1. Install Tailwind in compatibility mode with 7 PostCSS
$ npm install tailwindcss@npm:@tailwindcss/postcss7-compat [email protected]
  1. Create the PostCSS settings file
// postcss.config.js
module.exports = {
  plugins: [require('tailwindcss'), require('autoprefixer')],
};
  1. Create the Tailwind settings file
$ npx tailwindcss init
  1. Add the required Tailwind imports to your main CSS file
@tailwind base;
@tailwind components;
@tailwind utilities;
  1. Create the webpack settings file in the project you want to use
// webpack.config.js
const nrwlConfig = require('@nrwl/react/plugins/webpack.js');

module.exports = (config) => {
  nrwlConfig(config);
  return {
    ...config,
    module: {
      rules: [
        ...config.module.rules,
        {
          test: /\.css$/,
          use: [
            {
              loader: 'postcss-loader',
            },
          ],
        },
      ],
    },
  };
};
  1. Look for your project's webpackConfig on workspace.json and change it to use the webpack file you just created

Thank you @pauloedurezende! And if you get an error like this PostCSS plugin tailwindcss requires PostCSS 8, just follow this instruction.

Super quick setup with SCSS, Tailwind, Nx, React (adapted from @pauloedurezende):

  1. Install Tailwind in compatibility mode with 7 PostCSS
$ npm install tailwindcss@npm:@tailwindcss/postcss7-compat [email protected]
  1. Create tailwind.webpack.config.js
const nrwlConfig = require('@nrwl/react/plugins/webpack.js');

module.exports = (config) => {
  nrwlConfig(config);
  return {
    ...config,
    plugins: [...config.plugins],
    module: {
      rules: [
        ...config.module.rules,
        {
          test: /\.scss$/,
          loader: 'postcss-loader',
          options: {
            plugins: [
              require('postcss-import'),
              require('tailwindcss')('./tailwind.config.js'),
              require('autoprefixer'),
            ],
          },
        },
      ],
    },
  };
};
  1. Update your webpackConfig in workspace.json to tailwind.webpack.config.js
"my-app": {
    ...
    "architect": {
      "build": {
        ...
        "options": {
          ...
          "webpackConfig": "tailwind.webpack.config.js"
  1. Add style imports to your scss file:
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Done.

Was this page helpful?
0 / 5 - 0 ratings