react-imported-component icon indicating copy to clipboard operation
react-imported-component copied to clipboard

Client side only import executing on server when using SSR

Open beleidy opened this issue 5 years ago • 1 comments

I'm trying out react-imported-component in a demo app before using it in a production app, and hit the following block.

I have an About component that I'm importing as follows:

const About = importComponent(() => import(/* client-side */ "./About"), {
  LoadingComponent,
  ErrorComponent,
});

My understanding is that this would cause the About component to only be imported on the client side and thus never executed on the server side. However I have a console.log statement in the About component that prints out on the server side.

My imported.js file looks like this:


    /* eslint-disable */
    /* tslint:disable */
    
    // generated by react-imported-component, DO NOT EDIT     
    import {assignImportedComponents} from 'react-imported-component/macro';    
    
    // all your imports are defined here
    // all, even the ones you tried to hide in comments (that's the cost of making a very fast parser)
    // to remove any import from here
    // 1) use magic comment `import(/* client-side */ './myFile')` - and it will disappear
    // 2) use file filter to ignore specific locations (refer to the README)
    
    const applicationImports = assignImportedComponents([
           [() => import(/* client-side */'./About'), '', './app/About', true],
    ]);
    
    export default applicationImports;
    
    // @ts-ignore
    if (module.hot) {
       // these imports would make this module a parent for the imported modules.
       // but this is just a helper - so ignore(and accept!) all updates
       
       // @ts-ignore
       module.hot.accept(() => null);
    }  

I find the following confusing. In the imported.js comment number 1), it says if I use the magic comment /* client-side */ it would disappear from the file, however as you can see it doesn't.

On the other hand if I understood correctly, in __tests__/utils.spec.ts line 21 the test checks that a client-side import should be mapped to the value at line 30.

Can you please advise as to which behaviour from the above is expected, and how to get client-side only imports to work? Thank you

beleidy avatar Jun 10 '20 21:06 beleidy

"client-side" magic comment is suppressing import auto execution on the server side - by default all found import would be called before the render, so you will be able to render your application synchronously, and not all components could be run on a server.

However that would not block those modules/components from being used - you still can try to render them, and they will be rendered. Here you need something like NoSSR in Material-UI.

const NoSSR = ({children}) => {
 const [locked, setLocked] = useState(true);
 useEffect(() => setLocked(false), []); // unlock on the client-side
 return locked ? null : children;
}

Check https://github.com/theKashey/react-imported-component/issues/47 for other solutions.

Frankly speaking trying to render client-side only component should fail the first render, as long as it's not "ready".

theKashey avatar Jun 11 '20 03:06 theKashey