I'm using webpack-dev-server to hot load all of my assets including CSS. Currently though, my CSS loads after the JavaScript which causes my application issues in some places that depend on layout existing.
How can I ensure that the CSS loads before the JavaScript executes?
I'm thinking there must be a way to do this from module
, perhaps a a callback I could hook in to? Or maybe by configuring the style-loader to have priority?
This is my index.js:
import './styles/main.scss';
import './scripts/main.js';
if (module.hot) {
module.hot.accept();
}
and this is my styles loader:
{
test: /\.(scss)$/,
loader: 'style!css?&sourceMap!postcss!resolve-url!sass?sourceMap'
},
A similar question has been asked at this style-loader Github Issue: https://github.com/webpack/style-loader/issues/121
I was having the exacly same issue, in production the css are extracted so it always work, however in development because of the style-loader
"sometimes executing after the main bundle" i had issues where the main bundle would calculate the size of some nodes in the DOM which was set by the css... so it could result to wrong sizes as the main css still havent loaded... i fixed this issue by having the option singleton:true
.
example:
{
test: /\.s?css$/,
loader: ExtractTextPlugin.extract({
fallback: [
{
loader: 'style-loader',
options: { singleton: true }
}
],
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: !isProduction,
sourceMap: !isProduction
}
},
{ loader: 'postcss-loader', options: { sourceMap: !isProduction, ...postcss } },
{ loader: 'resolve-url-loader', options: { sourceMap: !isProduction } },
{ loader: 'sass-loader', options: { sourceMap: true } }
]
}
)
}
Looks like there's no event, callback or any way to detect that the style has been loaded. After long hours of searching in vain, I had to do something really dirty:
function checkCSS() {
const repeat = requestAnimationFrame(checkCSS);
// CSS loaded?
if(getComputedStyle(document.body).boxSizing === 'border-box') {
routes.loadEvents() // Init JS
cancelAnimationFrame(repeat) // Cancel next frame
}
}
if (process.env.NODE_ENV !== 'production') {
checkCSS()
} else {
$(document).ready(() => {
routes.loadEvents()
})
}
Because I have * { box-sizing: border-box; }
in my styles and that I'm pretty sure native CSS styles won't never look like this, I can be ~99% sure that my own CSS is loaded.
I died a little writing this. Hopefully we'll find a better way!