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

fix: force module format for virtual client-proxy file #74162

Open
wants to merge 2 commits into
base: canary
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ impl EcmascriptClientReferenceProxyModule {
#[turbo_tasks::function]
async fn proxy_module(&self) -> Result<Vc<Box<dyn EcmascriptChunkPlaceable>>> {
let mut code = CodeBuilder::default();
let is_esm: bool;

let server_module_path = &*self.server_module_ident.to_string().await?;

// Adapted from https://github.com/facebook/react/blob/c5b9375767e2c4102d7e5559d383523736f1c902/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js#L323-L354
if let EcmascriptExports::EsmExports(exports) = &*self.client_module.get_exports().await? {
is_esm = true;
let exports = exports.expand_exports().await?;

if !exports.dynamic_exports.is_empty() {
Expand Down Expand Up @@ -130,6 +132,7 @@ impl EcmascriptClientReferenceProxyModule {
}
}
} else {
is_esm = false;
writedoc!(
code,
r#"
Expand All @@ -146,7 +149,13 @@ impl EcmascriptClientReferenceProxyModule {
AssetContent::file(File::from(code.source_code().clone()).into());

let proxy_source = VirtualSource::new(
self.server_module_ident.path().join("proxy.js".into()),
self.server_module_ident.path().join(
// Depending on the original format, we call the file `proxy.mjs` or `proxy.cjs`.
// This is because we're placing the virtual module next to the original code, so
// its parsing will be affected by `type` fields in package.json --
// a bare `proxy.js` may end up being unexpectedly parsed as the wrong format.
format!("proxy.{}", if is_esm { "mjs" } else { "cjs" }).into(),
),
proxy_module_content,
);

Expand Down
Copy link
Member Author

@lubieowoce lubieowoce Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the case that matches what happened with jotai. other permutations are just for completeness.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

import EsmFromCjs from 'lib-cjs'

export default function Page() {
return (
<p>
lib-cjs: <EsmFromCjs />
</p>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

import EsmFromEsm from 'lib-esm'

export default function Page() {
return (
<p>
lib-esm: <EsmFromEsm />
</p>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ReactNode } from 'react'
export default function Root({ children }: { children: ReactNode }) {
return (
<html>
<body>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

const CjsFromCjs = require('lib-cjs')

export default function Page() {
return (
<p>
lib-cjs: <CjsFromCjs />
</p>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

const CjsFromEsm = require('lib-esm')

export default function Page() {
return (
<p>
lib-esm: <CjsFromEsm />
</p>
)
}
31 changes: 31 additions & 0 deletions test/e2e/app-dir/client-module-with-package-type/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { nextTestSetup } from 'e2e-utils'

describe('esm-client-module-without-exports', () => {
const { next } = nextTestSetup({
files: __dirname,
})

describe('"type": "commonjs" in package.json', () => {
it('should render without errors: import cjs', async () => {
const $ = await next.render$('/import-cjs')
expect($('p').text()).toContain('lib-cjs: esm')
})

it('should render without errors: require cjs', async () => {
const $ = await next.render$('/require-cjs')
expect($('p').text()).toContain('lib-cjs: cjs')
})
})

describe('"type": "module" in package.json', () => {
it('should render without errors: import esm', async () => {
const $ = await next.render$('/import-esm')
expect($('p').text()).toContain('lib-esm: esm')
})

it('should render without errors: require esm', async () => {
const $ = await next.render$('/require-esm')
expect($('p').text()).toContain('lib-esm: cjs')
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {}

module.exports = nextConfig

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading