Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NextJS with global CSS import fail in production mode

I'm using Next.JS with a few other modules. One of them, Megadraft, comes with its own CSS. I don't know if this is relevant, but I also use PurgeCSS.

Everything works fine on development mode, but the CSS seems to break in production mode. To be a little more explicit, all of the classes of Megadraft, seem to have no definition in production mode. The HTML nodes in the inspector still show that the classes are here, but they have just no definition.

Here's how I import the said CSS files in my pages/_app.js file:

// pages/_app.js
import "css/tailwind.css";
import "megadraft/dist/css/megadraft.css";

And this is my postcss.config.js:

// postcss.config.js
const purgecss = [
    "@fullhuman/postcss-purgecss",
    {
        content: [
            "./components/**/*.js",
            "./Layout/**/*.js",
            "./pages/**/*.js",
            "./node_modules/next/dist/pages/**/*.js",
            "./node_modules/next/dist/Layout/**/*.js",
            "./node_modules/next/dist/components/**/*.js"
        ],
        defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:/]+/g) || [],
    },
];
module.exports = {
    plugins: [
        "postcss-import",
        "tailwindcss",
        "autoprefixer",
        ...(process.env.NODE_ENV === "production" ? [purgecss] : []),
    ],
};

I'm using next ^9.4.4. It may be worth noticing that TailwindCSS seems to work just fine (both in dev and prod), but I think it may be because it is used as a plugin in postcss...

Just in case also, I integrated webpack to my project to solve an error I had where the code was telling that I needed a loader:

// next.config.js
module.exports = {
    cssModules: true,
    webpack: (config, options) => {
        config.node = {
            fs: "empty",
        };
        config.module.rules.push({
            test: /\.(png|woff|woff2|eot|ttf|svg)$/,
            use: [
                options.defaultLoaders.babel,
                {
                    loader: "url-loader?limit=100000",
                },
                {
                    loader: "file-loader",
                },
            ],
        });
        return config;
    },
};

Anyway, if someone has an idea of why this works in development mode and not in production, it could be of great help.

like image 740
Thanh-Quy Nguyen Avatar asked Jun 12 '20 13:06

Thanh-Quy Nguyen


Video Answer


1 Answers

Option 1: use Tailwind CSS built-in PurgeCSS

// tailwind.config.css
module.exports = {
  purge: ["./components/**/*.js", "./pages/**/*.js"],
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
};

// postcss.config.js
module.exports = {
  plugins: ["tailwindcss", "postcss-preset-env"]
};

Be sure to add postcss-preset-env to the package's dev dependencies with npm i --save-dev postcss-preset-env or yarn add -D postcss-preset-env.

Option 2: Manually setup purge and add "./node_modules/megadraft/dist/**/*.css" to purgecss whitelisting content array:

// tailwind.config.css
module.exports = {
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
};

// postcss.config.js
const purgecss = ['@fullhuman/postcss-purgecss',{
  content: ["./node_modules/megadraft/dist/**/*.css", "./components/**/*.js", "./pages/**/*.js"],

  defaultExtractor: content => {
    const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
    const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || []
    return broadMatches.concat(innerMatches)
  }
}]

module.exports = {
  plugins: [
    'tailwindcss',
    'autoprefixer',
    ...process.env.NODE_ENV === 'production'
      ? [purgecss]
      : []
  ]
}

There may be better solutions but these two are what I can think of.

like image 193
hangindev.com Avatar answered Oct 21 '22 12:10

hangindev.com