Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
vinutha93bnvs opened this issue Nov 20, 2018 · 7 comments
Labels

Comments

@vinutha93bnvs
Copy link

vinutha93bnvs commented Nov 20, 2018

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.

@dalanmiller
Copy link

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({})
        ]
    },
};

@thescientist13
Copy link
Collaborator

thescientist13 commented Jan 1, 2019

Thanks for your code snippets @vinutha93bnvs and @dalanmiller .

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

@vinutha93bnvs
Copy link
Author

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

@thescientist13
Copy link
Collaborator

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

@vinutha93bnvs
Copy link
Author

vinutha93bnvs commented Jan 30, 2019

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.

@thescientist13
Copy link
Collaborator

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.

@thescientist13
Copy link
Collaborator

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants