Repository: swc-project/swc (rust)

Issue:
Aliases (paths) are incorrectly resolved
### Describe the bug

The issue started happening after upgrading `@swc/core` from `1.4.2` to `1.4.4`.
The compilation now doesn't seem to take into account the relative part of an alias and simply insert the alias itself.

We're using NestJs.

### Input code

```typescript
import { AppController } from '@app/app.controller';
import { AppService } from '@app/app.service';
```


### Config

_No response_

### Playground link (or link to the minimal reproduction)

https://github.com/dmitriy-kudelko/swc-paths

### SWC Info output

    Operating System:
        Platform: darwin
        Arch: arm64
        Machine Type: arm64
        Version: Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000
        CPU: (10 cores)
            Models: Apple M1 Max

    Binaries:
        Node: 20.11.0
        npm: 10.2.4
        Yarn: 1.22.19
        pnpm: 8.15.4

    Relevant Packages:
        @swc/core: 1.4.4
        @swc/helpers: N/A
        @swc/types: 0.1.5
        typescript: 5.3.3

    SWC Config:
        output: N/A
        .swcrc path: N/A

    Next.js info:
        output: N/A

### Expected behavior

Previously the compiled code looked like this, and worked fine:

```ts
const _appcontroller = require("./app.controller");
const _appservice = require("./app.service");
```

### Actual behavior

The compiled output now looks like the following, and so module resolution fails:

```ts
const _appcontroller = require("src/app.controller");
const _appservice = require("src/app.service");
```

### Version

1.4.4

### Additional context

_No response_

Pull request description:
fix(es/module): Fix relativeness check for `jsc.paths`
**Description:**



**Related issue:**

 - Closes #8701

Patch:
diff --git a/crates/swc_ecma_transforms_module/src/path.rs b/crates/swc_ecma_transforms_module/src/path.rs
index a7a23766a8..2150debd01 100644
--- a/crates/swc_ecma_transforms_module/src/path.rs
+++ b/crates/swc_ecma_transforms_module/src/path.rs
@@ -259,14 +259,7 @@ where
         info!("Resolved as {target:?} with slug = {slug:?}");
 
         let mut target = match target {
-            FileName::Real(v) => {
-                // @nestjs/common should be preserved as a whole
-                if v.starts_with(".") || v.starts_with("..") || v.is_absolute() {
-                    v
-                } else {
-                    return Ok(self.to_specifier(v, slug));
-                }
-            }
+            FileName::Real(v) => v,
             FileName::Custom(s) => return Ok(self.to_specifier(s.into(), slug)),
             _ => {
                 unreachable!(


Test patch:
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/.swcrc
new file mode 100644
index 0000000000..0975fef780
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/.swcrc
@@ -0,0 +1,15 @@
+{
+    "$schema": "http://json.schemastore.org/swcrc",
+    "jsc": {
+        "baseUrl": ".",
+        "paths": {
+            "@app/*": [
+                "./src/*"
+            ]
+        },
+        "parser": {
+            "syntax": "typescript",
+            "decorators": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.spec.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.spec.ts
new file mode 100644
index 0000000000..b7bb7163ab
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.spec.ts
@@ -0,0 +1,21 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppController } from './app.controller';
+import { AppService } from './app.service';
+
+describe('AppController', () => {
+  let app: TestingModule;
+
+  beforeAll(async () => {
+    app = await Test.createTestingModule({
+      controllers: [AppController],
+      providers: [AppService],
+    }).compile();
+  });
+
+  describe('getHello', () => {
+    it('should return "Hello World!"', () => {
+      const appController = app.get(AppController);
+      expect(appController.getHello()).toBe('Hello World!');
+    });
+  });
+});
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.ts
new file mode 100644
index 0000000000..cce879ee62
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.controller.ts
@@ -0,0 +1,12 @@
+import { Controller, Get } from '@nestjs/common';
+import { AppService } from './app.service';
+
+@Controller()
+export class AppController {
+  constructor(private readonly appService: AppService) {}
+
+  @Get()
+  getHello(): string {
+    return this.appService.getHello();
+  }
+}
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.module.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.module.ts
new file mode 100644
index 0000000000..4f209a8a4f
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.module.ts
@@ -0,0 +1,10 @@
+import { Module } from '@nestjs/common';
+import { AppController } from '@app/app.controller';
+import { AppService } from '@app/app.service';
+
+@Module({
+  imports: [],
+  controllers: [AppController],
+  providers: [AppService],
+})
+export class AppModule {}
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.service.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.service.ts
new file mode 100644
index 0000000000..927d7cca0b
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/app.service.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class AppService {
+  getHello(): string {
+    return 'Hello World!';
+  }
+}
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/main.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/main.ts
new file mode 100644
index 0000000000..13cad38cff
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/input/src/main.ts
@@ -0,0 +1,8 @@
+import { NestFactory } from '@nestjs/core';
+import { AppModule } from './app.module';
+
+async function bootstrap() {
+  const app = await NestFactory.create(AppModule);
+  await app.listen(3000);
+}
+bootstrap();
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.spec.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.spec.ts
new file mode 100644
index 0000000000..acfd162f01
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.spec.ts
@@ -0,0 +1,37 @@
+import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
+import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
+import { Test } from "@nestjs/testing";
+import { AppController } from "./app.controller";
+import { AppService } from "./app.service";
+describe("AppController", function() {
+    var app;
+    beforeAll(/*#__PURE__*/ _async_to_generator(function() {
+        return _ts_generator(this, function(_state) {
+            switch(_state.label){
+                case 0:
+                    return [
+                        4,
+                        Test.createTestingModule({
+                            controllers: [
+                                AppController
+                            ],
+                            providers: [
+                                AppService
+                            ]
+                        }).compile()
+                    ];
+                case 1:
+                    app = _state.sent();
+                    return [
+                        2
+                    ];
+            }
+        });
+    }));
+    describe("getHello", function() {
+        it('should return "Hello World!"', function() {
+            var appController = app.get(AppController);
+            expect(appController.getHello()).toBe("Hello World!");
+        });
+    });
+});
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.ts
new file mode 100644
index 0000000000..5e649af10a
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.controller.ts
@@ -0,0 +1,28 @@
+import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
+import { _ as _create_class } from "@swc/helpers/_/_create_class";
+import { _ as _define_property } from "@swc/helpers/_/_define_property";
+import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
+import { Controller, Get } from "@nestjs/common";
+export var AppController = /*#__PURE__*/ function() {
+    "use strict";
+    function AppController(appService) {
+        _class_call_check(this, AppController);
+        _define_property(this, "appService", void 0);
+        this.appService = appService;
+    }
+    _create_class(AppController, [
+        {
+            key: "getHello",
+            value: function getHello() {
+                return this.appService.getHello();
+            }
+        }
+    ]);
+    return AppController;
+}();
+_ts_decorate([
+    Get()
+], AppController.prototype, "getHello", null);
+AppController = _ts_decorate([
+    Controller()
+], AppController);
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.module.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.module.ts
new file mode 100644
index 0000000000..0a1135cef9
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.module.ts
@@ -0,0 +1,20 @@
+import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
+import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
+import { Module } from "@nestjs/common";
+import { AppController } from "./app.controller";
+import { AppService } from "./app.service";
+export var AppModule = function AppModule() {
+    "use strict";
+    _class_call_check(this, AppModule);
+};
+AppModule = _ts_decorate([
+    Module({
+        imports: [],
+        controllers: [
+            AppController
+        ],
+        providers: [
+            AppService
+        ]
+    })
+], AppModule);
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.service.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.service.ts
new file mode 100644
index 0000000000..7997c7a93d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/app.service.ts
@@ -0,0 +1,22 @@
+import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
+import { _ as _create_class } from "@swc/helpers/_/_create_class";
+import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
+import { Injectable } from "@nestjs/common";
+export var AppService = /*#__PURE__*/ function() {
+    "use strict";
+    function AppService() {
+        _class_call_check(this, AppService);
+    }
+    _create_class(AppService, [
+        {
+            key: "getHello",
+            value: function getHello() {
+                return "Hello World!";
+            }
+        }
+    ]);
+    return AppService;
+}();
+AppService = _ts_decorate([
+    Injectable()
+], AppService);
diff --git a/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/main.ts b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/main.ts
new file mode 100644
index 0000000000..4560044a71
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8701/1/output/src/main.ts
@@ -0,0 +1,34 @@
+import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
+import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
+import { NestFactory } from "@nestjs/core";
+import { AppModule } from "./app.module";
+function bootstrap() {
+    return _bootstrap.apply(this, arguments);
+}
+function _bootstrap() {
+    _bootstrap = _async_to_generator(function() {
+        var app;
+        return _ts_generator(this, function(_state) {
+            switch(_state.label){
+                case 0:
+                    return [
+                        4,
+                        NestFactory.create(AppModule)
+                    ];
+                case 1:
+                    app = _state.sent();
+                    return [
+                        4,
+                        app.listen(3000)
+                    ];
+                case 2:
+                    _state.sent();
+                    return [
+                        2
+                    ];
+            }
+        });
+    });
+    return _bootstrap.apply(this, arguments);
+}
+bootstrap();
diff --git a/crates/swc/tests/projects.rs b/crates/swc/tests/projects.rs
index c95aea9c2c..10e2da2da6 100644
--- a/crates/swc/tests/projects.rs
+++ b/crates/swc/tests/projects.rs
@@ -8,8 +8,8 @@ use anyhow::Context;
 use rayon::prelude::*;
 use swc::{
     config::{
-        Config, FileMatcher, JsMinifyOptions, JscConfig, ModuleConfig, Options, SourceMapsConfig,
-        TransformConfig,
+        Config, FileMatcher, JsMinifyOptions, JscConfig, ModuleConfig, Options, Paths,
+        SourceMapsConfig, TransformConfig,
     },
     try_with_handler, BoolOrDataConfig, Compiler, TransformOutput,
 };
@@ -65,7 +65,16 @@ fn file_with_opt(filename: &str, options: Options) -> Result<NormalizedOutput, S
 }
 
 fn str_with_opt(content: &str, options: Options) -> Result<NormalizedOutput, StdErr> {
-    compile_str(FileName::Anon, content, options).map(|v| v.code.into())
+    compile_str(
+        if options.filename.is_empty() {
+            FileName::Anon
+        } else {
+            FileName::Real(PathBuf::from(&options.filename))
+        },
+        content,
+        options,
+    )
+    .map(|v| v.code.into())
 }
 
 fn compile_str(
@@ -1155,6 +1164,50 @@ fn issue_8674_1() {
     assert_eq!(output.to_string(), "import { foo } from \"./src/foo\";\n");
 }
 
+#[test]
+fn issue_8701_1() {
+    static INPUT: &str = "import { AppController } from '@app/app.controller';
+    import { AppService } from '@app/app.service';
+    
+    console.log(AppController, AppService);";
+
+    let base_url = current_dir()
+        .unwrap()
+        .join("tests/projects/issue-8701")
+        .canonicalize()
+        .unwrap();
+
+    dbg!(&base_url);
+
+    let output = str_with_opt(
+        INPUT,
+        Options {
+            filename: "src/app.module.ts".into(),
+            config: Config {
+                jsc: JscConfig {
+                    base_url,
+                    paths: {
+                        let mut paths = Paths::default();
+                        paths.insert("@app/*".into(), vec!["./src/*".into()]);
+                        paths
+                    },
+                    ..Default::default()
+                },
+                ..Default::default()
+            },
+            ..Default::default()
+        },
+    )
+    .unwrap();
+    println!("{}", output);
+
+    assert_eq!(
+        output.to_string(),
+        "import { AppController } from \"./app.controller\";\nimport { AppService } from \
+         \"./app.service\";\nconsole.log(AppController, AppService);\n"
+    );
+}
+
 #[testing::fixture("tests/minify/**/input.js")]
 fn minify(input_js: PathBuf) {
     let input_dir = input_js.parent().unwrap();
diff --git a/crates/swc/tests/projects/issue-8701/src/app.controller.spec.ts b/crates/swc/tests/projects/issue-8701/src/app.controller.spec.ts
new file mode 100644
index 0000000000..b7bb7163ab
--- /dev/null
+++ b/crates/swc/tests/projects/issue-8701/src/app.controller.spec.ts
@@ -0,0 +1,21 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppController } from './app.controller';
+import { AppService } from './app.service';
+
+describe('AppController', () => {
+  let app: TestingModule;
+
+  beforeAll(async () => {
+    app = await Test.createTestingModule({
+      controllers: [AppController],
+      providers: [AppService],
+    }).compile();
+  });
+
+  describe('getHello', () => {
+    it('should return "Hello World!"', () => {
+      const appController = app.get(AppController);
+      expect(appController.getHello()).toBe('Hello World!');
+    });
+  });
+});
diff --git a/crates/swc/tests/projects/issue-8701/src/app.controller.ts b/crates/swc/tests/projects/issue-8701/src/app.controller.ts
new file mode 100644
index 0000000000..cce879ee62
--- /dev/null
+++ b/crates/swc/tests/projects/issue-8701/src/app.controller.ts
@@ -0,0 +1,12 @@
+import { Controller, Get } from '@nestjs/common';
+import { AppService } from './app.service';
+
+@Controller()
+export class AppController {
+  constructor(private readonly appService: AppService) {}
+
+  @Get()
+  getHello(): string {
+    return this.appService.getHello();
+  }
+}
diff --git a/crates/swc/tests/projects/issue-8701/src/app.module.ts b/crates/swc/tests/projects/issue-8701/src/app.module.ts
new file mode 100644
index 0000000000..521408ad9d
--- /dev/null
+++ b/crates/swc/tests/projects/issue-8701/src/app.module.ts
@@ -0,0 +1,9 @@
+import { Module } from '@nestjs/common';
+import { AppController } from '@app/app.controller';
+import { AppService } from '@app/app.service';
+@Module({
+  imports: [],
+  controllers: [AppController],
+  providers: [AppService],
+})
+export class AppModule { }
diff --git a/crates/swc/tests/projects/issue-8701/src/app.service.ts b/crates/swc/tests/projects/issue-8701/src/app.service.ts
new file mode 100644
index 0000000000..927d7cca0b
--- /dev/null
+++ b/crates/swc/tests/projects/issue-8701/src/app.service.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class AppService {
+  getHello(): string {
+    return 'Hello World!';
+  }
+}
diff --git a/crates/swc/tests/projects/issue-8701/src/main.ts b/crates/swc/tests/projects/issue-8701/src/main.ts
new file mode 100644
index 0000000000..13cad38cff
--- /dev/null
+++ b/crates/swc/tests/projects/issue-8701/src/main.ts
@@ -0,0 +1,8 @@
+import { NestFactory } from '@nestjs/core';
+import { AppModule } from './app.module';
+
+async function bootstrap() {
+  const app = await NestFactory.create(AppModule);
+  await app.listen(3000);
+}
+bootstrap();
diff --git a/crates/swc_ecma_transforms_module/tests/path_node.rs b/crates/swc_ecma_transforms_module/tests/path_node.rs
index 28200a1f3f..62c3e6298d 100644
--- a/crates/swc_ecma_transforms_module/tests/path_node.rs
+++ b/crates/swc_ecma_transforms_module/tests/path_node.rs
@@ -126,14 +126,19 @@ fn fixture(input_dir: PathBuf) {
     let config = serde_json::from_str::<TestConfig>(&paths_json).unwrap();
 
     let index_path = input_dir.join(config.input_file.as_deref().unwrap_or("index.ts"));
+    dbg!(&index_path);
 
+    let base_dir = input_dir
+        .join(config.base_url.clone().unwrap_or(input_dir.clone()))
+        .canonicalize()
+        .unwrap();
+    dbg!(&base_dir);
     test_fixture(
         Syntax::default(),
         &|_| {
             let rules = config.paths.clone().into_iter().collect();
 
-            let resolver =
-                paths_resolver(&config.base_url.clone().unwrap_or(input_dir.clone()), rules);
+            let resolver = paths_resolver(&base_dir, rules);
 
             import_rewriter(FileName::Real(index_path.clone()), resolver)
         },
diff --git a/crates/swc_ecma_transforms_module/tests/paths/pack-1682/1/output/index.ts b/crates/swc_ecma_transforms_module/tests/paths/pack-1682/1/output/index.ts
index e41f409c11..37eb0aa56d 100644
--- a/crates/swc_ecma_transforms_module/tests/paths/pack-1682/1/output/index.ts
+++ b/crates/swc_ecma_transforms_module/tests/paths/pack-1682/1/output/index.ts
@@ -1,4 +1,4 @@
-import PrismaClientProvider from "db/PrismaClientProvider";
+import PrismaClientProvider from "../db/PrismaClientProvider.js";
 export default function setupTests() {
     const context = {};
     beforeEach(()=>{
diff --git a/node-swc/__tests__/transform/issue_7806_test.mjs b/node-swc/__tests__/transform/issue_7806_test.mjs
index acda06b88d..80d86bb835 100644
--- a/node-swc/__tests__/transform/issue_7806_test.mjs
+++ b/node-swc/__tests__/transform/issue_7806_test.mjs
@@ -6,17 +6,15 @@ const __filename = fileURLToPath(import.meta.url);
 
 describe("jsc.paths", () => {
     it("should work with process.cwd()", async () => {
-        console.log(process.cwd());
-        const f = path.join(
+        const testDir = path.join(
             __filename,
             "..",
             "..",
             "..",
             "tests",
-            "swc-path-bug-1",
-            "src",
-            "index.ts"
+            "swc-path-bug-1"
         );
+        const f = path.join(testDir, "src", "index.ts");
         console.log(f);
         expect(
             (
@@ -25,7 +23,7 @@ describe("jsc.paths", () => {
                         parser: {
                             syntax: "typescript",
                         },
-                        baseUrl: process.cwd(),
+                        baseUrl: testDir,
                         paths: {
                             "@utils/*": ["src/utils/*"],
                         },
@@ -37,21 +35,15 @@ describe("jsc.paths", () => {
             Object.defineProperty(exports, "__esModule", {
                 value: true
             });
-            const _helloworldutils = require("src/utils/hello-world.utils.js");
+            const _helloworldutils = require("./utils/hello-world.utils.js");
             console.log((0, _helloworldutils.helloWorld)());
             "
         `);
     });
 
     it("should work with process.cwd() and relative url", async () => {
-        console.log(process.cwd());
-        const f = path.join(
-            "node-swc",
-            "tests",
-            "swc-path-bug-1",
-            "src",
-            "index.ts"
-        );
+        const testDir = path.join("node-swc", "tests", "swc-path-bug-1");
+        const f = path.join(testDir, "src", "index.ts");
         console.log(f);
         expect(
             (
@@ -60,7 +52,7 @@ describe("jsc.paths", () => {
                         parser: {
                             syntax: "typescript",
                         },
-                        baseUrl: process.cwd(),
+                        baseUrl: path.resolve(testDir),
                         paths: {
                             "@utils/*": ["src/utils/*"],
                         },
@@ -72,7 +64,7 @@ describe("jsc.paths", () => {
             Object.defineProperty(exports, "__esModule", {
                 value: true
             });
-            const _helloworldutils = require("src/utils/hello-world.utils.js");
+            const _helloworldutils = require("./utils/hello-world.utils.js");
             console.log((0, _helloworldutils.helloWorld)());
             "
         `);
diff --git a/node-swc/__tests__/transform/issue_8701_test.mjs b/node-swc/__tests__/transform/issue_8701_test.mjs
new file mode 100644
index 0000000000..9c21f51b3b
--- /dev/null
+++ b/node-swc/__tests__/transform/issue_8701_test.mjs
@@ -0,0 +1,51 @@
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+import swc from "../../..";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+it("should transpile import path correctly", async () => {
+    const baseUrl = path.resolve(__dirname, "../../tests/issue-8701");
+    console.log("baseUrl", baseUrl);
+    process.chdir(baseUrl);
+
+    const { code } = await swc.transformFile("src/app.module.ts", {
+        jsc: {
+            baseUrl,
+            paths: {
+                "@app/*": ["./src/*"],
+            },
+            parser: {
+                syntax: "typescript",
+                decorators: true,
+            },
+            target: "es2019",
+        },
+    });
+
+    expect(code).toMatchInlineSnapshot(`
+        "function _ts_decorate(decorators, target, key, desc) {
+            var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+            if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+            else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+            return c > 3 && r && Object.defineProperty(target, key, r), r;
+        }
+        import { Module } from "@nestjs/common";
+        import { AppController } from "./app.controller";
+        import { AppService } from "./app.service";
+        export class AppModule {
+        }
+        AppModule = _ts_decorate([
+            Module({
+                imports: [],
+                controllers: [
+                    AppController
+                ],
+                providers: [
+                    AppService
+                ]
+            })
+        ], AppModule);
+        "
+    `);
+});
diff --git a/node-swc/tests/issue-8701/src/app.controller.spec.ts b/node-swc/tests/issue-8701/src/app.controller.spec.ts
new file mode 100644
index 0000000000..b7bb7163ab
--- /dev/null
+++ b/node-swc/tests/issue-8701/src/app.controller.spec.ts
@@ -0,0 +1,21 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppController } from './app.controller';
+import { AppService } from './app.service';
+
+describe('AppController', () => {
+  let app: TestingModule;
+
+  beforeAll(async () => {
+    app = await Test.createTestingModule({
+      controllers: [AppController],
+      providers: [AppService],
+    }).compile();
+  });
+
+  describe('getHello', () => {
+    it('should return "Hello World!"', () => {
+      const appController = app.get(AppController);
+      expect(appController.getHello()).toBe('Hello World!');
+    });
+  });
+});
diff --git a/node-swc/tests/issue-8701/src/app.controller.ts b/node-swc/tests/issue-8701/src/app.controller.ts
new file mode 100644
index 0000000000..cce879ee62
--- /dev/null
+++ b/node-swc/tests/issue-8701/src/app.controller.ts
@@ -0,0 +1,12 @@
+import { Controller, Get } from '@nestjs/common';
+import { AppService } from './app.service';
+
+@Controller()
+export class AppController {
+  constructor(private readonly appService: AppService) {}
+
+  @Get()
+  getHello(): string {
+    return this.appService.getHello();
+  }
+}
diff --git a/node-swc/tests/issue-8701/src/app.module.ts b/node-swc/tests/issue-8701/src/app.module.ts
new file mode 100644
index 0000000000..521408ad9d
--- /dev/null
+++ b/node-swc/tests/issue-8701/src/app.module.ts
@@ -0,0 +1,9 @@
+import { Module } from '@nestjs/common';
+import { AppController } from '@app/app.controller';
+import { AppService } from '@app/app.service';
+@Module({
+  imports: [],
+  controllers: [AppController],
+  providers: [AppService],
+})
+export class AppModule { }
diff --git a/node-swc/tests/issue-8701/src/app.service.ts b/node-swc/tests/issue-8701/src/app.service.ts
new file mode 100644
index 0000000000..927d7cca0b
--- /dev/null
+++ b/node-swc/tests/issue-8701/src/app.service.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class AppService {
+  getHello(): string {
+    return 'Hello World!';
+  }
+}
diff --git a/node-swc/tests/issue-8701/src/main.ts b/node-swc/tests/issue-8701/src/main.ts
new file mode 100644
index 0000000000..13cad38cff
--- /dev/null
+++ b/node-swc/tests/issue-8701/src/main.ts
@@ -0,0 +1,8 @@
+import { NestFactory } from '@nestjs/core';
+import { AppModule } from './app.module';
+
+async function bootstrap() {
+  const app = await NestFactory.create(AppModule);
+  await app.listen(3000);
+}
+bootstrap();