5

Given this folder structure:

├──components/
|  └─Elements/
|    └─Button/
|    └─Input/
|    └─index.ts
|  └─Home/
|    └─home.tsx

I would like to export Button and Input so I can access them from the home component by doing:

home.tsx

import { Button, Input } from '@elements/'

I have tried this:

index.ts (in Elements folder)

export { Button } from './Button/button';
export { Input } from './Input/input';

But it does not work, I get: Cannot find module '@elements/' or its corresponding type declarations. even thou the resolve alias does work.

tsconfig.json

{
  "compilerOptions": {
    "outDir": "../public",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "baseUrl": "./",
    "rootDir": "./",
    "typeRoots": ["./node_modules/@types", "./src/@types"],
    "paths": {
      "@src/*": ["src/*"],
      "@images/*": ["src/images/*"],
      "@styles/*": ["src/styles/*"],
      "@components/*": ["src/components/*"],
      "@elements/*": ["src/components/Elements/*"],
    },
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "importsNotUsedAsValues": "preserve"
  },
  "exclude": ["node_modules", "webpack"]
}

webpack.config.babel.js

...
resolve: {
  alias: [
    '@src': join(rootDir, '/src'),
    '@images': join(rootDir, '/src/images'),
    '@assets': join(rootDir, '/src/assets'),
    '@styles': join(rootDir, '/src/styles'),
    '@components': join(rootDir, '/src/components'),
    '@elements': join(rootDir, '/src/components/Elements')
  ]
  extensions: ['.tsx', '.ts', '.js', '.jsx']
},

5
  • @elements alias works if I import a single component Commented Jan 24, 2021 at 13:40
  • 1
    I see, yes it has to do with that I changed it to ../Elements and now it works Commented Jan 24, 2021 at 13:41
  • 1
    @T.J Crowder, in TypeScript "paths": { "@elements/*": ["src/components/Elements/*"]} and in webpack resolve: { alias :'@elements': join(rootDir, '/src/components/Elements')... Commented Jan 24, 2021 at 13:43
  • @T.J Crowder, I do not understand why it wont work with @elements, it works if I import a single component with import { Button } from '@elements/Button' Commented Jan 24, 2021 at 13:53
  • 2
    I fix it by doing "@elements/*": ["src/components/Elements/"], basically removing the * from the path Commented Jan 24, 2021 at 14:16

3 Answers 3

3

I found the solution to be removing the * from the path declaration on tsconfig.json

This

"@elements/*": ["src/components/Elements/"]

Instead of this

"@elements/*": ["src/components/Elements/*"]

And then importing it by using

import { Button, Input } from '@elements/'

or

"@elements": ["src/components/Elements"]
import { Button, Input } from '@elements'
Sign up to request clarification or add additional context in comments.

6 Comments

That worked for me as well. Since the documentation shows those * in the target, I suggest raising a documentation bug report.
@Alvaro Is this correct "@src/*": ["src*"], ? I mean it should be ["src/*"] ?
Subro, you are correct, I never really used the @src alias but it was wrong
I have edited the answer to address just that
Oh thats works too I would go with 2nd approach. Btw nice config file.
|
1
import { Button } from './Button/button';
import { Input } from './Input/input';

should probably be

export { Button } from './Button/button';
export { Input } from './Input/input';

If they are default exports, you have to do this.

export { default as Button } from './Button/button';
export { default as Input } from './Input/input';

Comments

0

Module resolution in Typescript is the process that the compiler uses to figure out what an import refers to. You can read more on module resolution in the Typescript Handbook.

import { Button } from './Button/button';

This type of import is called a relative import. A relative import is one that starts with /, ./ or ../.

Any other import is considered non-relative. Some examples include:

import * as $ from "jquery";
import { Component } from "@angular/core";

There is two module resolution strategy in typescript which is node and classic. By default module resolution is set to classic.

Set the module resolution to node would solve your problem.

"moduleResoution": "node"

Note: node module resolution is the most-commonly used in the TypeScript community and is recommended for most projects. If you are having resolution problems with imports and exports in TypeScript, try setting moduleResolution: "node" to see if it fixes the issue.

4 Comments

Setting "moduleResolution": "node" in tsconfig.json didn't fix this for me.
@Subro, thanks for the response, I already have "moduleResolution": "node" on my tsconfig, but still if I import a single component it works but not with two
Did you get it to work with @elements and with two components?
@Álvaro - (If that was in response to my saying I couldn't get it to work even with one component in my non-deleted comment.) No, I can't get it to work with one component, two components, etc. I figure there's just something I'm missing, though, TS config isn't my strong suit.

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.