swc: Path aliases don't seem to respect nested folder structure

Describe the bug After https://github.com/swc-project/swc/issues/1934 and https://github.com/swc-project/swc/issues/1935 were resolved in 1.2.76, I gave it a quick try and run into another issue.

It seems to me that paths simply rewrites the path prefix but doesn’t respect the location of given file. I also tried using baseUrl but no luck. Am I missing some configuration?

Input code Using ~ as an alias for src and having a file src/subfolder/A.ts with an import { B } from '~/subfolder/B.ts'; (and considering the src/subfolder/B.ts exists and exports B), we’ll run into Error: Cannot find module './subfolder/B'.

This is because the import was rewritten to ./subfolder/B instead of just ./B or ../subfolder/B (that should be correct as these files are in the same subfolder indeed).

The command I’m running is: yarn swc src -s -d ./dist

Config Note that baseUrl probably has no effect but I tried to add it to conform with tsconfig.json.

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
    },
    "target": "es2020",
    "baseUrl": ".",
    "paths": {
      "~/*": ["./*"]
    }
  },
  "module": {
    "type": "commonjs"
  }
}

Also note that in TypeScript the correct path in the config would be "~/*": ["./src/*"] in this case (including the src portion) since baseUrl is .. With SWC, however, I need to use just ./*, probably because I’m passing src dir to the swc command.

Expected behavior Paths should be rewritten using current file location (not just using a static prefix). In the given example the import from '~/subfolder/B.ts was rewritten to ./subfolder/B instead of just ./B (or ../subfolder/B).

Version The version of @swc/core: 1.2.76

Additional context TypeScript also uses baseUrl to set the base path relative to which imports are rewritten.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 6
  • Comments: 28 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I’ll fix this with the next version.

@JanJakes

This has no specific estimate or priority, right It has higher priority than issues without milestone.

Are the paths-related issues small fixes or large issues? I don’t expect it to be a large task.

Also, if I use es6 modules, the aliases don’t work at all. They are just left as-is.

  "module": {
    "type": "es6"
  }

@stefee I added it to the documentation.

I am doing some more testing around the issue we are experiencing - the bug seems to be more nuanced than it initially appears, and it seems to be at least tangentially related to <file ...> and --out-dir on the CLI.

We have the following file structure:

package.json
tsconfig.json
...
server
├── absolutePathTest.ts
├── datadog
│   └── tracing
│       └── init.ts
├── index.ts
└── logger.ts

If I run the following from the root dir:

swc server --config-file server/.swcrc  --out-dir dist/server --copy-files

Then the resultant file tree is this: ✅

dist
└── server
    ├── absolutePathTest.js
    ├── datadog
    │   └── tracing
    │       └── init.js
    ├── index.js
    └── logger.js

(Note in the above file tree the generated import paths are still wrong as has been previously explained in this thread, but file tree is correct.)

However, if I set cd to server and run this:

swc $PWD --config-file .swcrc --out-dir ../dist/server --copy-files  # --config-file flag is optional here

Then not only is the import path wrong, the result file tree is also incorrect: ❌

dist
└── server
    ├── absolutePathTest.js
    ├── index.js
    ├── logger.js
    └── tracing
        └── init.js

I’m not sure if this is actually the same bug, or an unrelated bug, perhaps related to #2210.

you check this also #2126

This works:

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

This does not:

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

I think the missing config option is rootDir if you want to have parity with tsconfig.

I think the baseUrl prop is missing from the docs - shall we fix that before closing this?

I have had a revelation - our .swcrc was missing the baseUrl property and only using paths. With the fix introduced in 1.2.87 this works as expected if we add the baseUrl. 🎉

I have updated my repro repository to include repro-3 and repro-4 which are identical to repro-1 and repro-2 but include the baseUrl - you can see that this resolves the issue and now dist has the correct import path.

However, the issue described in my comment about file trees is still present, even with baseUrl. I think this should be addressed as a separate issue - this issue is also not a blocker for us since we can just use swc server instead of swc . or swc $PWD.

@vjpr Woops! Try again now.

Here’s our repro: stefee/swc-issue-repro-2050

Repo not accessible.

@schmod I don’t think that’s related to this issue, you may want to create a new one, I guess. There is also https://github.com/swc-project/swc/issues/1943 but that’s about emitting to ES-style imports so I guess it’s not related either.

Also worth noting that SWC currently only appears to transform ES-style imports.

Paths are not resolved for CJS imports with require('~/file.ts')