Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWC plugin runner no longer provides full file path to metadata #72019

Open
serg-and opened this issue Oct 29, 2024 · 14 comments
Open

SWC plugin runner no longer provides full file path to metadata #72019

serg-and opened this issue Oct 29, 2024 · 14 comments
Labels
linear: next Confirmed issue that is tracked by the Next.js team. Pages Router Related to Pages Router. SWC Related to minification/transpilation in Next.js.

Comments

@serg-and
Copy link

Link to the code that reproduces this issue

https://github.com/serg-and/nextjs-minimal-swc-plugin-issue

To Reproduce

npm i
cd swc_plugin
npm run prepublish
cd ..
npm run dev

Logs will show that the provided filename in the metadata no longer includes the file path, only the filename.

Current vs. Expected behavior

Next's pluggin runner no longer provides the known file path to the metadata for a SWC plugin, only providing the file name.

This is conflict with SWC, saying: swc docs

/// Host side metadata context plugin may need to access.
/// This is a global context - any plugin in single transform will have same
/// values.
pub struct TransformPluginMetadataContext {
    /// The path of the file being processed. This includes all of the path as
    /// much as possible.
    pub filename: Option<String>,

    ...
}

This breaks several packages such as next-superjson-plugin which rely on the path to determine whether some files are page or app router based.

Provide environment information

Operating System:
  Platform: linux
  Arch: arm64
  Version: #1 SMP Wed Jul 17 10:51:09 UTC 2024
  Available memory (MB): 7185
  Available CPU cores: 8
Binaries:
  Node: 20.11.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 15.0.1 // Latest available version is detected (15.0.1).
  eslint-config-next: 15.0.1
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.0.4
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Pages Router, SWC

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

I believe the issue originates from here https://github.com/vercel/next.js/blob/v15.0.1/turbopack/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs#L189

Some(ctx.file_name_str.to_string()) could simply be changed to Some(ctx.file_path_str.to_string())

@serg-and serg-and added the bug Issue was opened via the bug report template. label Oct 29, 2024
@github-actions github-actions bot added Pages Router Related to Pages Router. SWC Related to minification/transpilation in Next.js. labels Oct 29, 2024
@github-actions github-actions bot added the linear: next Confirmed issue that is tracked by the Next.js team. label Nov 18, 2024
@kdy1 kdy1 self-assigned this Dec 5, 2024
@kdy1
Copy link
Member

kdy1 commented Dec 5, 2024

@kdy1
Copy link
Member

kdy1 commented Dec 9, 2024

I did some extra investigation, and

let options: TransformOptions = serde_json::from_slice(&self.options)?;
let fm = match &self.input {
Input::Source { src } => {
let filename = if options.swc.filename.is_empty() {
FileName::Anon
} else {
FileName::Real(options.swc.filename.clone().into())
};
self.c.cm.new_source_file(filename.into(), src.to_string())
}
Input::FromFilename => {
let filename = &options.swc.filename;
if filename.is_empty() {
bail!("no filename is provided via options");
}
self.c.cm.new_source_file(
FileName::Real(filename.into()).into(),
read_to_string(filename).with_context(|| {
format!("Failed to read source code from {}", filename)
})?,
)
}
};
is the direct cause. So, javascript is not passing the absolute path as filename option at first.

@kdy1
Copy link
Member

kdy1 commented Dec 9, 2024

Do you mean the absolute file path, or path from the project root?
Which one is the thing you need?

@serg-and
Copy link
Author

Path from the project root was what was provided by previous versions of next, so that's what is need for backwards compatibility.

@samcx samcx removed the bug Issue was opened via the bug report template. label Jan 23, 2025
@kdy1 kdy1 removed their assignment Feb 3, 2025
@awkaiser-tr
Copy link

Giving this a New Years bump! I see @kdy1 self-assigned, identified root cause, then recently unassigned? 😞

If the Next.js team has reasons this won't be patched, that would be great to know so projects such as next-superjson-plugin can be prompted to adapt. In the meantime, folks impacted by this have been unable to upgrade their Next.js projects beyond v14 for 109 days now and it feels bad to be held back by something so small. The issue can be resolved a few different ways12 but, if it makes no difference to Next.js itself, here at the root cause would be the best patch location.

Footnotes

  1. Suggestion to change next-superjson-plugin behavior

  2. Suggestion to use next-superjson instead

@kdy1
Copy link
Member

kdy1 commented Feb 8, 2025 via email

@awkaiser-tr
Copy link

awkaiser-tr commented Feb 18, 2025

@kdy1 Hmm. You identified that the problem lies within vendored /crates/napi code last "synched" with swc_core 5.0.1 (11/6/24), with only a handful of changes made to transform.rs since then. The portion you highlighted appears to relate to 3 year old versions of swc_core and bears no resemblance to 5.0.1 transform.rs (if even relevant).

💡 You made some changes six months ago that coincide with this issue's reported bug:

  1. v15.0.0-canary.121 works 🎉
  2. v15.0.0-canary.122 throws next-superjson-plugin/dist/next_superjson.wasm error 😿

@kdy1
Copy link
Member

kdy1 commented Feb 19, 2025

@awkaiser-tr It’s failing with something completely unrelated.

@kdy1 kdy1 assigned kdy1 and unassigned kdy1 Feb 19, 2025
@awkaiser-tr
Copy link

awkaiser-tr commented Feb 19, 2025

🙇🏻 🍻

@kdy1 can you be more specific RE: "something completely unrelated"?

My understanding – from this and other related issues on Github – is that next-superjson-plugin fails due to missing path information, as described by this issue's description.

@serg-and either I'm going about [the below] wrong1 or your repro implementation would benefit from some adjustments. Can you create a branch on your repo that receives the path you expect, pinning the latest version of Next.js that works?

Troubleshooting

Using the reproduction repo from description, Next.js 15.0.1 and 15.0.0-canary.122 share same result:

> nextjs-minimal-swc-plugin-issue@0.1.0 dev
> next dev --turbopack

  ▲ Next.js 15.0.1 (Turbopack)
  - Local:        http://localhost:3000
  - Experiments (use with caution):
    · swcPlugins

 ✓ Starting...
 ✓ Ready in 1070ms
got filename: _app.tsx
 ○ Compiling / ...
got filename: _app.tsx
got filename: _document.tsx
got filename: index.tsx
got filename: index.tsx
got filename: helpers.js
 ✓ Compiled / in 2000ms
 GET / 200 in 2145ms
> nextjs-minimal-swc-plugin-issue@0.1.0 dev
> next dev --turbo

  ▲ Next.js 15.0.0-canary.122 (turbo)
  - Local:        http://localhost:3000
  - Experiments (use with caution):
    · swcPlugins

 ✓ Starting...
 ⚠ Configuration with next.config.ts is currently an experimental feature, use with caution.
 ✓ Ready in 1069ms
got filename: _app.tsx
 ○ Compiling / ...
got filename: _app.tsx
got filename: _document.tsx
got filename: index.tsx
got filename: index.tsx
got filename: helpers.js
 ✓ Compiled / in 1854ms
 GET / 200 in 2004ms

Testing 15.0.0-canary.121 required downgrading to swc_core 0.96.9 but that surprisingly exhibited same behavior:

> nextjs-minimal-swc-plugin-issue@0.1.0 dev
> next dev --turbo

  ▲ Next.js 15.0.0-canary.121 (turbo)
  - Local:        http://localhost:3000
  - Experiments (use with caution):
    · swcPlugins

 ✓ Starting...
 ⚠ Configuration with next.config.ts is currently an experimental feature, use with caution.
 ✓ Ready in 1163ms
got filename: _app.tsx
 ○ Compiling / ...
got filename: _app.tsx
got filename: _document.tsx
got filename: index.tsx
got filename: index.tsx
got filename: helpers.js
 ✓ Compiled / in 1758ms
 GET / 200 in 1970ms

To sanity check, I went back further to known working version 14.2.16 with swc_core 0.90.30, but got same result:

> nextjs-minimal-swc-plugin-issue@0.1.0 dev
> next dev --turbo

  ▲ Next.js 14.2.16 (turbo)
  - Local:        http://localhost:3000
  - Experiments (use with caution):
    · swcPlugins

 ✓ Starting...
 ✓ Ready in 887ms
got filename: _app.tsx
got filename: hmr-client.ts
got filename: websocket.ts
 ○ Compiling / ...
got filename: _app.tsx
got filename: _document.tsx
got filename: index.tsx
got filename: index.tsx
got filename: helpers.js
 ✓ Compiled / in 1353ms
 GET / 200 in 1513ms

Footnotes

  1. Updating test plugin's swc_core and rebuilding it + adjusting root package.json and config as appropriate for target Next.js version

@kdy1
Copy link
Member

kdy1 commented Feb 20, 2025

Yeap, that's why I said it's not related to swc_core update.

@kdy1
Copy link
Member

kdy1 commented Feb 20, 2025

@awkaiser-tr If you want to bisect, you need to adjust swc_core version respectively, each time.

@awkaiser-tr
Copy link

Yeap, that's why I said it's not related to swc_core update.

There are two problems:

  1. To be compatible with Next 15, next-superjson-plugin must upgrade its swc_core version (i.e. regular maintenance)
  2. What this issue is about: Next stopped passing enough path information (RE: TransformPluginMetadataContext filename) for plugins such as next-superjson-plugin to determine if modules are located beneath the App Router or Pages Router directories

@kdy1 when you consider what this issue is related to, do you have further insights beyond what you wrote in December?

If you want to bisect, you need to adjust swc_core version respectively, each time.

Yeah, I rebuilt the repro repo's plugin with appropriate swc_core version for each of the Next version tests shared above. It'd be clear if I hadn't done that, since an error like this would be thrown:

- failed to run Wasm plugin transform. Please ensure the version of `swc_core` used by the plugin is compatible with the host runtime. See https://swc.rs/docs/plugin/selecting-swc-core for compatibility information. If you are an author of the plugin, please update `swc_core` to the compatible version.

Given that next-superjson-plugin is known to work fine on Next 14.2.16 + swc_core 0.90.*, I am left confused. The plugin code written by @serg-and looks pretty straightforward, merely printing the value of TransformPluginMetadataContext filename (which is what next-superjson-plugin is using). My expectation that I'd see a path prefix on that final 14.2.16 sanity check was subverted! 😵 Hopefully I'm just doing something wrong...

@serg-and
Copy link
Author

@awkaiser-tr I'm pretty sure i had to throw away the entire .next cache or maybe even the entire node_modules, because it otherwise wouldn't update the plugin.

@kdy1 why cant this line
https://github.com/vercel/next.js/blob/v15.0.1/turbopack/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs#L189
be changed to Some(ctx.file_path_str.to_string()) . It seems that this is what is passed to the plugins and should be changed to keep backwards compatibility.

@kdy1
Copy link
Member

kdy1 commented Feb 26, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear: next Confirmed issue that is tracked by the Next.js team. Pages Router Related to Pages Router. SWC Related to minification/transpilation in Next.js.
Projects
None yet
Development

No branches or pull requests

4 participants