faceyspacey / react-universal-component

🚀 The final answer to a React Universal Component: simultaneous SSR + Code Splitting
MIT License
1.7k stars 80 forks source link

Static component import not working #191

Open theonelucas opened 5 years ago

theonelucas commented 5 years ago

According to this line of code, the component can either be a string or a component:

typeof page === 'string' ? import(`./${page}`) : () => page()

But when we try to import the component:

import Page1 from '../components/Page1'

const components = {
  HOME: 'Home',
  PAGE1: Page1,
  [NOT_FOUND]: 'NotFound'
}

An error is being returned:

Error: load is not a function

How the component should be imported?

tstirrat15 commented 5 years ago

Where is your import statement?

theonelucas commented 5 years ago

Where is your import statement?

import Page1 from '../components/Page1'

tstirrat15 commented 5 years ago

Right, that's a synchronous import that isn't covered by this component. The import() function and the import x from 'y' statement are two different things. To use this component, you need to be using the function:

const ListingPage = universal(import('./listing/components/Root'), { onError: exceptionHandler });

That sort of thing.

theonelucas commented 5 years ago

So, basically I cannot pass a component already imported to Universal?

tstirrat15 commented 5 years ago

I'm not completely certain of whether you can or not, but I'd question why you'd want to.

An import foo from 'bar' statement says "load this code when this statement is encountered." For a bundler, that means "add this code to the current bundle," and in an environment like node, that means "go get this code right now if it hasn't already been gotten." import statements are hoisted to the top of the file and are executed on the first walk of the code tree.

An import('bar') call says "create a placeholder for an asynchronous import." For a bundler, this means that it marks that spot as the start of a new bundle, and includes code to go fetch that new bundle. In an environment like node, it's an asynchronous require statement, more or less.

My guess is that you're wanting to use this library for code splitting. In that case, if you're using the import statement, you're losing out on the whole reason that you'd want to use this library. Does that make sense?

theonelucas commented 5 years ago

That makes sense, but what I'm aiming here is to do an incremental code splitting. Some routes, which I would explicitly pass an previously imported component, would just use it, but the other routes with a string as the component would fetch it at runtime. That way I can really leverage the power of code splitting, bundling some pages that will always be used and fetching the others as needed.

tstirrat15 commented 5 years ago

You'll need to refactor the calling code in that case. One way to do it with your example given above would be to replace the string references to components above with the RUC instances.