swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
31.23k stars 1.23k forks source link

Build incorrectly resolves import paths for files with multiple dots in the filename using `tsc paths resolve fully` #9591

Closed victorfreitas closed 1 month ago

victorfreitas commented 1 month ago

Describe the bug

Hi,

I've found a bug using paths containing multiple dots, and I'm using SWC on a Nestjs project; sometimes, I use filenames with more than one dot. Because of that, the output doesn't work as expected in the split_once, causing the wrong separation of the parts.

I think the bug is in this line: https://github.com/swc-project/swc/blob/main/crates/swc_ecma_loader/src/resolvers/tsc.rs#L305

Please take a look at the example below. I've changed the split_once to rsplit_once.

fn main() {
    let path = "src/common/decorators/foo-bar.decorator.ts";
    let unexpected_output = path.split_once('.').map(|v| v.0).unwrap_or(path);
    let expected_output = path.rsplit_once('.').map(|v| v.0).unwrap_or(path);

    println!(
        "unexpected_output : {:?}\nexpected_output   : {:?}",
        unexpected_output,
        expected_output
    );
}

// unexpected_output : "src/common/decorators/foo-bar"
// expected_output   : "src/common/decorators/foo-bar.decorator"

Input code

// src/foo/bar.controller.ts

import { FooBar } from '@decorator/foo-bar'

@FooBar()

Config

{
  "$schema": "https://swc.rs/schema.json",
  "sourceMaps": true,
  "minify": false,
  "isModule": true,
  "module": {
    "type": "nodenext",
    "strict": true,
    "strictMode": true,
    "noInterop": true,
    "resolveFully": true
  },
  "jsc": {
    "baseUrl": "./",
    "loose": true,
    "externalHelpers": false,
    "target": "esnext",
    "paths": {
      "#src/*": ["src/*"], // Ok
      "#common/*": ["src/common/*"], // Ok
      "#decorator/foo-bar": ["src/common/decorators/foo-bar.decorator.ts"], // Wrong output
      "#decorator/bar-baz": ["src/common/decorators/bar-baz-decorator.ts"] // Ok
    },
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true,
      "importAssertions": true,
      "tsx": false
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "minify": {
      "compress": false,
      "mangle": {
        "toplevel": true
      }
    }
  },
  "exclude": [
    "node_modules",
    "dist",
    ".*\\.js$",
    ".*\\.map$"
  ]
}

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.7.28&code=H4sIAAAAAAAAA8vMLcgvKlFQV05JTc4vSizJL9JPy8%2FXTUosUufKxJQDigPlqtQBd1OaDjcAAAA%3D&config=H4sIAAAAAAAAA31TwW7bMAy95ysCL6eite%2B9DRiK9pDjTm0xqDKTqJBFgaS7eEX%2BfZRdKXZa9GKY7z0%2FPsrU%2B2q9rjZsD9CZ6nZdHUQi3zYN%2F7U1cTMR9StjqK6TlLEnC1sTWdVCPYxo54LbDYrsjOcJcrzFtvewkGXkXSutZYipqgK2EOAoY4vURMhZmX1ZMPWEJR7wIQgQxiVMwOjf4K73fvhglDiNMV7ZnjO8GIbf5FOMuskBPCJf9NF4QMH4e%2FARiOezpkkM7SElroDnk0QjBy7NFPjBZJsrRR6r6e35ulAWuw7DjC3ATNSCRTKC1OwQb14MXaqLgLOiLlAt%2FLWXqlT57xuvD8XN0mu0OpVhiYHm0%2FIQxBzTsaRfzZZczEej7Nl9cdSJGYLpnH3oIpJckm5Ef7L2Eofh08fCx%2Fx3FvGETOAdUjdP6GFv7PArJ%2FkUJBNbENMaMeddOhuX7S%2BuenxRN%2FBiS5LUhP3sBky5MHp4Az%2B3VvNVfk5LC0fr%2B3H5H%2FPit%2FBnulGc1611XFavvnp60ou7WdSdiZtK6%2BfV6T%2BwGlfV%2BgMAAA%3D%3D

SWC Info output

Binaries:
    Node: 20.17.0
    npm: 10.8.3

Relevant Packages:
    @swc/core: 1.7.28
    @swc/helpers: 0.5.13
    @swc/types: 0.1.12
    typescript: 5.6.2

SWC Config:
    output: N/A
    .swcrc path: N/A

Next.js info:
    output: N/

Expected behavior

Correctly output ./src/common/decorators/foo-bar.decorator.js for path aliases.

Actual behavior

No response

Version

1.7.28

Additional context

No response

swc-bot commented 1 week ago

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.