jabuj
jabuj

Reputation: 3649

How to force Nextjs to create a chunk for particular module?

I'm trying to use dynamic import for importing a different modules depending on the props passed to the component. Paths to the components are kept in an object

const components = {
    'apple': './Apple.js',
    'orange': './Orange.js',
    // ...
}

Then

// ...
import(components[this.props.type])
// ...

Unfortunately, I get the following error:

Unhandled Rejection (Error): Cannot find module './Apple.js'

It disappears when I explicitly specify the filename (import('./Apple.js')). Is it possible to force nextjs to serve these dynamic modules?

Upvotes: 2

Views: 4000

Answers (2)

nawfel bgh
nawfel bgh

Reputation: 1552

You can tell webpack to put a dynamically named module inside a particular chunk using this syntax:

const module = await import(
    /* webpackChunkName: "your_custom_chunk_name" */
    "path/to/your/module"
);

Webpack will extract your module's code inside the file: /.next/server/chunks/your_custom_chunk_name.js.

(Tested on NextJs version 12.1.6)

Upvotes: 0

Andrei  Belokopytov
Andrei Belokopytov

Reputation: 1081

You need to use the dynamic utility from next/dynamic for dynamic import in Next.js. This function is inspired by react-loadable library and uses similar syntax.

The simplest way to dynamically import React component in Next.js is:

const DynamicComponent1 = dynamic(import('../components/hello1'))

If you want to import module that is not a React component than you need to use customizing rendering feature:

const DynamicDeliveryOptions = dynamic({
  loader: () => import('../components/delivery-options'),
  render(props, loaded) {
    const options = loaded.deliveryOptions.map(
      option => <option key={option.id}>{option.title}</option>
    );
    return <select>{options}</select>
  },
});

Notice that signature of the render function in Next.js is different from its signature in react-loadable library (props is the first argument in Next.js).

Returning to your example: I think the best way to import multiple modules will be to declare them all as dynamic modules and conditionally render depending on the passed props (modules won't be loaded before render).

Upvotes: 2

Related Questions