vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.95k stars 26.69k forks source link

import.meta.dirname + import.meta.filename `undefined` in page #60879

Open karlhorky opened 8 months ago

karlhorky commented 8 months ago

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/import-meta-dirname-reproduction-vj3gfq?file=%2Fapp%2Fpage.tsx%3A1%2C1

To Reproduce

  1. Open the reproduction
  2. Observe import.meta.dirname is undefined in the webpack-compiled page.tsx (but is a dir path in Node.js)

Screenshot 2024-01-19 at 11 45 54

Changes to repro template:

Current vs. Expected behavior

I expected import.meta.dirname and import.meta.filename, introduced in Node.js 20.11.0 to not be undefined in Next.js pages in the App Router, but it is undefined

Verify canary release

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
Binaries:
  Node: 20.11.0
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.14.1
Relevant Packages:
  next: 14.1.1-canary.1
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

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

Module resolution (CJS / ESM, module resolving)

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

next dev (local), next build (local)

Additional context

No response

PACK-2953

karlhorky commented 8 months ago

cc @alexander-akait if I should open an issue in https://github.com/webpack/webpack, let me know and I'll do that.

alexander-akait commented 8 months ago

@karlhorky Yeah, to be honestly it is already in my internal roadmap :smile:

karlhorky commented 8 months ago

Ok, then I'll just leave it open here.

karlhorky commented 8 months ago

Workaround

Configure the DefinePlugin to alias import.meta.dirname to __dirname, similar to https://github.com/webpack/webpack/issues/1599#issuecomment-186620333:

/** @type {import("next").NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (
    config,
    { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack },
  ) => {
    config.plugins.push(
      new webpack.DefinePlugin({
        "import.meta.dirname": "__dirname",
      }),
    );
    return config;
  },
};

export default nextConfig;

CodeSandbox demo: https://codesandbox.io/p/devbox/import-meta-dirname-reproduction-forked-4ldmgw?file=%2Fnext.config.js%3A3%2C25

Screenshot 2024-01-19 at 12 14 13

huozhi commented 8 months ago

@alexander-akait let us know when it's landed in webpack, would love to help bump webpack in next.js for this later 🙏

kachkaev commented 5 months ago

I just upgraded to Node 20, used import.meta.dirname, ran unit tests and all worked there. TypeScript linter did not complain as well, so I committed and pushed. Surprisingly, next build in CI failed because of this issue and it took me a few minutes to understand the cause. Next.js is about DX, so it’d be great to see import.meta.dirname / import.meta.filename to Just Work™

How hard would it be to add @karlhorky’s workaround in the meantime?

kachkaev commented 5 months ago

Looks like turbopack does not know about import.meta.dirname and import.meta.filename too. They return undefined in next dev --turbo as of v 14.2.0.

And because webpack config is ignored by --turbo, we can no longer leverage webpack.DefinePlugin({...}) as a workaround. It’d be cool to use these two little shorthands because they are natively supported by Node 20.

karlhorky commented 2 weeks ago

@alexander-akait if you haven't gotten around to implementing yet, what do you think about me creating a tracking issue in the webpack repo?

karlhorky commented 2 weeks ago

Ah wait, looks like there maybe is one already...? Looks like the issue started as some other topic, but now is about general import.meta.dirname and import.meta.filename support:

alexander-akait commented 2 weeks ago

@karlhorky Yeah, it is an issue about it