Skip to content

Commit

Permalink
[edge] support edge-light exports when bundling edge functions (#45188)
Browse files Browse the repository at this point in the history
This PR implements `edge-light` as a main field for bundling edge
functions as defined in https://runtime-keys.proposal.wintercg.org

Resolves EC-614

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

---------
  • Loading branch information
Schniz authored Feb 16, 2023
1 parent f3b231c commit 282c1a0
Show file tree
Hide file tree
Showing 23 changed files with 150 additions and 3 deletions.
13 changes: 10 additions & 3 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -903,13 +903,13 @@ export default async function getBaseWebpackConfig(
const mainFieldsPerCompiler: Record<typeof compilerType, string[]> = {
[COMPILER_NAMES.server]: ['main', 'module'],
[COMPILER_NAMES.client]: ['browser', 'module', 'main'],
[COMPILER_NAMES.edgeServer]: ['browser', 'module', 'main'],
[COMPILER_NAMES.edgeServer]: ['edge-light', 'browser', 'module', 'main'],
}

const reactDir = path.dirname(require.resolve('react/package.json'))
const reactDomDir = path.dirname(require.resolve('react-dom/package.json'))

const resolveConfig = {
const resolveConfig: webpack.Configuration['resolve'] = {
// Disable .mjs for node_modules bundling
extensions: isNodeServer
? ['.js', '.mjs', '.tsx', '.ts', '.jsx', '.json', '.wasm']
Expand Down Expand Up @@ -1022,6 +1022,7 @@ export default async function getBaseWebpackConfig(
}
: undefined),
mainFields: mainFieldsPerCompiler[compilerType],
...(isEdgeServer && { conditionNames: ['edge-light', 'import', 'node'] }),
plugins: [],
}

Expand Down Expand Up @@ -1723,7 +1724,13 @@ export default async function getBaseWebpackConfig(
return true
},
resolve: {
conditionNames: ['react-server', 'node', 'import', 'require'],
conditionNames: [
'react-server',
...(!isEdgeServer ? [] : ['edge-light']),
'node',
'import',
'require',
],
alias: {
// If missing the alias override here, the default alias will be used which aliases
// react to the direct file path, not the package name. In that case the condition
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import edgeLightPackage from 'my-edge-light-package'
import edgeLightPackageExports from 'my-edge-light-package-exports'

export const runtime = 'edge'

export default function AppDirPage() {
return (
<pre id="result">
{JSON.stringify({ edgeLightPackage, edgeLightPackageExports }, null, 2)}
</pre>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function RootLayout({ children }) {
return (
<html>
<head />
<body>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { createNextDescribe } from 'e2e-utils'

createNextDescribe(
'edge-runtime uses edge-light import specifier for packages',
{
files: __dirname,
packageJson: {
scripts: {
setup: 'cp -r ./node_modules_bak/* ./node_modules',
build: 'yarn setup && next build',
dev: 'yarn setup && next dev',
start: 'next start',
},
},
installCommand: 'yarn',
startCommand: (global as any).isNextDev ? 'yarn dev' : 'yarn start',
buildCommand: 'yarn build',
skipDeployment: true,
},
({ next }) => {
// In case you need to test the response object
it('pages/api endpoints import the correct module', async () => {
const res = await next.fetch('/api/edge')
const html = await res.json()
expect(html).toEqual({
edgeLightPackage: 'edge-light',
edgeLightPackageExports: 'edge-light',
})
})

it('pages import the correct module', async () => {
const $ = await next.render$('/')
const text = JSON.parse($('pre#result').text())
expect(text).toEqual({
edgeLightPackage: 'edge-light',
edgeLightPackageExports: 'edge-light',
})
})

it('app-dir imports the correct module', async () => {
const $ = await next.render$('/app-dir')
const text = JSON.parse($('pre#result').text())
expect(text).toEqual({
edgeLightPackage: 'edge-light',
edgeLightPackageExports: 'edge-light',
})
})
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
appDir: true,
},
}

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.

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.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'edge-light'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'import'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "my-edge-light-package-exports",
"main": "./require.js",
"exports": {
"edge-light": "./edge-light.js",
"require": "./require.js",
"import": "./import.js"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'require'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'edge-light'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'import'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "my-edge-light-package",
"main": "./require.js",
"module": "./import.js",
"edge-light": "./edge-light.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'require'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import edgeLightPackage from 'my-edge-light-package'
import edgeLightPackageExports from 'my-edge-light-package-exports'
import { NextResponse } from 'next/server'

export const config = { runtime: 'edge' }

export default function MyEdgeFunction() {
return NextResponse.json({
edgeLightPackage,
edgeLightPackageExports,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import edgeLightPackage from 'my-edge-light-package'
import edgeLightPackageExports from 'my-edge-light-package-exports'

export const config = { runtime: 'experimental-edge' }

export default function Index() {
return (
<pre id="result">
{JSON.stringify({ edgeLightPackage, edgeLightPackageExports }, null, 2)}
</pre>
)
}

0 comments on commit 282c1a0

Please sign in to comment.