Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async loading of CSS bundle #204

Closed
Vangor opened this issue Jul 6, 2018 · 11 comments
Closed

Async loading of CSS bundle #204

Vangor opened this issue Jul 6, 2018 · 11 comments

Comments

@Vangor
Copy link

Vangor commented Jul 6, 2018

Is there a way to disable async loading of CSS bundle?
Using it with this config.

new MiniCssExtractPlugin({
  chunkFilename: 'data-police.css?t=[contenthash]'
})
MiniCssExtractPlugin.loader,
{
  loader: 'css-loader',
  options: {
  importLoaders: 1,
  sourceMap: true,
  url: false,
  modules: true,
  localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
  }
 }
@alexander-akait
Copy link
Member

@Vangor What you mean? Just don't load css async

@Vangor
Copy link
Author

Vangor commented Jul 6, 2018

@evilebottnawi Well, the thing is, that I don't specify it anywhere. I just use these settings, and CSS file is loaded asynchronously.
Maybe it's how this plugin works with css-modules?

@alexander-akait
Copy link
Member

@Vangor can you create minimum reproducible test repo?

@Vangor
Copy link
Author

Vangor commented Jul 9, 2018

I will try but don't think so.

@alexander-akait
Copy link
Member

@Vangor Without reproducible test repo, we can't help, sorry

@zahorovskyi
Copy link

zahorovskyi commented Jul 10, 2018

@evilebottnawi Hi. I have small question regarding to your comment "@Vangor What you mean? Just don't load css async". Do we have some way to disable just async loading? I mean that I want change nothing in plugin working flow, I still want to build css and have chunks in bundle. I just want to managing connection css to the page manually.

@ScriptedAlchemy
Copy link
Contributor

i get what you want.

you are looking for something that will extract the stylesheets, but not necessarily append them on demand when a new javascript file is consumed.

From my development of a derivative of mini-css, i can tell you that its pretty baked into the plugin, as it should be.

The feature you are requesting does not really align with the goals of webpack-team.

Mini css likely will be a built in part of webpack in 5.x

if you want to remove the ability to load on demand (append a link to the head), you might want to either look for another loader which may further process the file, or consider changing your applications architecture so that it can work with webpack.

There some things to consider as well, like chunking, and the fact that mini-css actually does a good job at optimizing and combining chunks... The file you want, might have been transformed and shares styles with other components / relys on other style optimizations and its own loading mechanism to recombine the used styles.

One workaround might be to just use file-loader and postcss, it wouldn't have the loading mechanism to append resources on demand like mini-css does.

@Vangor Vangor closed this as completed Sep 7, 2018
@Vangor
Copy link
Author

Vangor commented Sep 7, 2018

Thanks for Explanation @ScriptedAlchemy
I think we will use it as is for now.
This was needed, since we have microservice architecture, and controller that brings all services together, loads it's css and js, and we wanted to handle it trough controller only.

@ScriptedAlchemy
Copy link
Contributor

ScriptedAlchemy commented Sep 7, 2018

@Vangor
Ahh, you might be interested in this https://github.com/ScriptedAlchemy/webpackery - work in progress, but have a private implementation.

I design microservice - microfrontend architecture.

This is a very hard one to solve, however i have achieved this.
What you are looking for, is a way to treat multiple webpack builds as one single build.

I had the same thought.

Thanks to webpack 4, you can actually tap into and inject dependencies into webpack from another build.

i know theres things like externals, to stop webpack bundeling vendor code. But its not very good.
Im working on a way where everything could be share, nothing loaded twice. Multiple builds on the page, all sharing browser cache.

What might help is creating another npm package that contains all your shared styles, you could then dynamically import it. If another build already has it, webpack wont require it again.

Managing dynamic imports, especially with react, can be impossible. For this we created the Universal family which help you code split and load css & js together without disrupting SSR.

Universal has been one of the key parts to my architecture - allowing me to import dependency chains.

Check out https://github.com/faceyspacey/react-universal-component it might help you load your css in a more manageable manner and on demand with the components who need the code.

If you have any questions - i can give you my email.

Ive done this for a kubernatized LOSA systems, where microservices ran and render parts of a page or whole pages, hundreds of them, with react based fragment caching 🔥

@zahorovskyi
Copy link

@ScriptedAlchemy, thank's for your answer.

@thomasbaldwin
Copy link

thomasbaldwin commented Feb 11, 2019

@Vangor @ScriptedAlchemy - I was able to stop the async loading of CSS chunks by commenting out these lines in the plugin: thomasbaldwin@f350eb8

screen shot 2019-02-10 at 11 37 21 pm

@evilebottnawi the reason someone would want to do something like this is because they may have a component that looks like this:

import React from 'react';
import PropTypes from 'prop-types';

const brandStyles = {};
brandStyles[A] = require('./styles.a.scss'); // version A of the component styling
brandStyles[B] = require('./styles.b.scss'); // version B of the component styling

const BrandedComponent = ({ brand, ... }) => {
  const styles = brandStyles[brand] || brandStyles[A];

  return (
    <div className={styles.container}>
      ...
    </div>
  )
}

export default BrandedComponent;

Notice how there's an A and B stylesheet. This is because using a different stylesheet, we can drastically change how the component looks in our application, essentially creating different branded versions of it. Depending on the brand you hit, the correct stylesheet will be applied.

The way I've compiled the stylesheets is so that there's a global.css, a.css, b.css files (and even more because we support more than just 2 brands). Depending on the brand you hit, I attach the correct stylesheets in a link tag to the page source so the browser will download them.

If I had not disabled the async loading of styles, the other brand styles being required at the top of the component would have been asynchronously downloaded, sometimes causing the component to not look as I wanted it to.

However, I cannot seem to find out how the corresponding JS (which maps the local class names to the desired output classnames) can be stopped from being dynamically added to the page. This has no effect other than it's a couple KB of JS that is downloaded that's not used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants