How to ensure that hot CSS loads before JS in webpack-dev-server?

只谈情不闲聊 提交于 2019-12-22 04:36:08

问题


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


回答1:


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 } }
            ]
        }
    )
}



回答2:


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!



来源:https://stackoverflow.com/questions/39400038/how-to-ensure-that-hot-css-loads-before-js-in-webpack-dev-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!