kriasoft / isomorphic-style-loader

CSS style loader for Webpack that is optimized for isomorphic (universal) web apps.
https://reactstarter.com
MIT License
1.27k stars 144 forks source link

How to use isomorphic-style-loader with extract-text-webpack-plugin #123

Open Demon137 opened 6 years ago

Demon137 commented 6 years ago

In my reactjs project, I am using isomorphic approach and in webpackconfig, I want to use isomorphic-style-loader so that It can embed (inline) CSS style in the header but along with extract-text-webpack-plugin so that it will also create a separate bundle CSS file.

frenzzy commented 6 years ago

when you extract css you don't need isomorphic-style-loader, just use null loader on server side

Demon137 commented 6 years ago

Hey @frenzzy , Thank for the response. I am new to reactjs and webpack I am using below code in webpack :

use: ExtractTextPlugin.extract({ fallback: 'isomorphic-style-loader', use: [ { loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: '[hash:base64:10]', sourceMap: true } }, { loader: 'sass-loader' } ] })

is it fine???

Demon137 commented 6 years ago

in above case , I am getting following error at browser: Uncaught TypeError: style._insertCss is not a function

I have the same configuration on webpack client and server.

TheodorTomas commented 5 years ago

Hey @frenzzy, I am a bit confused on what you mean by "when you extract css you don't need isomorphic-style-loader". I am looking to using this plugin only to extract and inline the critical "above the fold" css. I would then like to extract and bundle the remaining css and use that to load asynchronously using Javascript. The examples I have found are utilizing the plugin for exactly that reason but fail to explain in detail how to load the remaining CSS that does not use the withStyles function. Could you help shed light on this use case?

Thanks in advance.

frenzzy commented 5 years ago

extract-text-webpack-plugin extracts styles from .js files into separate .css files. Then you use .css files as you wish, for example you can manually use <link rel="stylesheet" href="{file-with-extracted-styles}.css"> or webpack will add this line at runtime.

isomorphic-style-loader does not extracts styles from .js files but instead convert them into a javascript module with _getCss() method which you can use at runtime manually. It allows you to capture critical path css during server-side-rendering but you also have to care about inserting styles on client side yourself by calling _insertCss(). This approach is used in react-starter-kit (see src/client.js and src/server.js files).

TheodorTomas commented 5 years ago

Thanks @frenzzy, I just made some progress with this. I have already implemented it in a similar fashion as in react-starter-kit, but the main struggle has been to configure webpack correctly along with style-loader, css-loader, postcss-loader and sass-loader. I just changed it to use isomorphic-style-loader as a fallback along with a small change to the insertCss function server-side and am now not getting any more errors.

StefanoSega commented 5 years ago

I've a similar issue but using MiniCssExtractPlugin instead.

Since I'm extracting the css (that then it get splitted into chunks with webpack and the app loads just the needed css for each route I hit) for the SSR part of webpack I use null-loader for the .scss files, and the bundled .css file is linked in the head of the document statically.

... webpack for frontend ...

{
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: false,
            localIdentName: '[local]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }, {
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: true,
            localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }]
    }

... webpack for SSR ...

{
      test: /\.scss$/,
      use: ['null-loader'],
    }

the problem is that when I reload a route of the app the HTML is immediately rendered from the server in nanoseconds, but for at least 1 sec it appears unstyled, giving FOUC experience.

jerryOnlyZRJ commented 5 years ago

when you extract css you don't need isomorphic-style-loader, just use null-loader on server side

Thank you! It works for me.

jerryOnlyZRJ commented 5 years ago

I've a similar issue but using MiniCssExtractPlugin instead.

Since I'm extracting the css (that then it get splitted into chunks with webpack and the app loads just the needed css for each route I hit) for the SSR part of webpack I use null-loader for the .scss files, and the bundled .css file is linked in the head of the document statically.

... webpack for frontend ...

{
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: false,
            localIdentName: '[local]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }, {
        use: [MiniCssExtractPlugin.loader, {
          loader: 'css-loader',
          options: {
            modules: true,
            sourceMap: true,
            camelCase: true,
            localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
          },
        }, 'sass-loader', 'postcss-loader'],
      }]
    }

... webpack for SSR ...

{
      test: /\.scss$/,
      use: ['null-loader'],
    }

the problem is that when I reload a route of the app the HTML is immediately rendered from the server in nanoseconds, but for at least 1 sec it appears unstyled, giving FOUC experience.

Don't use CSS Modules in this case, because the hash is different between client-side and server-side.