Search code examples
csswebpackpostcsspostcss-import

Importing global css custom variables


I'm trying to use webpack with postcss to import a theme-variables.css file that contains my css custom variables.

//theme-variables.css
:root {
    --babyBlue: blue;
}

Basically I want any css that imports theme-variable to be able to access these css custom properties and resolve to static values using postcss-css-variables.

//style.css
@import "./theme-variable.css";

div {
    display: flex;
    color: var(--babyBlue);
}

becomes

//main.css
div {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    color: blue;
}

However I keep getting webpack errors variable --babyBlue is undefined and used without a fallback

main.js ends up looking like this:

:root {
    --babyBlue: blue;
}
div {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    color: undefined;
}

Here's my webpack (index.js requires styles.js):

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: { main: "./src/index.js" },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          {
            loader: "css-loader",
            options: { importLoaders: 1 }
          },
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss",
              plugins: loader => [
                require("postcss-css-variables")(),
                require("postcss-cssnext")(),
                require("autoprefixer")(),
                require("postcss-import")()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ]
};

Solution

  • Solution: The postcss-import plugin has to come first HOWEVER the plugins for Postcss-loader does not go in reverse order like webpack loaders do.

    This fixes it:

    loader: "postcss-loader",
    options: {
       ident: "postcss",
       plugins: loader => [
          require("postcss-import")()
          require("postcss-css-variables")(),
          require("postcss-cssnext")(),
          require("autoprefixer")(),
    
       ]
    }