2

I have the following directory structure:

.
├── \ .babelrc
├── README.md
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   ├── icon128.png
│   ├── icon16.png
│   ├── icon48.png
│   ├── manifest.json
│   └── popup.html
├── src
│   ├── App.tsx
│   ├── background.ts
│   ├── components
│   │   ├── Main.tsx
│   │   ├── Options.tsx
│   │   ├── SiteImage.tsx
│   │   ├── TrafficSignal.tsx
│   │   └── index.ts
│   ├── content.ts
│   ├── custom.d.ts
│   ├── popup.tsx
│   ├── store
│   │   ├── FrameItContext.tsx
│   │   ├── FrameItStore.ts
│   │   └── index.ts
│   ├── styles
│   │   ├── popup.css
│   │   └── tailwind.css
│   └── types
│       └── index.ts
├── tailwind.config.js
├── tsconfig.json
└── webpack.config.js

And tsconfig.json looks like:

{
    "compilerOptions": {
        "baseUrl": "node_modules",
        "paths": {
            "@/*": ["../src/*"]
        },
        "outDir": "./dist/",
        "sourceMap": true,
        "strict": true,
        "noImplicitReturns": true,
        "noImplicitAny": true,
        "module": "es6",
        "moduleResolution": "node",
        "target": "es5",
        "allowJs": true,
        "jsx": "react",
    },
    "exclude": ["node_modules"],
    "include": [
        "./src/**/*",
        "src/custom.d.ts"
    ]
}

My App.tsx looks like:

import { Main } from '@/components/index'
import { config, FrameItProvider } from '@/store/index'

TS error looks like:

ERROR in ./src/App.tsx 2:0-42
Module not found: Error: Can't resolve '@/components/index'

ERROR in ./src/App.tsx 3:0-48
Module not found: Error: Can't resolve '@/store/index'

How do I solve this? I'm following Next.js absolute imports structure.

Even tried doing:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        },
}

But it still gives error. How do I solve it?

I have webpack.config.js too, which looks like:

const webpack = require('webpack')
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin')

const config = {
  entry: {
    popup: path.join(__dirname, 'src/popup.tsx'),
    content: path.join(__dirname, 'src/content.ts'),
    background: path.join(__dirname, 'src/background.ts'),
  },
  output: { path: path.join(__dirname, 'dist'), filename: '[name].js' },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
        exclude: /\.module\.css$/,
      },
      {
        test: /\.ts(x)?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              modules: true,
            },
          },
        ],
        include: /\.module\.css$/,
      },
      {
        test: /\.svg$/,
        use: 'file-loader',
      },
      {
        test: /\.png$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              mimetype: 'image/png',
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx', '.tsx', '.ts'],
    alias: {
      'react-dom': '@hot-loader/react-dom',
    },
  },
  devServer: {
    contentBase: './dist',
  },
  plugins: [
    new CopyPlugin({
      patterns: [{ from: 'public', to: '.' }],
    }),
  ],
}

module.exports = config

Do I have to specify anything in webpack.config.js? Because VSCode autocomplete is working just fine.

6
  • Did you try "@/*": ["src/*"] ? Commented Dec 22, 2020 at 7:40
  • @KevinZhang I did just now with baseUrl as . & node_modules but doesn't work. I mean VSCode autocomplete works but the Webpack throws error so maybe it's a Webpack issue? Commented Dec 22, 2020 at 7:44
  • set baseUrl as ., and meantime set paths as { "@/*": ["src/*"] } Commented Dec 22, 2020 at 7:46
  • @KevinZhang i did that already. i did try both combinations Commented Dec 22, 2020 at 7:49
  • 1
    @KevinZhang the issue was with webpack. i solved it thanks to decembersoft.com/posts/… i'll post an answer once i find an efficient way :) Commented Dec 22, 2020 at 8:01

1 Answer 1

1

It was a webpack issue, not TS which I found through https://decembersoft.com/posts/say-goodbye-to-relative-paths-in-typescript-imports/

I kept tsconfig.json as it is:

{
    "compilerOptions": {
        "baseUrl": "node_modules",
        "paths": {
            "@/*": ["../src/*"],
        },
}

And I had to add the following code to webpack.config.js:

const fs = require('fs')

const srcPath = (subdir) => path.join(__dirname, 'src', subdir)
const getFilesAndDirectories = (source) =>
    fs.readdirSync(source, { withFileTypes: true }).map((dirent) => dirent.name)
let absoluteImports = {}
getFilesAndDirectories('src').forEach((fileName) => {
    const fileNameWithoutExtension = path.parse(fileName).name
    absoluteImports[`@/${fileNameWithoutExtension}`] = srcPath(fileName)
})

const config = {
    .
    .
    .
    resolve: {
        alias: {
            'react-dom': '@hot-loader/react-dom',
            ...absoluteImports,
        },
    },
}

That did the trick 🎉

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

Comments

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.