Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop FOUC when using css loaded by webpack

Tags:

css

webpack

fouc

I am getting FOUC when loading css inside of my entry point when using webpack. If I remove my css from being loaded by webpack and just include it in my html file as a normal link then the problem with FOUC goes away.

Note: This not just with bootstrap framework, I have tested with Foundation and Materialize with the same results

The code posted below is just a test example of my problem using Bootstrap.

Html code

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title>  </head> <body> <div class="container">     <div class="jumbotron">         <h1>Navbar example</h1>     </div> </div> <!-- /container -->  <script src="build/bundle.js"></script> </body> </html> 

bootstrap.js main entry point

import "../node_modules/bootstrap/dist/css/bootstrap.css"; import bootstrap from 'bootstrap'  $(document).ready(function () {    console.log('bootstrap loaded') }); 

webpack.config.js

var path = require('path'); const ProvidePlugin = require('webpack/lib/ProvidePlugin'); const webpack = require("webpack");  module.exports = {   entry: './src/bootstrap.js',   output: {     path: path.join(__dirname, 'build'),     filename: 'bundle.js'   },     resolve: {         extensions: ['', '.js']     },     plugins: [         new webpack.ProvidePlugin({             $: "jquery",             jQuery: "jquery",             'window.jQuery': 'jquery'         })     ],   devtool: 'inline-source-map',   module: {       resolve: {           modulesDirectories: ['node_modules']       },     loaders: [       {         test: path.join(__dirname, 'src'),         loader: 'babel-loader',           query: {               presets: ['es2015']           }       },         { test: /\.css?$/, loader: 'style!css'},         { test: /\.html$/, loader: 'html' },         { test: /\.(png|gif|jpg)$/, loader: 'url', query: { limit: 8192 } },         { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff2' } },         { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff' } },         { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file' },     ]   } }; 
like image 729
dan Avatar asked Apr 06 '16 14:04

dan


People also ask

How does webpack load CSS?

To be able to use CSS in your webpack app, you need to set up a new loader. Out-of-the-box, webpack only understands Javascript and JSON. With a loader, you can translate another type of file to a format that webpack understands and can work with. There are many webpack loaders and each loader has a specific purpose.

What is webpack CSS?

css-loader is the npm module that would help webpack to collect CSS from all the css files referenced in your application and put it into a string. And then style-loader would take the output string generated by the above css-loader and put it inside the <style> tags in the index. html file.


1 Answers

ExtractTextWebpackPlugin will allow you to output your CSS as a separate file rather than having it embedded in your JS bundle. You can then include this file in your HTML, which as you said, prevents the flash of unstyled content.

I'd recommend only using this in production environments, as it stops hot-loading from working and makes your compile take longer. I have my webpack.config.js set up to only apply the plugin when process.env.NODE_ENV === "production"; you still get the FOUC when you're doing a development build/running the dev server, but I feel like this is a fair trade off.

For more information on how to set this up, take a look at SurviveJS's guide.


Update: As noted in the comments, ExtractTextWebpackPlugin has now been superceded by mini-css-extract-plugin - you should use that instead.

like image 60
Joe Clay Avatar answered Sep 19 '22 00:09

Joe Clay