Reactgo: Why use "new ExtractTextPlugin()" twice and how it works?

Created on 18 Sep 2016  路  14Comments  路  Source: reactGo/reactGo

1. I am confused why you choose to use new ExtractTextPlugin('styles/main.css', { allChunks: true })
both on server and client in webpack.config.prod.js. Wouldn't styles/main.css be overwritten by the last execution (2nd one)? As I understand we only need one styles/main.css in our public folder. Why have two? Or do

new webpack.optimize.OccurenceOrderPlugin(),
new ExtractTextPlugin('styles/main.css', { allChunks: true }) 

do something magical together?

2. Can you also explain how ExtractTextPlugin works? Does it only get the style(s) from the entry file or it takes all styles from other components and bundles `em together?

3. Does postCSS/postcss-loader compile sass, so I dont need to use sass-loader?

Thanks :)

Discussion Documentaion

Most helpful comment

  1. I don't think it's needed in both, it'd be in plugins because it's included in common loaders. Can probably be removed if you'd like to make a PR.
  2. allChunks: true means it gets styles from all components and bundles them. If you look in the output JS files, there are empty modules with a comment saying "extracted by extract-text-plugin" (or similar).
  3. No, postcss-loader does PostCSS => CSS. PostCSS can be used instead of SASS if you want, but if using SASS you still need sass-loader to convert to regular CSS.

All 14 comments

  1. I don't think it's needed in both, it'd be in plugins because it's included in common loaders. Can probably be removed if you'd like to make a PR.
  2. allChunks: true means it gets styles from all components and bundles them. If you look in the output JS files, there are empty modules with a comment saying "extracted by extract-text-plugin" (or similar).
  3. No, postcss-loader does PostCSS => CSS. PostCSS can be used instead of SASS if you want, but if using SASS you still need sass-loader to convert to regular CSS.

@psimyn Thanks dude. 2 more questions :)

1. ExtractTextPlugin() doesn't get style(s) from components imported with require.ensure(), since they're "separate chunks", therefore they will be loaded on demand through javascript instead. Is that correct?

2 Does allChunks: true options over-rides the behaviour described in 1?

in this case it will put everything in styles/main.css (the hardcoded path in the config). If you want it to output separate CSS file per-chunk you can use this in webpack config:

  new ExtractTextPlugin('[name].css'), // add [chunkhash] if you want cache-busting

You then need to add the CSS for each chunk on the pages they are needed. this should all be independent of allChunks' value

Why not simple inline css styles relative only to current page into the page header? isomorphic-style-loader do it and update styles on page routing.

@psimyn thanks :)

@alex-shamshurin
I think it should not be inlined because incline css styles cannot be cached. Caching doesn't matter when the app is small, but we should also consider the case when the app grows and gets bigger.
Just my opinion. :)

there is no reasons to cache, styles are included into the bundle, so everything already there. But initial loading is faster.

@alex-shamshurin extract text plugin extracts imported CSS out of the bundle (so it's no longer included).

The potential speedups are:
Smaller js download
CSS is cached
Not parsing giant strings of css to inject into DOM

Including css for entire application in 1 file is not ideal, but you can start module splitting and load on demand

@shakaIsReal happy for this to be closed?

@psimyn No reasons to use extracted-text-plugin, I guess so.

Browser stops rendering when it gets instructions to download css file. Until it finished everything is stopped. When styles are inlined - browser engine have not to wait. Included styles in this case are "critical only" - only for components which are on this page and minified and compressed within a html page.
All other styles are in the bundle and js file can be download async, page loading do not wait for that. After initial loading components replace styles in the head.

@alex-shamshurin critical CSS as the only blocking script tag is definitely a good option. I think it's possible to extract critical CSS as a separate bundle, and then load other CSS as async.

My main motivation for having CSS completely separate is to keep JS bundle size down - keeping render-blocking CSS out of is good, but not if you are then waiting on 1mb of js/styles before anything is interactive.

Will look some more into critical styles, not yet sure of a way to include in the build.

Example detector/generator:
https://github.com/addyosmani/critical

but not if you are then waiting on 1mb of js/styles before anything

Why wait for that? All components on the page already provided with all their styles and it is grouped in the page's head and this is exactly what server do during initial rendering.
All other styles for other pages may be loaded with new bundle if they are too big via require.ensure. if it is not big, it can be in one bundle.

I do not understand why keeping styles apart can speed up something or reduce bundle size. Anyway css files must be downloaded too and it's a blocking op.

All other styles for other pages may be loaded with new bundle

this is the 1mb I meant - not blocking render but slows down page ready. But yeah, that is fixable by require.ensure or aysnc requires

thanks!

@psimyn Please do a pull request, if you can! I don't have time to do it ATM. Thanks again :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

psimyn picture psimyn  路  6Comments

elitekode picture elitekode  路  8Comments

zacharybrady picture zacharybrady  路  4Comments

kenjim83 picture kenjim83  路  8Comments

thientran1707 picture thientran1707  路  5Comments