Use Tailwind with Webpack 5

Viewed 1270

My current Webpack 5 setup includes the following rule for CSS and SCSS files:

test: /\.s?css$/,
use: [
    { loader: MiniCssExtractPlugin.loader },
    { loader: 'css-loader', options: { importLoaders: 1 } },
    {
        loader: 'postcss-loader',
        plugins: [
            tailwindcss
        ]
    },
    'sass-loader'
],

The goal is to:

  • compile scss
  • process tailwind
  • load css
  • separate css into file

My scss file contains:

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

But I get the following error:

Failed to load 'C:\dev\project\webpack.config.js' config
lum[i] = (chan <= 0.039_28) ? chan / 12.92 : ((chan + 0.055) / 1.055) ** 2.4;
SyntaxError: Invalid or unexpected token

Relevant note: if I remove the postcss-loader, it compiles but of course tailwind doesn't get included into the CSS file.

How may I solve this?

1 Answers

For tailwind preprocessor like SASS, @tailwind will not work. You have to use @import "tailwindcss/" instead. for example @import "tailwindcss/base".

Now jump on webpack config:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const WorkboxWebpackPlugin = require("workbox-webpack-plugin");
const { VueLoaderPlugin } = require('vue-loader')
const isProduction = process.env.NODE_ENV == "production";
const stylesHandler = MiniCssExtractPlugin.loader;

const config = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HtmlWebpackPlugin({
  // template: "index.html",
  template: path.resolve(__dirname, 'public/index.html')
}),

new MiniCssExtractPlugin(),
new VueLoaderPlugin(),

// Add your plugins here
// Learn more about plugins from 
https://webpack.js.org/configuration/plugins/
],
module: {
rules: [
  {
    test: /\.vue$/,
    loader: 'vue-loader'
  },
  {
    test: /\.(js|jsx)$/i,
    loader: "babel-loader",
  },
  {
    test: /\.s[ac]ss$/i,
    use: [stylesHandler, "css-loader", "postcss-loader", "sass-loader"],
  },
  {
    test: /\.css$/i,
    use: [stylesHandler, "css-loader", "postcss-loader"],
  },
  {
    test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
    type: "asset",
  },

  // Add your rules for custom modules here
  // Learn more about loaders from https://webpack.js.org/loaders/
],
},
};

module.exports = () => {
if (isProduction) {
config.mode = "production";

config.plugins.push(new WorkboxWebpackPlugin.GenerateSW());
} else {
config.mode = "development";
}
return config;
};

you can ignore vue rules if you're not using VueJs. And here is the devDependencies I used:

"@babel/core": "^7.17.7",
"@babel/preset-env": "^7.16.11",
"@webpack-cli/generators": "^2.4.2",
"autoprefixer": "^10.4.4",
"babel-loader": "^8.2.3",
"css-loader": "^6.7.1",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.0",
"postcss": "^8.4.12",
"postcss-loader": "^6.2.1",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"tailwindcss": "^3.0.23",
"vue-loader": "^17.0.0",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"workbox-webpack-plugin": "^6.5.1"

Don't forget to configure postCSS like this:

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

Now import the scss files to your main.js or index.js. And for separating CSS, you can follow this article: https://survivejs.com/webpack/styling/separating-css/

Enjoy.

Related