Skip to content

Commit

Permalink
Alias nextjs api entry to esm version for app router
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Dec 21, 2023
1 parent 325cad6 commit f55a5a0
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/next/src/build/create-compiler-aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export function createNextApiEsmAliases() {
constants: 'next/dist/api/constants',
router: 'next/dist/api/router',
dynamic: 'next/dist/api/dynamic',
script: 'next/dist/api/script',
link: 'next/dist/api/link',
navigation: 'next/dist/api/navigation',
headers: 'next/dist/api/headers',
Expand Down
26 changes: 2 additions & 24 deletions packages/next/taskfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,6 @@ const fs = require('fs/promises')
const resolveFrom = require('resolve-from')
const execa = require('execa')

export async function next_esm_api_entries(task, opts) {
const mapping = {
head: 'next/dist/shared/lib/head.esm',
image: 'next/dist/shared/lib/image-external.esm',
constants: 'next/dist/shared/lib/constants.esm',
router: 'next/dist/client/router.esm',
dynamic: 'next/dist/client/dynamic.esm',
link: 'next/dist/client/link.esm',
navigation: 'next/dist/client/components/navigation.esm',
headers: 'next/dist/client/components/headers.esm',
og: 'next/dist/server/og/image-response.esm',
}

for (const file of Object.keys(mapping)) {
const filePath = join(__dirname, `${file.slice('next/'.length)}.js`)
console.error('filePath', filePath)
// await fs.writeFile(
// filePath,
// 'e' + `xport * from '${mapping[file]}'\n` +
// 'e' + `xport { default } from '${mapping[file]}'`
// )
}
}

export async function next__polyfill_nomodule(task, opts) {
await task
.source(relative(__dirname, require.resolve('@next/polyfill-nomodule')))
Expand Down Expand Up @@ -2477,6 +2453,8 @@ export async function server_esm(task, opts) {
.target('dist/esm/server')
}

// Provide ESM entry files for Next.js apis,
// Remain in ESM both for dist/ and dist/esm
export async function api_esm(task, opts) {
await task
.source('src/api/**/*.+(js|mts|ts|tsx)')
Expand Down
3 changes: 0 additions & 3 deletions test/e2e/app-dir/app-alias/app-alias.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ createNextDescribe(
'app-dir alias',
{
files: __dirname,
packageJson: {
type: 'module',
},
skipDeployment: true,
},
({ next, isNextStart }) => {
Expand Down
8 changes: 8 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/client-hooks-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use client'

import { useRouter } from 'next/navigation.js'

export function ClientHooks() {
useRouter()
return null
}
8 changes: 8 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/client-hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use client'

import { useRouter } from 'next/navigation'

export function ClientHooks() {
useRouter()
return null
}
18 changes: 18 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/components-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import NextImage, { unstable_getImgProps } from 'next/image.js'
import Link from 'next/link.js'
import Script from 'next/script.js'

import src from '../../public/test.jpg'

export function Components() {
return (
<>
<NextImage className="img" src={src} />
<p className="unstable_getImgProps">{typeof unstable_getImgProps}</p>
<Link className="link" href="/client">
link
</Link>
<Script className="script" src="/test-ext.js" />
</>
)
}
18 changes: 18 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import NextImage, { unstable_getImgProps } from 'next/image'
import Link from 'next/link'
import Script from 'next/script'

import src from '../../public/test.jpg'

export function Components() {
return (
<>
<NextImage className="img" src={src} />
<p className="unstable_getImgProps">{typeof unstable_getImgProps}</p>
<Link className="link" href="/client">
link
</Link>
<Script className="script" src="/test.js" />
</>
)
}
8 changes: 8 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/hooks-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ClientHooks } from './client-hooks-ext'
import { headers, cookies } from 'next/headers.js'

export function useHooks() {
headers()
cookies()
return <ClientHooks />
}
8 changes: 8 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ClientHooks } from './client-hooks'
import { headers, cookies } from 'next/headers'

export function useHooks() {
headers()
cookies()
return <ClientHooks />
}
20 changes: 20 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/app/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useHooks } from './hooks'
import { useHooks as useHooks2 } from './hooks-ext'
import { Components } from './components'
import { Components as Components2 } from './components-ext'

export default function Page() {
useHooks()
useHooks2()

return (
<>
<div id="without-ext">
<Components />
</div>
<div id="with-ext">
<Components2 />
</div>
</>
)
}
12 changes: 12 additions & 0 deletions test/e2e/app-dir/app-esm-js/app/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
}

export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
39 changes: 39 additions & 0 deletions test/e2e/app-dir/app-esm-js/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createNextDescribe } from 'e2e-utils'

createNextDescribe(
'app-dir - esm js extension',
{
files: __dirname,
},
({ next }) => {
it('should be able to render nextjs api in app router', async () => {
const $ = await next.render$('/app')

async function validateDomNodes(selector: string) {
expect(await $(`${selector} .img`).prop('tagName')).toBe('IMG')
expect(await $(`${selector} .link`).prop('tagName')).toBe('A')
expect(await $(`${selector} .unstable_getImgProps`).text()).toContain(
'function'
)
}

await validateDomNodes('#with-ext')
await validateDomNodes('#without-ext')

expect($('head link[href="/test-ext.js"]').length).toBe(1)
expect($('head link[href="/test.js"]').length).toBe(1)
})

it('should be able to use nextjs api in pages router', async () => {
const $ = await next.render$('/pages')

expect(await $('meta[name="head-value-1"]').attr('content')).toBe(
'with-ext'
)
expect(await $('meta[name="head-value-2"]').attr('content')).toBe(
'without-ext'
)
expect(await $('.root').text()).toContain('pages')
})
}
)
File renamed without changes.
1 change: 1 addition & 0 deletions test/e2e/app-dir/app-esm-js/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'next/app.js'
13 changes: 13 additions & 0 deletions test/e2e/app-dir/app-esm-js/pages/_document.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document.js'

export default function MyDocument() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
20 changes: 20 additions & 0 deletions test/e2e/app-dir/app-esm-js/pages/pages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Head from 'next/head'
import AnotherHead from 'next/head.js'
import { useRouter } from 'next/router'
import { useRouter as useRouter2 } from 'next/router.js'

export default function Page() {
useRouter()
useRouter2()
return (
<>
<Head>
<meta name="head-value-1" content="with-ext" />
</Head>
<AnotherHead>
<meta name="head-value-2" content="without-ext" />
</AnotherHead>
<div className="root">pages</div>
</>
)
}
Binary file added test/e2e/app-dir/app-esm-js/public/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f55a5a0

Please sign in to comment.