Skip to content

Commit

Permalink
Revert "edge-ssr: bundle next/dist as ESM for better tree-shaking (#4…
Browse files Browse the repository at this point in the history
…0251) (#40967)

This reverts commit 11deaaa.

Temporarily reverts the above commit due to breaking middleware/edge
functions once deployed.

Fixes:
https://github.com/vercel/next.js/actions/runs/3133433920/jobs/5087331787

cc @shuding @feedthejim 

```sh
[GET] /blog/first
13:56:56:61
2022-09-27T20:56:56.671Z	61d43a6a-34a1-40c0-b71f-4ae5d1918431	ERROR	/var/task/node_modules/next/dist/esm/client/router.js:1
/* global window */ import React from 'react';
                    ^^^^^^
SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/var/task/node_modules/next/router.js:3:7)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
```
  • Loading branch information
ijjk committed Sep 27, 2022
1 parent b16fccc commit ccc8d27
Show file tree
Hide file tree
Showing 26 changed files with 52 additions and 270 deletions.
5 changes: 1 addition & 4 deletions packages/next/amp.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/shared/lib/amp')
: require('./dist/shared/lib/amp')
module.exports = require('./dist/shared/lib/amp')
5 changes: 1 addition & 4 deletions packages/next/app.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/pages/_app')
: require('./dist/pages/_app')
module.exports = require('./dist/pages/_app')
3 changes: 0 additions & 3 deletions packages/next/build/entries.ts
Expand Up @@ -219,7 +219,6 @@ export function getAppEntry(opts: {
appDir: string
appPaths: string[] | null
pageExtensions: string[]
nextRuntime: string
}) {
return {
import: `next-app-loader?${stringify(opts)}!`,
Expand Down Expand Up @@ -456,7 +455,6 @@ export async function createEntrypoints(params: CreateEntrypointsParams) {
appDir,
appPaths: matchedAppPaths,
pageExtensions,
nextRuntime: 'nodejs',
})
} else if (isTargetLikeServerless(target)) {
if (page !== '/_app' && page !== '/_document') {
Expand All @@ -481,7 +479,6 @@ export async function createEntrypoints(params: CreateEntrypointsParams) {
appDir: appDir!,
appPaths: matchedAppPaths,
pageExtensions,
nextRuntime: 'edge',
}).import
}

Expand Down
18 changes: 8 additions & 10 deletions packages/next/build/webpack-config.ts
Expand Up @@ -180,9 +180,11 @@ export function getDefineEnv({
}),
// TODO: enforce `NODE_ENV` on `process.env`, and add a test:
'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production'),
'process.env.NEXT_RUNTIME': JSON.stringify(
isEdgeServer ? 'edge' : isNodeServer ? 'nodejs' : undefined
),
...((isNodeServer || isEdgeServer) && {
'process.env.NEXT_RUNTIME': JSON.stringify(
isEdgeServer ? 'edge' : 'nodejs'
),
}),
'process.env.__NEXT_MIDDLEWARE_MATCHERS': JSON.stringify(
middlewareMatchers || []
),
Expand Down Expand Up @@ -793,7 +795,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
isEdgeServer ? 'next/dist/esm/pages/_app.js' : 'next/dist/pages/_app.js',
'next/dist/pages/_app.js',
]
customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [
...(pagesDir
Expand All @@ -802,9 +804,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
isEdgeServer
? 'next/dist/esm/pages/_error.js'
: 'next/dist/pages/_error.js',
'next/dist/pages/_error.js',
]
customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [
...(pagesDir
Expand All @@ -813,9 +813,7 @@ export default async function getBaseWebpackConfig(
return prev
}, [] as string[])
: []),
isEdgeServer
? `next/dist/esm/pages/_document.js`
: `next/dist/pages/_document.js`,
`next/dist/pages/_document.js`,
]
}

Expand Down
18 changes: 8 additions & 10 deletions packages/next/build/webpack/loaders/next-app-loader.ts
Expand Up @@ -120,9 +120,8 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
appDir: string
appPaths: string[] | null
pageExtensions: string[]
nextRuntime: string
}> = async function nextAppLoader() {
const { name, appDir, appPaths, pagePath, pageExtensions, nextRuntime } =
const { name, appDir, appPaths, pagePath, pageExtensions } =
this.getOptions() || {}

const buildInfo = getModuleBuildInfo((this as any)._module)
Expand Down Expand Up @@ -180,24 +179,23 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
resolveParallelSegments,
})

const rootDistFolder = nextRuntime === 'edge' ? 'next/dist/esm' : 'next/dist'
const result = `
export ${treeCode}
export const AppRouter = require('${rootDistFolder}/client/components/app-router.client.js').default
export const LayoutRouter = require('${rootDistFolder}/client/components/layout-router.client.js').default
export const RenderFromTemplateContext = require('${rootDistFolder}/client/components/render-from-template-context.client.js').default
export const AppRouter = require('next/dist/client/components/app-router.client.js').default
export const LayoutRouter = require('next/dist/client/components/layout-router.client.js').default
export const RenderFromTemplateContext = require('next/dist/client/components/render-from-template-context.client.js').default
export const HotReloader = ${
// Disable HotReloader component in production
this.mode === 'development'
? `require('${rootDistFolder}/client/components/hot-reloader.client.js').default`
? `require('next/dist/client/components/hot-reloader.client.js').default`
: 'null'
}
export const staticGenerationAsyncStorage = require('${rootDistFolder}/client/components/static-generation-async-storage.js').staticGenerationAsyncStorage
export const requestAsyncStorage = require('${rootDistFolder}/client/components/request-async-storage.js').requestAsyncStorage
export const staticGenerationAsyncStorage = require('next/dist/client/components/static-generation-async-storage.js').staticGenerationAsyncStorage
export const requestAsyncStorage = require('next/dist/client/components/request-async-storage.js').requestAsyncStorage
export const serverHooks = require('${rootDistFolder}/client/components/hooks-server-context.js')
export const serverHooks = require('next/dist/client/components/hooks-server-context.js')
export const renderToReadableStream = require('next/dist/compiled/react-server-dom-webpack/writer.browser.server').renderToReadableStream
export const __next_app_webpack_require__ = __webpack_require__
Expand Down
35 changes: 7 additions & 28 deletions packages/next/build/webpack/loaders/next-edge-ssr-loader/index.ts
Expand Up @@ -18,18 +18,6 @@ export type EdgeSSRLoaderQuery = {
hasFontLoaders: boolean
}

/*
For pages SSR'd at the edge, we bundle them with the ESM version of Next in order to
benefit from the better tree-shaking and thus, smaller bundle sizes.
The absolute paths for _app, _error and _document, used in this loader, link to the regular CJS modules.
They are generated in `createPagesMapping` where we don't have access to `isEdgeRuntime`,
so we have to do it here. It's not that bad because it keeps all references to ESM modules magic in this place.
*/
function swapDistFolderWithEsmDistFolder(path: string) {
return path.replace('next/dist/pages', 'next/dist/esm/pages')
}

export default async function edgeSSRLoader(this: any) {
const {
dev,
Expand Down Expand Up @@ -66,18 +54,9 @@ export default async function edgeSSRLoader(this: any) {
}

const stringifiedPagePath = stringifyRequest(this, absolutePagePath)
const stringifiedAppPath = stringifyRequest(
this,
swapDistFolderWithEsmDistFolder(absoluteAppPath)
)
const stringifiedErrorPath = stringifyRequest(
this,
swapDistFolderWithEsmDistFolder(absoluteErrorPath)
)
const stringifiedDocumentPath = stringifyRequest(
this,
swapDistFolderWithEsmDistFolder(absoluteDocumentPath)
)
const stringifiedAppPath = stringifyRequest(this, absoluteAppPath)
const stringifiedErrorPath = stringifyRequest(this, absoluteErrorPath)
const stringifiedDocumentPath = stringifyRequest(this, absoluteDocumentPath)
const stringified500Path = absolute500Path
? stringifyRequest(this, absolute500Path)
: null
Expand All @@ -88,8 +67,8 @@ export default async function edgeSSRLoader(this: any) {
)}`

const transformed = `
import { adapter, enhanceGlobals } from 'next/dist/esm/server/web/adapter'
import { getRender } from 'next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render'
import { adapter, enhanceGlobals } from 'next/dist/server/web/adapter'
import { getRender } from 'next/dist/build/webpack/loaders/next-edge-ssr-loader/render'
enhanceGlobals()
Expand All @@ -98,7 +77,7 @@ export default async function edgeSSRLoader(this: any) {
isAppDir
? `
const Document = null
const appRenderToHTML = require('next/dist/esm/server/app-render').renderToHTMLOrFlight
const appRenderToHTML = require('next/dist/server/app-render').renderToHTMLOrFlight
const pagesRenderToHTML = null
const pageMod = require(${JSON.stringify(pageModPath)})
const appMod = null
Expand All @@ -108,7 +87,7 @@ export default async function edgeSSRLoader(this: any) {
: `
const Document = require(${stringifiedDocumentPath}).default
const appRenderToHTML = null
const pagesRenderToHTML = require('next/dist/esm/server/render').renderToHTML
const pagesRenderToHTML = require('next/dist/server/render').renderToHTML
const pageMod = require(${stringifiedPagePath})
const appMod = require(${stringifiedAppPath})
const errorMod = require(${stringifiedErrorPath})
Expand Down
@@ -1,5 +1,4 @@
import type { NextConfig } from '../../../../server/config-shared'

import type { DocumentType, AppType } from '../../../../shared/lib/utils'
import type { BuildManifest } from '../../../../server/get-page-files'
import type { ReactLoadableManifest } from '../../../../server/load-components'
Expand Down
16 changes: 3 additions & 13 deletions packages/next/build/webpack/plugins/flight-client-entry-plugin.ts
Expand Up @@ -307,19 +307,9 @@ export class FlightClientEntryPlugin {
modules: clientComponentImports,
server: false,
}

// For the client entry, we always use the CJS build of Next.js. If the
// server is using the ESM build (when using the Edge runtime), we need to
// replace them.
const clientLoader = `next-flight-client-entry-loader?${stringify({
modules: this.isEdgeServer
? clientComponentImports.map((importPath) =>
importPath.replace('next/dist/esm/', 'next/dist/')
)
: clientComponentImports,
server: false,
})}!`

const clientLoader = `next-flight-client-entry-loader?${stringify(
loaderOptions
)}!`
const clientSSRLoader = `next-flight-client-entry-loader?${stringify({
...loaderOptions,
server: true,
Expand Down
20 changes: 0 additions & 20 deletions packages/next/build/webpack/plugins/flight-manifest-plugin.ts
Expand Up @@ -56,9 +56,6 @@ export type FlightManifest = {
__ssr_module_mapping__: {
[moduleId: string]: ManifestNode
}
__edge_ssr_module_mapping__: {
[moduleId: string]: ManifestNode
}
} & {
[modulePath: string]: ManifestNode
}
Expand Down Expand Up @@ -144,7 +141,6 @@ export class FlightManifestPlugin {
) {
const manifest: FlightManifest = {
__ssr_module_mapping__: {},
__edge_ssr_module_mapping__: {},
}
const dev = this.dev
const fontLoaderTargets = this.fontLoaderTargets
Expand Down Expand Up @@ -200,7 +196,6 @@ export class FlightManifestPlugin {

const moduleExports = manifest[resource] || {}
const moduleIdMapping = manifest.__ssr_module_mapping__
const edgeModuleIdMapping = manifest.__edge_ssr_module_mapping__

// Note that this isn't that reliable as webpack is still possible to assign
// additional queries to make sure there's no conflict even using the `named`
Expand Down Expand Up @@ -309,25 +304,10 @@ export class FlightManifestPlugin {
...moduleExports[name],
id: ssrNamedModuleId,
}

edgeModuleIdMapping[id] = edgeModuleIdMapping[id] || {}
edgeModuleIdMapping[id][name] = {
...moduleExports[name],
id: ssrNamedModuleId.replace(/\/next\/dist\//, '/next/dist/esm/'),
}
})

manifest[resource] = moduleExports

// The client compiler will always use the CJS Next.js build, so here we
// also add the mapping for the ESM build (Edge runtime) to consume.
if (/\/next\/dist\//.test(resource)) {
manifest[resource.replace(/\/next\/dist\//, '/next/dist/esm/')] =
moduleExports
}

manifest.__ssr_module_mapping__ = moduleIdMapping
manifest.__edge_ssr_module_mapping__ = edgeModuleIdMapping
}

chunkGroup.chunks.forEach((chunk: webpack.Chunk) => {
Expand Down
14 changes: 4 additions & 10 deletions packages/next/build/webpack/plugins/telemetry-plugin.ts
Expand Up @@ -110,15 +110,11 @@ function findFeatureInModule(module: Module): Feature | undefined {
* dependency.
*/
function findUniqueOriginModulesInConnections(
connections: Connection[],
originModule: Module
connections: Connection[]
): Set<unknown> {
const originModules = new Set()
for (const connection of connections) {
if (
!originModules.has(connection.originModule) &&
connection.originModule !== originModule
) {
if (!originModules.has(connection.originModule)) {
originModules.add(connection.originModule)
}
}
Expand Down Expand Up @@ -165,10 +161,8 @@ export class TelemetryPlugin implements webpack.WebpackPluginInstance {
const connections = (
compilation as any
).moduleGraph.getIncomingConnections(module)
const originModules = findUniqueOriginModulesInConnections(
connections,
module
)
const originModules =
findUniqueOriginModulesInConnections(connections)
this.usageTracker.get(feature)!.invocationCount =
originModules.size
}
Expand Down
5 changes: 1 addition & 4 deletions packages/next/client.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/client/index')
: require('./dist/client/index')
module.exports = require('./dist/client/index')
5 changes: 1 addition & 4 deletions packages/next/config.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/shared/lib/runtime-config')
: require('./dist/shared/lib/runtime-config')
module.exports = require('./dist/shared/lib/runtime-config')
5 changes: 1 addition & 4 deletions packages/next/constants.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/shared/lib/constants')
: require('./dist/shared/lib/constants')
module.exports = require('./dist/shared/lib/constants')
5 changes: 1 addition & 4 deletions packages/next/document.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/pages/_document')
: require('./dist/pages/_document')
module.exports = require('./dist/pages/_document')
5 changes: 1 addition & 4 deletions packages/next/dynamic.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/shared/lib/dynamic')
: require('./dist/shared/lib/dynamic')
module.exports = require('./dist/shared/lib/dynamic')
5 changes: 1 addition & 4 deletions packages/next/error.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/pages/_error')
: require('./dist/pages/_error')
module.exports = require('./dist/pages/_error')
5 changes: 1 addition & 4 deletions packages/next/head.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/shared/lib/head')
: require('./dist/shared/lib/head')
module.exports = require('./dist/shared/lib/head')
5 changes: 1 addition & 4 deletions packages/next/image.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/client/image')
: require('./dist/client/image')
module.exports = require('./dist/client/image')
5 changes: 1 addition & 4 deletions packages/next/link.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/client/link')
: require('./dist/client/link')
module.exports = require('./dist/client/link')
6 changes: 2 additions & 4 deletions packages/next/pages/_app.tsx
@@ -1,6 +1,6 @@
import React from 'react'

import type {
import {
loadGetInitialProps,
AppContextType,
AppInitialProps,
AppPropsType,
Expand All @@ -9,8 +9,6 @@ import type {
} from '../shared/lib/utils'
import type { Router } from '../client/router'

import { loadGetInitialProps } from '../shared/lib/utils'

export { AppInitialProps, AppType }

export { NextWebVitalsMetric }
Expand Down
5 changes: 1 addition & 4 deletions packages/next/router.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/client/router')
: require('./dist/client/router')
module.exports = require('./dist/client/router')
5 changes: 1 addition & 4 deletions packages/next/script.js
@@ -1,4 +1 @@
module.exports =
process.env.NEXT_RUNTIME === 'edge'
? require('./dist/esm/client/script')
: require('./dist/client/script')
module.exports = require('./dist/client/script')

0 comments on commit ccc8d27

Please sign in to comment.