0

I am using Next.js for React. I like how Arc (other react boilerplate) dynamically imports components without requiring developer to specify path.

import { Input, Label, Field, HomePage, PageTemplate } from 'components' 

Folder structure may look somewhat like this:

components
|_ index.js
|_ atoms
  |_ Input
  |__ index.js
|_ molecules
|_ organisms
|_ templates

and I'd like to import it like:

import { Input } from 'components'

Code that is used for dynamic import: components/index.js

const req = require.context('.', true, /\.\/[^/]+\/[^/]+\/index\.js$/)

req.keys().forEach((key) => {
  const componentName = key.replace(/^.+\/([^/]+)\/index\.js/, '$1')
  module.exports[componentName] = req(key).default
})

However it doesn't work. The error I get:

Module not found: Error: Cannot resolve module 'components'...

The issue is that require.context is not available on serverside. I suppose I need to specify this path to be imported like this in loader config. Can anybody share a hint on how is this done properly?

2
  • 1
    Why dont you make your /components/index.js export all components in the folder? Commented May 24, 2017 at 13:27
  • @Robsonsjre can you please link reference or show example of that? Btw, how does that work in background? Does it ruin performances or memory consumption? Next.js does SSR by default, rendering only what is imported. Commented May 24, 2017 at 13:40

2 Answers 2

1

I don't think there is a simple and reliable way to do what you want with Next.js

The standard/"correct" answer is to use a relative path to import your local components. It is a bit more boilerplate, but I think you'll ultimately find it to be less work than fighting with Next.js to make it do things the Arc way.


To followup on @Robsonsjre's suggestion:

Why dont you make your /components/index.js export all components in the folder?

I think there is an implied "you write that index.js file". For your example, it would look something like this:

export {default as Input } from './atoms/Input';
export {default as Foo } from './molecules/Foo';
// etc

The catch is that you'd have to remember to update this file every time you add or remove a component. It's probably possible to automate that, but I'm not aware of any system to do it off the top of my head.

Sign up to request clarification or add additional context in comments.

1 Comment

My current workaround is to drop atomic design and to put all my components into same folder. However, I added aliasing into babel file. So I can import stuff like import MyComponent from '~components/MyComponent' or import { myAction } from '~redux/input/actions`
1

This way is not exactly what you want, but works similar, well for performance because its only object pointers to imported components

//Input.js
class Input extends Component {
  render() {
   return <div>'input'</div>
  }
}
export default Input

//index.js
export { default as Input } from './Input/Input'

//otherComponent.js
import { Input } from './components' //path to folder components

1 Comment

It seems like adding more steps than using vanilla way rather than reducing it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.