anthonygore / html-critical-webpack-plugin

A webpack plugin that will extract critical CSS. Now supports Webpack v4.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"css should not be empty" with postcss config in next.js with purge css

vinutha93bnvs opened this issue · comments

const path = require('path');
const glob = require('glob');
const webpack = require('webpack');
const withCSS = require('@zeit/next-css');
const withEslint = require('next-eslint');
const withImages = require('next-images');
const withPurgeCss = require('next-purgecss');
const withPlugins = require('next-compose-plugins');
const HtmlCriticalWebpackPlugin = require('html-critical-webpack-plugin');

const generatePathMaps = require('./helpers/generate-export-urls');
require('dotenv').config();

// const PATHS = {
//   src: path.join(__dirname, './pages'),
//   out: path.join(__dirname, './out'),
// };

class TailwindExtractor {
  static extract(content) {
    return content.match(/[A-Za-z0-9-_:/]+/g) || [];
  }
}

const nextConfig = {
  webpack: (config, { dev }) => {
    config.plugins.push(
      new webpack.EnvironmentPlugin(process.env),
      new HtmlCriticalWebpackPlugin({
        base: path.resolve(__dirname, ''),
        src: 'out/en-ca/index.html',
        dest: 'out/en-ca/index.html',
        // css: 'static/css/index.css',
        inline: true,
        minify: true,
        extract: true,
        width: 375,
        height: 565,
        penthouse: {
          timeOut: 300000,
          blockJSRequests: false,
        },
      })
    );

    return config;
  },
  useFileSystemPublicRoutes: false,
  exportPathMap: async () => {
    const extraPathMaps = {
      '/en-ca': { page: '/homePage', query: { locale: 'en-CA' } },
    };
    const pathMapObject = await generatePathMaps();
    return Object.assign({}, extraPathMaps, pathMapObject[0]);
  },
};

module.exports = withPlugins(
  [
    [
      withPurgeCss,
      {
        purgeCssPaths: ['pages/**/*.js', 'components/**/*.js', 'utils/**/*.js'],
        purgeCss: {
          whitelistPatterns: () => [/^slick-/],
          extractors: [
            {
              extractor: TailwindExtractor,

              // Specify the file extensions to include when scanning for
              // class names.
              extensions: ['js'],
            },
          ],
        },
      },
    ],
    withCSS,
    withImages,
  ],
  nextConfig
);

I am expecting the .css file to be picked from index.html and inject inline critical css.

commented

Also getting this with the following config (where I'm not using either PostCSS or nextCSS):

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
// const ExtractTextPlugin = require("extract-text-webpack-plugin");
const { GenerateSW } = require('workbox-webpack-plugin');
const HtmlCriticalWebpackPlugin = require("html-critical-webpack-plugin");

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    module: {
        rules: [
            // {
            //     test: /\.css$/,
            //     // use: ['style-loader', 'css-loader']
            //     use: [
            //         {
            //             loader: MiniCssExtractPlugin.loader,
            //             options: {
            //                 // you can specify a publicPath here
            //                 // by default it use publicPath in webpackOptions.output
            //                 publicPath: '../'
            //             }
            //         },
            //         "css-loader"
            //     ]
            // },
            {
                test: /\.css$/,
                use: [
                    'isomorphic-style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1
                        }
                    }
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    "css-loader", // translates CSS into CommonJS
                    "sass-loader" // compiles Sass to CSS, using Node Sass by default
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/i,
                loader: 'url-loader',
                options: {
                    limit: 80192
                },
            }, {
                test: /\.html$/,
                use: ['file-loader?name=[name].[ext]', 'extract-loader', 'html-loader'],
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        }),
        new GenerateSW({
            swDest: path.resolve(__dirname, 'dist/sw.js')
        }),
        new HtmlCriticalWebpackPlugin({
            base: path.resolve(__dirname, 'dist'),
            src: 'index.html',
            dest: 'index.html',
            inline: true,
            minify: true,
            extract: true,
        })
    ],
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true // set to true if you want JS source maps
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    },
};

Thanks for your code snippets @vinutha93bnvs and @dalanmiller .

In both cases, are you confirming index.html is being generated before HtmlCriticalWebpackPlugin runs? Any errors?

@thescientist13 ,
Yes. I have generated a sample index.html with external css file. However i dont see this working

@vinutha93bnvs
Are you developing a SPA (Single Page Application, eg. React, Angular) by chance? (what does your index.html look like?

yes. my main intention was SPA. But to start with, i tested with a demo index.html file generated by static site generator (Gatsby), with external css file linked, critical css did not work.

To my knowledge, external style tag detection and path is not extracted in a proper way by this plugIn.

Can you please share the contents of your index.html though? My main concern is that critical needs DOM to scan in index.html to see what styles need to get extracted. So with a SPA, there usually isn't much DOM in index.html, and so not much for critical to scan.

Just to follow up, a user with a similar report found that running critical manually also produced the same results, so maybe critical itself isn't well suited to SPAs?

Can you please confirm as well? Might not be a plugin issue.
#39 (comment)