gregberge / loadable-components

The recommended Code Splitting library for React ✂️✨
https://loadable-components.com
MIT License
7.69k stars 382 forks source link

Chunks exist in my stats file but not in LOADABLE_REQUIRED_CHUNKS on client. #241

Closed garrettsherm closed 5 years ago

garrettsherm commented 5 years ago

I have been trying the last few days to get code splitting working with SSR and after fixing a bunch of webpack/babel related issues (upgrading to webpack v4 & babel v7 with updated babel plugins), I am now facing an issue with the ChunkExtractor and loading of links/scripts.

In my routes file I have a loadable component

const Discover = loadable(() => import('../pages/discover.js'));

and I am seeing the the chunkName in my stats-loadable.json

"assetsByChunkName": {
    "main": [
      "main.d1605868d5f74e36b617.css",
      "main.d1605868d5f74e36b617.js"
    ],
    "pages-discover": "pages-discover.271ab8a69db56a13d8d5.js"
  },

But after running the example code from the documentation for the ChunkExtractor, I'm still not seeing the "pages-discover" chunk in the DOM when server side rendering. The weird part is that I am seeing the main chunk being rendered though.

<script>window.__LOADABLE_REQUIRED_CHUNKS__ = [];</script>
<script async data-chunk="main" src="/static/main.d1605868d5f74e36b617.js"></script>

Here is the relevant server code I'm using for SSR:

 const AppComponent = () => (
          <ApolloProvider client={client}>
            <Provider store={store}>
              <I18nextProvider i18n={req.i18n}>
                <AppDelegate>
                  <StaticRouter location={req.url} context={context}>
                    <Route component={props => <Routes {...props} />} />
                  </StaticRouter>
                </AppDelegate>
              </I18nextProvider>
            </Provider>
          </ApolloProvider>
        );

const webExtractor = new ChunkExtractor({
          statsFile: webStats,
        });

        const jsx = webExtractor.collectChunks(<AppComponent />);

        let initialState = {};

        try {
          await getDataFromTree(jsx);
          initialState = client.extract();
        } catch (e) {
          console.log('catching getDataFromTree');
        }

        const html = renderToString(jsx);

        const scriptTags = webExtractor.getScriptTags();

        const linkTags = webExtractor.getLinkTags();

        const styleTags = webExtractor.getStyleTags();

Then I pass all these variables to a render function to load the content that is sent to the user.

Any help or insight would be much appreciated!

gregberge commented 5 years ago

Hello @garrettsherm, I don't see anything wrong in your setup. Without being able to reproduce it, I can't help you. Can you provide a repro repository?

garrettsherm commented 5 years ago

@neoziro Ok np I can't share this specific repo but I'm going to try and create another repo where I replicate the issue when I get time.

gregberge commented 5 years ago

Outdated.

domilin commented 5 years ago

I have the same problem. Have you solved it @neoziro

gregberge commented 5 years ago

@zhoushuanglong please submit a repro repository and a new issue to describe your problem. Also please check that your setup is correct before submitting it.

gregberge commented 5 years ago

The library is stable and widely used, if you experience this issue, it is probably a wrong setup.

garrettsherm commented 5 years ago

@zhoushuanglong Sorry for the late response but I solved my issue a while back, and like @neoziro said it had to do with my webpack config being wrong. Instead of using @loadable/component as an external I was using @loadable/server (see https://github.com/smooth-code/loadable-components/blob/master/examples/server-side-rendering/webpack.config.babel.js).

Once I changed that it worked. Hope that can you help you out.