Loadable-components: SSR: ChunkExtractor tries to load unexisting script

Created on 4 Feb 2019  ยท  12Comments  ยท  Source: gregberge/loadable-components

๐Ÿ› Bug Report

During SSR, chunks generated with webpack and ones that loadable tries to load have different names.

It happens when we have template literals in our import paths. It this case webpack generates chunks with one extra component name in the end. Like Path-To-Component/Component-Component. ๐Ÿคทโ€โ™‚๏ธ

To Reproduce

platform is used to segrerate desktop and mobile templates.

const About = loadable(() => import(`Pages/Static/${platform}/About`));

webpack.config.js

{
  output: {
    chunkFilename: 'js/[name].[chunkhash:8].chunk.js',
}

With this setup webpack generates the following chunks structure:

โ”œโ”€โ”€ Pages-Static
โ”‚ย ย  โ”œโ”€โ”€ desktop-About-About.a2ddc8ae.chunk.js
โ”‚ย ย  โ”œโ”€โ”€ desktop-Feedback-Feedback.83cc2d57.chunk.js

loadable-stats.json contains correct paths and names:

image

But for some reason, ChunkExtractor tries to load files with different names. This happens only during SSR.

node:28532) UnhandledPromiseRejectionWarning: Invariant Violation: loadable: cannot find Pages-Static/desktop-About in stats
    at invariant (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/component/dist/loadable.cjs.js:13:15)
    at ChunkExtractor.getChunkGroup (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:166:36)
    at one (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:190:30)
    at /Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:34:12
    at arrayMap (/Users/forastero/www/powerthesaurus-client/node_modules/lodash/lodash.js:639:23)
    at map (/Users/forastero/www/powerthesaurus-client/node_modules/lodash/lodash.js:9556:14)
    at Function.flatMap (/Users/forastero/www/powerthesaurus-client/node_modules/lodash/lodash.js:9259:26)
    at getAssets (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:33:49)
    at ChunkExtractor.getChunkAssets (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:203:14)
    at ChunkExtractor.getMainAssets (/Users/forastero/www/powerthesaurus-client/node_modules/@loadable/server/lib/ChunkExtractor.js:294:23)

I'm not sure if this is a bug with @loadable or with webpack itself. ๐Ÿค”

Link to repl or repo (highly encouraged)

I'm ready to reproduce the bug, if this is not something ridiculous. Maybe I'm doing something wrong.

Run npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard

Paste the results here:

## System:
 - OS: macOS 10.14.3
 - CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
 - Memory: 405.02 MB / 16.00 GB
 - Shell: 5.3 - /bin/zsh
## Binaries:
 - Node: 11.7.0 - /usr/local/bin/node
 - Yarn: 1.13.0 - /usr/local/bin/yarn
 - npm: 6.5.0 - /usr/local/bin/npm
 - Watchman: 4.9.0 - /usr/local/bin/watchman
## npmPackages:
 - @loadable/babel-plugin: ^5.0.1 => 5.2.2
 - @loadable/component: ^5.1.2 => 5.2.2
 - @loadable/server: ^5.1.3 => 5.4.0
 - @loadable/webpack-plugin: ^5.0.2 => 5.4.0
bug

Most helpful comment

I think the issue is here:
https://github.com/smooth-code/loadable-components/blob/8decb0d73b1e1f1233d731ca7d1469f61d2b4231/packages/babel-plugin/src/properties/chunkName.js#L121

The pre and postfix of the template literal are added to the [request] keyword. However, this is already done in the userRequest which replaces [request] in the webpack ContextModule. Because of that the postfix is added twice.

If I replace the above line with just [request] everything works fine.

All 12 comments

Hello @ElForastero, I think it has been fixed in #219. It will be fixed in next release.

After update to 5.6.0 chunks are built without subdirectories, but the problem with chunk names during SSR is still present.

So the issue is still actual.

## System:
 - OS: macOS 10.14.3
 - CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
 - Memory: 807.32 MB / 16.00 GB
 - Shell: 5.3 - /bin/zsh
## Binaries:
 - Node: 11.7.0 - /usr/local/bin/node
 - Yarn: 1.13.0 - /usr/local/bin/yarn
 - npm: 6.5.0 - /usr/local/bin/npm
 - Watchman: 4.9.0 - /usr/local/bin/watchman
## npmPackages:
 - @loadable/babel-plugin: ^5.0.1 => 5.6.0
 - @loadable/component: ^5.1.2 => 5.6.0
 - @loadable/server: ^5.1.3 => 5.6.0
 - @loadable/webpack-plugin: ^5.0.2 => 5.5.0

Currently, we solved this issue by not using template literals inside dynamic import paths.

Like this:

image

@neoziro Probably it should be reopened. ๐Ÿคทโ€โ™‚๏ธ

same issue, any updates?

Hi @Volkovskiy, can you explain your specific case?

  • What is your import()?
  • What file does it try to load?
  • What file should it load?

Also others could answer these three questions. This way we could try to know what is exactly the problem.

I do have the same issue:

  • Import: import(`./${props.lang}/Test`)
  • Tries to load: en-Test
  • Should load: en-Test-Test (this is generated by webpack)

I think the issue is here:
https://github.com/smooth-code/loadable-components/blob/8decb0d73b1e1f1233d731ca7d1469f61d2b4231/packages/babel-plugin/src/properties/chunkName.js#L121

The pre and postfix of the template literal are added to the [request] keyword. However, this is already done in the userRequest which replaces [request] in the webpack ContextModule. Because of that the postfix is added twice.

If I replace the above line with just [request] everything works fine.

Thanks @cevou for investigating! Could you submit a PR to fix it? Also we should try to find a way to write automated tests about it.

I think it's an issue, that the babel-plugin always overrides the webpackChunkName - even if the user specifies a custom name it will be overwritten.

I don't have an immediate solution, but if it would be possible to get rid of the whole chunkName function (it is only used for the chunkExtractor.addChunk(...)) and somehow use the actual chunkNames generated by webpack based on the user's configuration it would remove a source of error.

If we change the chunkNameFromTemplateLiteral function now and webpack changes any of their code it might not be compatible again.

I just tested it in the server-side-rendering example:

const Sub = loadable(props => import(`./letters/${props.letter}/test`))

<Sub letter="Z" />

I don't have any problem:

<script async data-chunk="letters-Z-test" src="/dist/web/letters-Z-test.js"></script>

I close it for now, please submit a new issue with a good reproducible example if you experience the bug.

Thanks for looking into it @neoziro.

I can confirm I've encountered this issue also (and was able to work around it with @cevou's fix).

I'll try reproducing it with the provided server-side example.

Was this page helpful?
0 / 5 - 0 ratings