Как остановить FOUC при использовании css, загружаемого webpack
Я получаю FOUC при загрузке css внутри моей точки входа при использовании webpack. Если я удалю свой css из загружаемого webpack и просто включу его в свой html файл в качестве обычной ссылки, проблема с FOUC исчезнет.
Примечание. Это не только с базой бутстрапов, я протестировал ее с помощью Основы и материализуются с теми же результатами
Код, представленный ниже, является лишь тестовым примером моей проблемы с использованием Bootstrap.
Код HTML
<!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
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' },
]
}
};
Ответы
Ответ 1
ExtractTextWebpackPlugin позволит вам выводить ваш CSS как отдельный файл, а не встраивать его в ваш пакет JS. Затем вы можете включить этот файл в свой HTML, который, как вы сказали, предотвращает появление неровного содержимого.
Я бы рекомендовал использовать это только в производственных средах, так как он перестает работать с горячей загрузкой и делает ваш компилятор более продолжительным. У меня есть webpack.config.js
, чтобы применить плагин только к process.env.NODE_ENV === "production"
; вы все равно получаете FOUC, когда работаете над созданием/запуском сервера dev, но я чувствую, что это справедливый компромисс.
Для получения дополнительной информации о том, как это установить, посмотрите SurviveJS guide.
Ответ 2
Это janky, но я обертываю ReactDom.render() в setTimeout() в моем корневом файле index.js.
setTimeout(ReactDOM.render(...), 0)
Ответ 3
Немного поздно для вечеринки, но вот как я это делаю.
В то время как я признаю достоинства extract-text-plugin, он страдает от ошибки перестройки, которая испортит порядок CSS, и это боль, которую нужно настроить. И установка тайм-аутов в js - это не то, что кто-то должен делать (это уродливо и не гарантируется на 100%, чтобы предотвратить fouc)...
Итак, мой index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
#app { display: none }
</style>
<title></title>
</head>
<body>
<div id="app"></div>
<script src="scripts/bundle.js"></script>
</body>
</html>
Затем в client.js в самом конце я добавляю:
include "./unhide.css";
... и unhide.css содержит одну строку:
#app { display: block }
Voila, вы ничего не видите, пока не загрузится все приложение.