14

Would like to be able to import any component in the components directory, directly from the components directory.

The current directory structure is:

src
├── components
│   ├── Camera.tsx
│   ├── Keyboard.tsx
│   └── index.ts
└── screens
    └── App.tsx

And would like to be able to import as follows:

// src/screens/App.tsx

import { Keyboard } from '../components'

The first option is obviously to maintain a long list of exports in src/components/index.ts:

// src/components/index.ts

export { Camera } from './Camera'
export { Keyboard } from './Keyboard'

However, this is cumbersome to maintain. Is there a way using glob and the export object to automagically export all components, or possibly another way all together?

thecartesianman
  • 745
  • 1
  • 6
  • 15
  • No, this is not possible. You can only import from modules, not directories. But you can export everything from a path. This has already been asked here: https://stackoverflow.com/questions/40702842/how-to-import-all-modules-from-a-directory-in-typescript – majusebetter Oct 05 '21 at 10:27
  • I wasn't asking to import a directory, I was asking for a 'hack' to 'automagically' make it seem like I could. – thecartesianman Oct 05 '21 at 10:56
  • However, thanks for sharing the previous question. It turns out this is possible. Someone there posted a solution. – thecartesianman Oct 05 '21 at 10:57
  • You'll have to resort to re-exporting the objects like you have at the moment. If it does ever become cumbersome to maintain, then reconsider whether this should all be part of the same module. It shouldn't be that annoying to maintain for small enough modules. – David Callanan Oct 05 '21 at 11:38
  • Write a script that generates the file. – Evert Oct 05 '21 at 11:51
  • If your question is solved, please accept the solution. The ✔ is below the ▲/▼ arrow, at the top left of the answer. A new solution can be accepted if a better one shows up. You may also vote on the usefulness of an answer with the ▲/▼ arrow. Leave a comment if a solution doesn't answer the question. – nima Oct 07 '21 at 08:13

3 Answers3

12

You could achieve that by editing your index.ts to be like this

src
├── components
│   ├── Camera.tsx
│   ├── Keyboard.tsx
│   └── index.ts <=== this file
└── screens
    └── App.tsx
export * from './Camera'
export * from './Keyboard'
Joseph
  • 5,644
  • 3
  • 18
  • 44
  • just curious as to when this became possible, or perhaps this is a typescript only thing, I remember the best way used to be to import and then export but I really like this short hand way! – Max Carroll Sep 12 '22 at 13:32
5

Since you are using TypeScript, why not just use the paths in TsConfig like described here?

Jiri Kralovec
  • 1,487
  • 1
  • 10
  • 18
4

In this case, you need to create an index.ts file in your components directory.

First, import all of your components in it:

import Camera from './Camera'
import Keyboard from './Keyboard'
// and so on for other components

Now, export all of them:

import Camera from './Camera'
import Keyboard from './Keyboard'

export Camera;
export Keyboard;

This can be simplified in this way:

export Camera from './Camera'
export Keyboard from './Keyboard'

Finally, use the './components' path to import the Camera and other components as well:

import { Keyboard, Camera } from '../components'

Note 1: Using this type of imports/exports will cause problems with code splitting or using Suspense/Lazy methods.

Note 2: debugging will be harder with a general index file.

nima
  • 7,796
  • 12
  • 36
  • 53
  • 1
    I have basically identical setup. On `export Camera;` I get `Declaration or statement expected.ts(1128)` any idea why? – Kip Feb 13 '22 at 03:29
  • 3
    Figured it out, it was because my Camera.ts did `export default class Camera {.....}` so my index.ts needed to be `export {default as Camera} from './Camera';` – Kip Feb 13 '22 at 04:04
  • 1
    You have detailed the solution I mentioned in the question that I was trying to avoid. Hence this is not useful. – thecartesianman Jun 04 '22 at 13:02
  • 1
    For anyone using the code above, and running on typescript@2.4+ (_and probably before_), you can drop the `imports`, unless you are using the object elsewhere in your `index.ts` file. If you did import them, you could also then short-hand the export like so: `export { Keyboard, Camera }` – DoubleA Jan 07 '23 at 00:59