Skip to content
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

Invariant Violation: loadable: SSR requires @loadable/babel-plugin, please install it #466

Closed
zhenliliu opened this issue Nov 27, 2019 · 30 comments · Fixed by #494
Closed
Assignees
Labels

Comments

@zhenliliu
Copy link

zhenliliu commented Nov 27, 2019

🐛 Bug Report

I have configed '@loadable/babel-plugin' in babel.config.js, but when i use SSR to render react file ,then i got this error message
image

this is my config file
image

and this is SSR
image

this is client side route file
image

i want to get some help and to fix it

@theKashey
Copy link
Collaborator

Try to hoist loadable plugin. I reckon plugin-syntax-dynamic-import "eats" all imports before loadable plugin.

@zhenliliu
Copy link
Author

Try to hoist loadable plugin. I reckon plugin-syntax-dynamic-import "eats" all imports before loadable plugin.

i have try do it, but it still not working

@KleinMaximus
Copy link

I have similar trouble

@theKashey
Copy link
Collaborator

I've double-checked the babel plugin code, and it seems to be legitly not working - the problem is "classical" - https://jamie.build/babel-plugin-ordering.html - different plugins are conflicting with each other.
It's easy to fix it, as explained in the linked page, but it would make loadable plugin slightly slower.
However, we don't have a choice.

@theKashey theKashey self-assigned this Nov 29, 2019
@theKashey theKashey added the bug label Nov 29, 2019
@zhenliliu
Copy link
Author

I've double-checked the babel plugin code, and it seems to be legitly not working - the problem is "classical" - https://jamie.build/babel-plugin-ordering.html - different plugins are conflicting with each other.
It's easy to fix it, as explained in the linked page, but it would make loadable plugin slightly slower.
However, we don't have a choice.

but How to fix this problem

@lovewinders
Copy link

I have similar trouble, SSR requires @loadable/babel-plugin, please install it

@theKashey
Copy link
Collaborator

@lovewinders - trouble is with @loadable/babel-plugin (however you are correct, it's required)

@lovewinders
Copy link

@lovewinders - trouble is with @loadable/babel-plugin (however you are correct, it's required)

my question issue is #484

@shad-k
Copy link

shad-k commented Dec 25, 2019

@theKashey any update on how to solve this? I am facing the same issue.

@theKashey
Copy link
Collaborator

Update: you can't solve it, there is a really small change to be made to the babel plugin, but I can't find enough time to tackle it.
However, I could do the change, open a PR, and let you test it, so we would share a feature development burden.

@shad-k
Copy link

shad-k commented Dec 26, 2019

@theKashey sure I can test it. Let me know once you've made a PR.

@theKashey
Copy link
Collaborator

theKashey commented Jan 2, 2020

The "fix" is really super simple, see PR. It would be great if any of you would just copy-paste this gist to node_modules/@loadable/babel-plugin/lib/index.js and check if it works. 99% that it is.

@1846689910
Copy link

Hi @theKashey,
Thank you for your PR. I tried your fix solution, but it seems the error is still there. BTW, I think your gist is meant to replace node_modules/@loadable/babel-plugin/lib/index.js.

@theKashey
Copy link
Collaborator

:(
Just to double check - could you edit a file with loadable to burst possible compilation cache. If it will would not work - then I would gently ask someone for an example to find the real root cause.

@chen86860
Copy link

I have the same issue while wrap @loadable-component as a function call, like so:

// Loadable component
import React from 'react'
import loadable from '@loadable/component'

export default loader => loadable(loader, { fallback: <p> Loading...</p> })

and call it from routes definition:

// routes.js
import Loadable from 'components/Loadable'

const Index = Loadable(() => import('@/pages/Index'))

after remove this wrap and import @loadbale/component directly, errors was gone:

// routes.js
import loadable from '@loadbale/component'

const Index = loadable(() => import('@/pages/Index'))

Hope to be helpful :)

@smsivaprakaash
Copy link

Hi,
I had the similar problem. Im my case i wasn't using .bablerc. I have configured bable in webpack.
webpack.config.[evn].js

module.exports = {
  mode: 'production',
  .
  .
  .
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: require.resolve('babel-loader'),
            options: {
              babelrc: false,
              plugins: ['@loadable/babel-plugin'],
            },
          },
     }
   ]
}]}
}

@tmohammad78
Copy link

tmohammad78 commented Jul 3, 2020

The "fix" is really super simple, see PR. It would be great if any of you would just copy-paste this gist to node_modules/@loadable/babel-plugin/lib/index.js and check if it works. 99% that it is.

Hi @theKashey
I have same issue and i copy-paste it but it not helped me , what can i do for solving it ?

tsconfig

{
  "compilerOptions": {
    "module": "commonjs", // for Node and export
    "target": "es2015", // version of export file it can be any version
    "outDir": "lib", // exported in the folder
    "declaration": true, // add .d.ts file in outDir
    "sourceMap": true, // add .map file outDir  . debugger  forbid implicit any
    "jsx": "react", // transform JSX
    "strict": true, //enable strict  features
    "strictNullChecks": true, //check and compile JS
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true, // forexample for testing jest
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": false, //for casing erro in the route file
    "skipLibCheck": true,
    "lib": ["es6", "dom"],
    "noImplicitReturns": true,
    "noEmit": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    // "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": false,
    "rootDir": ".",
    "allowJs": true,
    "plugins": [
      { "transform": "typescript-transform-paths" },
      { "transform": "typescript-transform-paths", "afterDeclarations": true }
    ]
  },
  "include": ["./src/**/*", "./server", "./scripts"],
  "exclude": ["node_modules"]
}

Routes.tsx

const MainAuth = loadable(() => import('../Pages/auth/main/index'), {
	fallback: <div>...loading</div>
});

babel.config

  plugins: [
    '@loadable/babel-plugin', 
             ]

server/render

	const extractor = new ChunkExtractor({ statsFile })
	// console.log('extractor', extractor)
	const sheet = new ServerStyleSheet();
	const context = {};
	const extractorNew = extractor.collectChunks(sheet.collectStyles(
		<Provider store={store}>
			<StyleSheetManager sheet={sheet.instance} >
				<StaticRouter location={req.path} context={context}>
					<div>{renderRoutes(Routes)}</div>
				</StaticRouter>
			</StyleSheetManager>
		</Provider>
	))
	const content = renderToString(
		extractorNew
	);
       ....

@suhanw
Copy link

suhanw commented Aug 5, 2020

i have this issue only when i create my own custom loadable function (per the docs):

import baseLoadable from '@loadable/component';

export const loadable = (importCb, options) => {
	return baseLoadable(
		() => importCb().then(module => {
                       // do some stuff
                       return module;
                 }),
		options
	);
}

using the library loadable function works

@EgorVasilev
Copy link

@suhanw @chen86860 Hi! I faced the same problem as you and managed to solve it via "magic-comments". If you still want to use your own custom functions you can try to use this approach too: https://loadable-components.com/docs/babel-plugin/#magic-comments

For example, based on @suhanw comment, try to call your custom loadable function like this:
loadable(/* #__LOADABLE__ */ () => import ('./someModule'), {options})

@Ephem
Copy link

Ephem commented Mar 4, 2021

I ran into this problem as well. We have a wrapper around loadable that we also call loadable so that the Babel plugin can recognise it (as per the docs), but it still didn't work and adding magic comments didn't work either.

After a while I realised we also have a lazyLoadOnVisible(() => import('...'), options) which also wraps loadable and this was the source of the problem. Adding the magic comment to those calls solved it!

So for us it's working as documented. The wrapper we call loadable works without magic comments, the wrapper that is called something else needs the magic comments to work.

So for anyone else finding this issue:

  • The babel plugin converts () => import('...') to an object with some metadata
  • If the base loadable() function gets a function instead of an object, this error happens
  • Make sure you have added the Babel plugin (and possibly check plugin ordering)
  • Make sure the plugin can recognise which () => import('...') to convert either by:
    • Wrap it in any function called loadable() OR
    • Preceded by /* #__LOADABLE__ */

@Ephem
Copy link

Ephem commented Mar 4, 2021

@suhanw Your comment is pretty old by now so you might have moved passed this already, but, I think the reason that custom function isn't working is that it passes in a function that is impossible for loadable to convert into an object.

Maybe the resolveComponent option could help you achieve the thing you want to do?

@suhanw
Copy link

suhanw commented Mar 4, 2021

Thanks @Ephem ! I honestly can't remember what I wanted to accomplish 😅 but TIL about resolveComponent

@ghost
Copy link

ghost commented Mar 6, 2021

I get this issue aswell and I have tried everything.

My components are loaded in like the following:

import loadable from '@loadable/component';

const fallback = <div>Loading</div>;

const loginPage = loadable(/* #__LOADABLE__ */ () => import('../pages/platform/LoginPage'), {
    ssr: true,
    fallback,
    resolveComponent: (component) => component.default
});

When the application is running server side it just crashed with this error. Kind of running out of ideas 🤷

@Ephem
Copy link

Ephem commented Mar 6, 2021

@negomansini I'm not sure if there are other reasons this error can happen, but from my understanding for some reason () => import('../pages/platform/LoginPage') is not getting turned into the object loadable expects somewhere in your application.

I don't think the magic comment is necessary here, but shouldn't hurt either.

Are you 100% sure the Babel plugin is added for every environment you have (in case you have separate builds for client and server for example) and that no other Babel plugin is interfering?

What helped me narrow my case down was trying to do a minimal reproduction by commenting out all routes and adding a single test route with a single loadable component on it. I hope you'll be able to figure it out! 😄

@ghost
Copy link

ghost commented Mar 6, 2021

Hey! thanks for the reply. Yeah i've only got one route active at the moment to test this. I am using Webpack 5, and this is only relating to my server side builds.

My .babelrc file is what I am using. if i remove a plugin from the list my build fails so its definitely reading from this file... I have also tried specifying the plugins at the webpack config level but still no luck... Yeah really coming to the end of what else I could try....

{
    "presets": [
        "@babel/env",
        "@babel/react",
        [
            "@babel/preset-typescript",
            {
                "onlyRemoveTypeImports": true
            }
        ]
    ],
    "plugins": [
        "@loadable/babel-plugin",
        "babel-plugin-transform-typescript-metadata",
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }],
        "@babel/plugin-proposal-nullish-coalescing-operator",
        "@babel/plugin-proposal-object-rest-spread",
        "@babel/plugin-proposal-optional-chaining",
        "@babel/plugin-transform-runtime"
    ]
}

@anshumansworld
Copy link

Not sure whether it's a correct solution but it worked in my case. I used

import loadable from "@loadable/component";
const LoadableMyComponent = loadable(() => import("../LoadableMyComponent"));

in place of

import Loadable from "@loadable/component";
const LoadableMyComponent = Loadable(() => import("../LoadableMyComponent"));

small l l instead of L is working

@miggu
Copy link

miggu commented Jul 9, 2021

IMPORTANT! In my case it was the case that there was a process deleting .babelrc which is essential for the module loading !

@shifaligupta03
Copy link

In my case, the version for @loadable/component and @loadable/server was a mismatch. I resolved it by using the same version for both packages.

@srinisoundar
Copy link

I was facing the same issue with typescript. So, I added typescript support on top of server-side-rendering example. Hope it helps someone. Server Side Rendering with TS

@pupudu
Copy link

pupudu commented Dec 29, 2021

In my case I had a typo in import loadable from "@loadable/component";

fivethreeo pushed a commit to fivethreeo/loadable-components that referenced this issue Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.