React-toastify: WebPack CSS import fails with production mode; ok with dev mode

Created on 31 Mar 2019  路  20Comments  路  Source: fkhadra/react-toastify

When I compile (my ts) code in production mode

import 'react-toastify/dist/ReactToastify.min.css' 

is ignored:

Screen Shot 2019-03-31 at 4 03 40 PM

when I compile in development mode the css is successfully applied

Screen Shot 2019-03-31 at 4 05 22 PM

Haven't been able to find a workaround.

Worked fine in 4.x

in package.json:

  "scripts": {
    "dev": "webpack --mode development --config config/webpack.config.js",
    "build": "webpack --mode production --config config/webpack.config.js",
Reproduction Needed help wanted 馃檹

Most helpful comment

Fix pushed !

All 20 comments

Nothing had change for the css part since the v4. Could you share your webpack config please ?

Sure.

// webpack.config.js
var webpack = require('webpack');
var path = require('path');

// var WebpackNotifierPlugin = require('webpack-notifier');

module.exports = {
  devtool: 'eval',
  // This will be our app's entry point (webpack will look for it in the 'src' directory due to the modulesDirectory setting below). Feel free to change as desired.
  entry: [
    '@babel/polyfill',
    'index.tsx'
  ],
  // Output the bundled JS to dist/app.js
  output: {
    filename: 'app.js',
    path: path.resolve('dist')
  },
  resolve: {
    // Look for modules in .ts(x) files first, then .js(x)
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    // Add 'src' to our modulesDirectories, as all our app code will live in there, so Webpack should look in there for modules
    modules: ['ts', 'node_modules'],
  },
  module: {
    rules: [
      // .ts(x) files should first pass through the Typescript loader, and then through babel
      { test: /\.tsx?$/, 
        use:[
        {
          loader:'babel-loader'
        },
        {
          loader:'ts-loader'
        }]
      },
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      },
      { test: /\.txt$/, 
        use: ['raw-loader'] 
      },
      { test: /\.html$/, 
        use: ['html-loader'] 
      }
    ]
  },
  plugins: [
    // Set up the notifier plugin - you can remove this (or set alwaysNotify false) if desired
    // new WebpackNotifierPlugin({ alwaysNotify: true }),
  ]
};

Reverting to react-toastify 4.5.2 fixed the problem...

This is weird. The css files are still at the same location.

Facing the same issue here but in my case, revertin to react-toastify 4.5.2 does not fix the problem, i'm using this library within create-react-app so I think I can't configure webpack without ejecting.

I can confirm this issue. Problem with toasts only in production mode.

I fixed the problem adding the ToastContainer at the root of my app.

Hey the best is to render the ToastContainer at the root of the app. Since the v5 you can try to use the lazy container also.

If someone can provide a repo to reproduce the issue it would be cool

After some googling, problem wasn't with this library after all. I'm using Ruby on Rails on backend with webpacker gem. In this case you have to do following to be able use css styles in production:

  1. Include import 'react-toastify/dist/ReactToastify.css'; in your packs/my_component.jsx.
  2. If there is some import of .css files in your component, webpacker automatically compile it and include it in CSS pack called my_component.css.
  3. In your view you have to add <%= javascript_pack_tag 'my_component' %> and <%= stylesheet_pack_tag 'my_component.css' %>

Now you should be able to use .css files in production and component should be styled.

I don't know what others use, but maybe this could help. I've found solution thanks for this answer .

Hovewer problem is not in this library, at least not for me.

Running into the same problem, moving the container or removing the container has yielded no results

I have the same problem with 5.0.0, reverting to 4.5.2 worked.

Kind of a wild guess, but you marked the library as side-effect free, but importing CSS through Webpack (as in import 'path/styles.css') IS a side effect. Perhaps it's because of that? Haven't checked that but setting:

"sideEffects": [
  "*.css"
]

in package.json would maybe solve this problem.

@paolostyle thanks a lot. I think you are right.

Can someone try yarn add react-toastify@next and tell me if it fix the issue please ?

All I can do for now I post our (redacted) webpack config:

import { template as templateLegacy } from 'XX';
import { template } from 'XXX';

import config from 'config';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import HTMLPlugin from 'html-webpack-plugin';
import MiniExtractCss from 'mini-css-extract-plugin';
import { join } from 'path';
import { Configuration, HashedModuleIdsPlugin, ProvidePlugin } from 'webpack';

const dir = join(__dirname, '../');

const webpackConfig: Configuration = {
  context: join(dir, 'src/frontend'),
  devtool: 'source-map',
  entry: './index.tsx',
  mode: 'production',
  module: {
    rules: [
      {
        loader: 'ts-loader',
        options: {
          experimentalFileCaching: true,
          transpileOnly: true,
        },
        test: /\.tsx?$/,
      },
      {
        test: /\.s?css$/,
        use: [MiniExtractCss.loader, 'css-loader', {
          loader: 'sass-loader',
          options: {
            outputStyle: 'compressed',
          },
        }],
      },
    ],
  },
  optimization: {
    minimize: true,
    runtimeChunk: 'single',
    splitChunks: {
      chunks: 'all',
    },
  },
  output: {
    chunkFilename: '[name].[contenthash].js',
    filename: '[name].[contenthash].js',
    path: join(dir, 'dist/frontend'),
  },
  plugins: [
    new ProvidePlugin({
      Popper: ['popper.js', 'default'],
    }),
    new ForkTsCheckerWebpackPlugin({
      memoryLimit: 1024,
      useTypescriptIncrementalApi: false,
      workers: process.env.CI ? 1 : 2,
    }),
    new HashedModuleIdsPlugin(),
    new MiniExtractCss({
      chunkFilename: '[name].[contenthash].css',
      filename: '[name].[contenthash].css',
    }),
  ],
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
    symlinks: false,
  },
};

// Stub types for dev server.
declare module 'webpack' {
  interface Configuration {
    devServer?: object;
  }
}

export default function makeConfig(_env: undefined, cfg: { production?: true }) {
  const prepend: string[] = [];
  if (!cfg.production) {
    webpackConfig.mode = 'development'; // COMMENT THIS OUT FOR LIVE REPRO
    webpackConfig.optimization!.minimize = false;
    webpackConfig.devtool = 'eval';
    webpackConfig.devServer = {
      headers: {
        'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type, Authorization',
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
        'Access-Control-Allow-Origin': '*',
      },
      historyApiFallback: true,
      port: 8082,
      proxy: {
        '/api': 'http://localhost:8081',
      },
    };
  } else {
    prepend.push(templateLegacy);
  }
  if (config.has('log.frontend.publicToken')) {
    prepend.push(
      template({ environment: 'development', dsn: config.get('log.frontend.publicToken'), release: 'DEV' }),
    );
  }
  webpackConfig.plugins!.push(new HTMLPlugin({
    filename: 'index.html',
    minify: <any> true,
    prepend: prepend.join(''),
    template: 'index.ejs',
  }));
  return webpackConfig;
}

We have tried importing the css and scss style files via.

import 'react-toastify/dist/ReactToastify.min.css';

We have also tried to manually specify the toast container etc, nothing changes the outcome.

@SimonSchick could you try adding react-toastify@next ?

Yep, it works for me with react-toastify@next. Glad I could help :)

@paolostyle thanks for testing. I'll merge the fix to the stable branch

@fkhadra just did, works now 馃憤

Fix pushed !

@HenrikBechmann the issue should be fixed now. Thanks everyone for the help. Credit to @paolostyle 馃

@fkhadra yes i upgraded to 5.0.1 and all is fine. Good job everyone!

Was this page helpful?
0 / 5 - 0 ratings