Repository: swc-project/swc (rust)

Issue:
emit `.js` extensions to produce valid ESM import/export paths
### Describe the feature

We are using swc extensively but recently ran into issues when introducing native ESM outputs within build time.

swc should provide an option to emit explicit extensions within imports even if they are not specified within source code.

- rollup does this by default for example.
- there seems to be a inconsistencies within swc compiler already as if `module#resolveFully` is used it will unwrap directory import/exports to explicitly emit `index.js` 


We tried using `@swc/plugin-transform-imports` as a workaround but those transforms happen before swc does the transform ( we also need to use `module#resolveFully` in order to properly emit directory imports/exports in order to make outputs valid for browser ).


```ts
export { teamsDarkTheme, teamsHighContrastTheme, teamsLightTheme, webDarkTheme, webLightTheme } from './themes'; // 🚨 invalid directory path - wont work within browser
export { createDarkTheme, createHighContrastTheme, createLightTheme, createTeamsDarkTheme } from './utils'; // 🚨 invalid directory path - wont work within browser

export { themeToTokensObject } from './themeToTokensObject';
export { tokens } from './tokens';
export { typographyStyles } from './global';
```

⬇ swc with config ⬇ 
```js
"module": {
    "type": "es6",
    // ✅✅✅ unwraps directory imports to explicit `index.js`
    "resolveFully": true
  },
  "jsc": {
    "baseUrl": ".",
  }
}
```
⬇⬇⬇

```js
export { teamsDarkTheme, teamsHighContrastTheme, teamsLightTheme, webDarkTheme, webLightTheme } from "./themes/index.js"; // ✅
export { createDarkTheme, createHighContrastTheme, createLightTheme, createTeamsDarkTheme } from "./utils/index.js"; // ✅
export { themeToTokensObject } from "./themeToTokensObject"; // 🚨 invalid ESM
export { tokens } from "./tokens";  // 🚨 invalid ESM
export { typographyStyles } from "./global/index.js"; // ✅

//# sourceMappingURL=index.js.map
```

**Related issues:**

- https://github.com/swc-project/cli/issues/60
- https://github.com/swc-project/swc/issues/3067

### Babel plugin or link to the feature description

_No response_

### Additional context

_No response_

Pull request:
fix(es/module): Respect `module.resolveFully` in more cases
**Description:**


**Related issue:**

 - Closes #8742

Patch:
diff --git a/crates/swc_ecma_transforms_module/src/path.rs b/crates/swc_ecma_transforms_module/src/path.rs
index 06ee744f46..f1ae18c17c 100644
--- a/crates/swc_ecma_transforms_module/src/path.rs
+++ b/crates/swc_ecma_transforms_module/src/path.rs
@@ -173,7 +173,8 @@ where
                 false
             };
 
-            if orig_filename == "index" {
+            if self.config.resolve_fully && is_resolved_as_js {
+            } else if orig_filename == "index" {
                 // Import: `./foo/index`
                 // Resolved: `./foo/index.js`
 


Test patch:
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8742/input/.swcrc
new file mode 100644
index 0000000000..a2cea3ca7c
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/.swcrc
@@ -0,0 +1,9 @@
+{
+    "module": {
+        "type": "es6",
+        "resolveFully": true
+    },
+    "jsc": {
+        "baseUrl": "."
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/global/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/global/index.js
new file mode 100644
index 0000000000..3deda8047e
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/global/index.js
@@ -0,0 +1,1 @@
+export { }
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/index.js
new file mode 100644
index 0000000000..50ad856a72
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/index.js
@@ -0,0 +1,9 @@
+// ======
+// SOURCE
+// ======
+export { teamsDarkTheme, teamsHighContrastTheme, teamsLightTheme, webDarkTheme, webLightTheme } from './themes'; // 🚨 invalid directory path - wont work within browser
+export { createDarkTheme, createHighContrastTheme, createLightTheme, createTeamsDarkTheme } from './utils'; // 🚨 invalid directory path - wont work within browser
+
+export { themeToTokensObject } from './themeToTokensObject';
+export { tokens } from './tokens';
+export { typographyStyles } from './global'; // 🚨 invalid directory path - wont work within browser
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/themeToTokensObject.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/themeToTokensObject.js
new file mode 100644
index 0000000000..f0a766d36b
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/themeToTokensObject.js
@@ -0,0 +1,1 @@
+export { }
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/themes/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/themes/index.js
new file mode 100644
index 0000000000..3deda8047e
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/themes/index.js
@@ -0,0 +1,1 @@
+export { }
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/tokens.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/tokens.js
new file mode 100644
index 0000000000..3deda8047e
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/tokens.js
@@ -0,0 +1,1 @@
+export { }
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/input/utils/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/input/utils/index.js
new file mode 100644
index 0000000000..f0a766d36b
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/input/utils/index.js
@@ -0,0 +1,1 @@
+export { }
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/global/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/global/index.js
new file mode 100644
index 0000000000..2234b9cae1
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/global/index.js
@@ -0,0 +1,1 @@
+export { };
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/index.js
new file mode 100644
index 0000000000..971a2d901d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/index.js
@@ -0,0 +1,8 @@
+// ======
+// SOURCE
+// ======
+export { teamsDarkTheme, teamsHighContrastTheme, teamsLightTheme, webDarkTheme, webLightTheme } from "./themes/index.js"; // 🚨 invalid directory path - wont work within browser
+export { createDarkTheme, createHighContrastTheme, createLightTheme, createTeamsDarkTheme } from "./utils/index.js"; // 🚨 invalid directory path - wont work within browser
+export { themeToTokensObject } from "./themeToTokensObject.js";
+export { tokens } from "./tokens.js";
+export { typographyStyles } from "./global/index.js"; // 🚨 invalid directory path - wont work within browser
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/themeToTokensObject.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/themeToTokensObject.js
new file mode 100644
index 0000000000..2234b9cae1
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/themeToTokensObject.js
@@ -0,0 +1,1 @@
+export { };
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/themes/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/themes/index.js
new file mode 100644
index 0000000000..2234b9cae1
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/themes/index.js
@@ -0,0 +1,1 @@
+export { };
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/tokens.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/tokens.js
new file mode 100644
index 0000000000..2234b9cae1
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/tokens.js
@@ -0,0 +1,1 @@
+export { };
diff --git a/crates/swc/tests/fixture/issues-8xxx/8742/output/utils/index.js b/crates/swc/tests/fixture/issues-8xxx/8742/output/utils/index.js
new file mode 100644
index 0000000000..2234b9cae1
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-8xxx/8742/output/utils/index.js
@@ -0,0 +1,1 @@
+export { };