Skip to content

Async loading without document context throws errors #48

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

Closed
ctbarna opened this issue Mar 21, 2018 · 7 comments
Closed

Async loading without document context throws errors #48

ctbarna opened this issue Mar 21, 2018 · 7 comments

Comments

@ctbarna
Copy link

ctbarna commented Mar 21, 2018

I'm trying to get mini-css-extract-plugin to play nicely with react-loadable on the server. Everything seems relatively easy except that when I run Loadable.preloadAll() on the server, requireEnsure gets called for every async chunk. If the async chunk has CSS that hasn't been loaded it tries to insert a new link element, a ReferenceError: document is not defined gets thrown.

@alexander-akait
Copy link
Member

@ctbarna Thanks for issue. Can you create minimum reproducible test repo?

@ctbarna
Copy link
Author

ctbarna commented Mar 21, 2018

I can give it a shot but I will admit that I am not well versed in bootstrapping an SSR repo. The gist of the issue is that this creates a browser dependency in the webpackrequireEnsure method.

@alexander-akait
Copy link
Member

@ctbarna without reproducible test repo very difficult find problem 😞

@jonasIv
Copy link

jonasIv commented Mar 22, 2018

I had the same issue. If I'm not mistaken, the plugin uses document.createElement("link") to load the chunks. Running this server-side results in the reference error.

Here is a solution: Bundle your app for the client and additionally bundle your app for the server. When bundling for the server don't use mini-css-extract-plugin. Instead you use loader: 'css-loader/locals'.

When you bundle the client, create a react-loadable.json file using ReactLoadablePlugin. You can use this file on the server to figure out which chunks need to be rendered into <script> tags in your HTML. How you do this is described in the documentation of react-loadable in the "Server Side Rendering" section.

I hope that helped.

@pi0
Copy link

pi0 commented Mar 23, 2018

@jonasIv Thank you for your solution. It also worked for Nuxt.js but we have lost critical-path CSS.

@sokra
Copy link
Member

sokra commented Mar 29, 2018

When bundling for the server don't use mini-css-extract-plugin. Instead you use loader: 'css-loader/locals'.

@Murphycx94
Copy link

use extract-css-chunks-webpack-plugin instead mini-css-extract-plugin

webpack.base.config.js

const ExtractCssChunksPlugin = require('extract-css-chunks-webpack-plugin')
{
  ...
  {
        test: /\.css$/,
        use: [
          {
            loader: ExtractCssChunksPlugin.loader,
            options: {
              hot: !isProd,
              reloadAll: !isProd
            }
          },
          'postcss-loader',
          'css-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: ExtractCssChunksPlugin.loader,
            options: {
              hot: !isProd,
              reloadAll: !isProd
            }
          },
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      }
  ...
  plugins: [
   ...
    new ExtractCssChunksPlugin({
      filename: isProd ? 'css/[name].[contenthash:8].css' : '[name].css',
      chunkFilename: isProd ? 'css/[name].[contenthash:8].chunk.css' : '[name].chunk.css'
    })
  ]
}

webpack.server.config.js

{
  ...
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    })
  ]
}

extract-css-chunks-webpack-plugin

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

6 participants