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

Add doc for differences between the CSS loader options #75

Merged
merged 2 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions docs/style_loader_vs_mini_css.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# CSS Delivery In Development

You have two options for serving CSS in development:

1. You can opt to serve CSS via style-loader (as was traditionally done in a Webpack setup), where CSS is written by Javascript served by Webpacker into a `<style>` tag, or
2. You can opt to serve CSS as a full CSS file via mini-css-extract-plugin, which uses a standard `<link>` tag to load a fully separate CSS file.

Both options support HMR. The default is style-loader. If you want to use mini-css-extract-plugin in development, set `inline_css: false` in the development dev_server section of your webpacker.yml:

```yml
development:
<<: *default
dev_server:
hmr: true
inline_css: false # Use mini-css-extract-plugin for CSS delivery
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have this discussion include:

  1. CSS modules vs. CSS in JS?
  2. SSR vs. no SSR?
  3. Styling React components vs. non-react components?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth expanding on. Since this is mostly a development concern, I'm not sure it matters nearly as much as it would if it were a production concern, though.

## Why would I pick style-loader?

style-loader is how you are probably are used to serving CSS in development with HMR in Webpack.

### benefits

* No [Flash Of Unstyled Content (FOUC)](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) on HMR refreshes
* Smaller/faster incremental updates.

### drawbacks

* Inflated JS deliverable size; requires JS execution before CSS is available
* FOUC on initial page load
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is true only in special circumstances, like no SSR? or when SSR is improperly configured?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, actually. I don't do a lot of SSR. I'd need someone else to amend this.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking into this for the FOUC that I was getting using style-loader, now sure how to configure SSR or if that would actually help ?
Works app is pinned at ruby 2.5.0 so I can't use shakapacker at this time.

* Adds an extra dependency
* Divergence in delivery mechanism from production

## Why would I pick mini-extract-css-plugin?

mini-css-extract-plugin's behavior is much more true to a production deployment's behavior, in that CSS is loaded via `link rel=stylsheet` tags, rather than injected by Javascript into `style` tags.

### benefits

* Required for production, so it's going to be in play anyhow. Using only it simplifies the config and eliminates the style-loader dependency.
* No FOUC on initial page loads
* CSS delivered via `<link>` tags matches the mechanism used in production (I have been guilty of omitting my `stylesheet_pack_tag` for my first deploy because CSS worked fine with just the `javascript_pack_tag` in development.)

### drawbacks

* Invokes a separate HTTP request, compared to style-loader
* Potential for FOUC on HMR refreshes
* More data transferred per refresh (full stylesheet reload, rather than just an incremental patch). Not likely to be noticed for local development, but still a technical difference. This may only be the case [when you're using local CSS modules](https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/hmr/hotModuleReplacement.js#L267-L273).
9 changes: 7 additions & 2 deletions lib/install/config/webpacker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ development:
port: 3035
# Hot Module Replacement updates modules while the application is running without a full reload
hmr: false
# If HMR is on, CSS will by inlined by delivering it as part of the script payload via script-loader.
# If you want to instead deliver CSS as <link> tags via mini-extract-css-plugin, set inline_css to false.
# If HMR is on, CSS will by inlined by delivering it as part of the script payload via style-loader. Be sure
# that you add style-loader to your project dependencies.
#
# If you want to instead deliver CSS via <link> with the mini-extract-css-plugin, set inline_css to false.
# In that case, style-loader is not needed as a dependency.
#
# mini-extract-css-plugin is a required dependency in both cases.
inline_css: true
# Defaults to the inverse of hmr. Uncomment to manually set this.
# live_reload: true
Expand Down