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

Remove render workers in favor of esm loader #54813

Merged
merged 67 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
1c91427
Remove render workers in favor of esm loader
ijjk Aug 29, 2023
7fd5854
test cases
ijjk Aug 31, 2023
1723f93
telemetry case
ijjk Aug 31, 2023
1875a42
fix type
ijjk Aug 31, 2023
d7d7fbb
fix require cache case
ijjk Aug 31, 2023
6a91245
tweak request handler
ijjk Aug 31, 2023
0f286f8
fix req headers
ijjk Aug 31, 2023
809620a
fix response headers
ijjk Aug 31, 2023
733b9cb
avoid using mocked req/res for request handler
ijjk Aug 31, 2023
fe58674
middleware and config case
ijjk Aug 31, 2023
a5be36c
fix pages react aliasing with app dir
ijjk Aug 31, 2023
7cc363f
lint
ijjk Aug 31, 2023
6c79f69
config file watching
ijjk Aug 31, 2023
2c7d48e
fix build workers aliasing and config restart
ijjk Aug 31, 2023
d7164a8
lint fix
ijjk Aug 31, 2023
36621d7
fix env resetting
ijjk Aug 31, 2023
6e2cee3
fix env handling
ijjk Aug 31, 2023
d105781
Merge branch 'canary' into remove/render-workers
ijjk Aug 31, 2023
d525bf6
apply esm loader for build workers
ijjk Aug 31, 2023
97e85bb
Revert change to config.ts
timneutkens Sep 1, 2023
ca33652
prevent next.config defaults from being constantly assigned
ztanner Sep 1, 2023
f712466
Merge branch 'canary' into remove/render-workers
ztanner Sep 1, 2023
60d00d5
fix args
ztanner Sep 1, 2023
d1f3f73
Revert "prevent next.config defaults from being constantly assigned"
ztanner Sep 2, 2023
fef7850
attempt to fix image test
ztanner Sep 2, 2023
efc6ce5
check for app dir when bundling experimental react in standalone
ztanner Sep 2, 2023
373d58d
tweak test case & re-add pathPrefix check
ztanner Sep 2, 2023
6b2e97e
Merge branch 'canary' into pr-54813
ztanner Sep 2, 2023
f50d86a
fix cleanup exit code behavior
ztanner Sep 2, 2023
e62db55
tweak restart behavior
ztanner Sep 3, 2023
50567fa
pass parsedUrl to middleware request & copy over NEXT_REQUEST_META
ztanner Sep 4, 2023
1bd7d3f
questionably fix watch-config-file failure
ztanner Sep 5, 2023
3f0433f
Merge branch canary into pr-54813-2
ztanner Sep 5, 2023
35094c2
attempt a fix by adding node-polyfill-web-streams
ztanner Sep 5, 2023
9be1386
rework middleware handling
ijjk Sep 5, 2023
cb998a0
fix cases
ijjk Sep 5, 2023
8f2ee4c
Merge branch 'canary' into remove/render-workers
ijjk Sep 5, 2023
31c0b79
fix multi-zone case
ijjk Sep 6, 2023
7fc62a3
fix dev middleware cases
ijjk Sep 6, 2023
e64ffd4
add yarn pnp loader handling
ijjk Sep 6, 2023
103f011
fix more tests cases
ijjk Sep 6, 2023
5822640
missing await
ijjk Sep 6, 2023
5ad5cb3
fix middleware dev static chunks case
ijjk Sep 6, 2023
e89e234
Remove leftover await
timneutkens Sep 6, 2023
71df1f4
Merge branch 'canary' into remove/render-workers
ijjk Sep 6, 2023
c1ef15b
Merge branch 'remove/render-workers' of github.com:ijjk/next.js into …
ijjk Sep 6, 2023
ddc0dfb
remove debug fields
ijjk Sep 6, 2023
b0dacad
remove other log
ijjk Sep 6, 2023
a08ca47
remove un-needed IPC server
ijjk Sep 7, 2023
d791ddc
Merge branch 'canary' into remove/render-workers
ijjk Sep 7, 2023
e8bf9c2
rm extra error serialize
ijjk Sep 7, 2023
a6f3d52
ensure vendored is in split chunks
ijjk Sep 7, 2023
d8b5067
Merge branch 'canary' into remove/render-workers
ijjk Sep 7, 2023
b064f77
fix lint
ijjk Sep 7, 2023
410a256
Merge branch 'canary' of https://github.com/vercel/next.js into remov…
timneutkens Sep 9, 2023
4a27829
Bring back missing import that broke in merge
timneutkens Sep 9, 2023
643168a
Clarify ipc variables
timneutkens Sep 9, 2023
b19f410
Clarify initialize()
timneutkens Sep 9, 2023
f1fafd6
Remove unused properties
timneutkens Sep 9, 2023
b506e98
fix styled-jsx resolve
ijjk Sep 9, 2023
338a063
Merge branch 'canary' into remove/render-workers
ijjk Sep 11, 2023
6bbdac4
tweak require-hook handling
ijjk Sep 11, 2023
b788fb5
fix styled-jsx
ijjk Sep 11, 2023
c1cf934
extra change
ijjk Sep 11, 2023
d38f3a2
Merge branch 'canary' into remove/render-workers
ijjk Sep 11, 2023
5e6442f
fix turbopack cache clearing
ijjk Sep 11, 2023
a2df451
Merge branch 'canary' into remove/render-workers
kodiakhq[bot] Sep 11, 2023
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
92 changes: 74 additions & 18 deletions packages/next/src/bin/next.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#!/usr/bin/env node
import '../server/require-hook'
import * as log from '../build/output/log'
import arg from 'next/dist/compiled/arg/index.js'
import { NON_STANDARD_NODE_ENV } from '../lib/constants'
import { commands } from '../lib/commands'
;['react', 'react-dom'].forEach((dependency) => {
try {
// When 'npm link' is used it checks the clone location. Not the project.
require.resolve(dependency)
} catch (err) {
console.warn(
`The module '${dependency}' was not found. Next.js requires that you include it in 'dependencies' of your 'package.json'. To add it, run 'npm install ${dependency}'`
)
}
})
import { commandArgs } from '../lib/command-args'
import loadConfig from '../server/config'
import {
PHASE_PRODUCTION_SERVER,
PHASE_DEVELOPMENT_SERVER,
} from '../shared/lib/constants'
import { getProjectDir } from '../lib/get-project-dir'
import { getValidatedArgs } from '../lib/get-validated-args'
import { findPagesDir } from '../lib/find-pages-dir'

const defaultCommand = 'dev'
const args = arg(
Expand Down Expand Up @@ -122,13 +122,69 @@ if (!process.env.NEXT_MANUAL_SIG_HANDLE && command !== 'dev') {
process.on('SIGTERM', () => process.exit(0))
process.on('SIGINT', () => process.exit(0))
}
async function main() {
const currentArgsSpec = commandArgs[command]()
const validatedArgs = getValidatedArgs(currentArgsSpec, forwardedArgs)

if (
(command === 'start' || command === 'dev') &&
!process.env.NEXT_PRIVATE_WORKER
) {
const dir = getProjectDir(
process.env.NEXT_PRIVATE_DEV_DIR || validatedArgs._[0]
)
process.env.NEXT_PRIVATE_DIR = dir
const origEnv = Object.assign({}, process.env)

// TODO: set config to env variable to be re-used so we don't reload
// un-necessarily
const config = await loadConfig(
command === 'dev' ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
dir
)
let dirsResult: ReturnType<typeof findPagesDir> | undefined = undefined

try {
dirsResult = findPagesDir(dir)
} catch (_) {
// handle this error further down
}

commands[command]()
.then((exec) => exec(forwardedArgs))
.then(() => {
if (command === 'build' || command === 'experimental-compile') {
// ensure process exits after build completes so open handles/connections
// don't cause process to hang
process.exit(0)
if (dirsResult?.appDir || process.env.NODE_ENV === 'development') {
process.env = origEnv
}
})

if (dirsResult?.appDir) {
// we need to reset env if we are going to create
// the worker process with the esm loader so that the
// initial env state is correct
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = config.experimental
.serverActions
? 'experimental'
: 'next'
}
}

for (const dependency of ['react', 'react-dom']) {
try {
// When 'npm link' is used it checks the clone location. Not the project.
require.resolve(dependency)
} catch (err) {
console.warn(
`The module '${dependency}' was not found. Next.js requires that you include it in 'dependencies' of your 'package.json'. To add it, run 'npm install ${dependency}'`
)
}
}

await commands[command]()
.then((exec) => exec(validatedArgs))
.then(() => {
if (command === 'build' || command === 'experimental-compile') {
// ensure process exits after build completes so open handles/connections
// don't cause process to hang
process.exit(0)
}
})
}

main()
70 changes: 44 additions & 26 deletions packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,10 @@ import {
baseOverrides,
defaultOverrides,
experimentalOverrides,
} from '../server/require-hook'
import { initialize } from '../server/lib/incremental-cache-server'
} from '../server/import-overrides'
import { initialize as initializeIncrementalCache } from '../server/lib/incremental-cache-server'
import { nodeFs } from '../server/lib/node-fs-methods'
import { getEsmLoaderPath } from '../server/lib/get-esm-loader-path'

export type SsgRoute = {
initialRevalidateSeconds: number | false
Expand Down Expand Up @@ -1207,9 +1208,8 @@ export default async function build(
: config.experimental.cpus || 4

function createStaticWorker(
type: 'app' | 'pages',
ipcPort: number,
ipcValidationKey: string
incrementalCacheIpcPort: number,
incrementalCacheIpcValidationKey: string
) {
let infoPrinted = false

Expand Down Expand Up @@ -1246,16 +1246,21 @@ export default async function build(
},
numWorkers,
forkOptions: {
execArgv: [
'--experimental-loader',
getEsmLoaderPath(),
'--no-warnings',
],
env: {
...process.env,
__NEXT_INCREMENTAL_CACHE_IPC_PORT: ipcPort + '',
__NEXT_INCREMENTAL_CACHE_IPC_KEY: ipcValidationKey,
__NEXT_PRIVATE_PREBUNDLED_REACT:
type === 'app'
? config.experimental.serverActions
? 'experimental'
: 'next'
: undefined,
__NEXT_INCREMENTAL_CACHE_IPC_PORT: incrementalCacheIpcPort + '',
__NEXT_INCREMENTAL_CACHE_IPC_KEY:
incrementalCacheIpcValidationKey,
__NEXT_PRIVATE_PREBUNDLED_REACT: hasAppDir
? config.experimental.serverActions
? 'experimental'
: 'next'
: '',
},
},
enableWorkerThreads: config.experimental.workerThreads,
Expand Down Expand Up @@ -1290,7 +1295,10 @@ export default async function build(
CacheHandler = CacheHandler.default || CacheHandler
}

const { ipcPort, ipcValidationKey } = await initialize({
const {
ipcPort: incrementalCacheIpcPort,
ipcValidationKey: incrementalCacheIpcValidationKey,
} = await initializeIncrementalCache({
fs: nodeFs,
dev: false,
appDir: isAppDirEnabled,
Expand All @@ -1315,12 +1323,14 @@ export default async function build(
})

const pagesStaticWorkers = createStaticWorker(
'pages',
ipcPort,
ipcValidationKey
incrementalCacheIpcPort,
incrementalCacheIpcValidationKey
)
const appStaticWorkers = isAppDirEnabled
? createStaticWorker('app', ipcPort, ipcValidationKey)
? createStaticWorker(
incrementalCacheIpcPort,
incrementalCacheIpcValidationKey
)
: undefined

const analysisBegin = process.hrtime()
Expand Down Expand Up @@ -2124,9 +2134,14 @@ export default async function build(

const vanillaServerEntries = [
...sharedEntriesSet,
isStandalone
? require.resolve('next/dist/server/lib/start-server')
: null,
...(isStandalone
? [
require.resolve('next/dist/server/lib/start-server'),
require.resolve('next/dist/server/next'),
require.resolve('next/dist/esm/server/esm-loader.mjs'),
require.resolve('next/dist/server/import-overrides'),
]
: []),
require.resolve('next/dist/server/next-server'),
].filter(Boolean) as string[]

Expand Down Expand Up @@ -2402,7 +2417,8 @@ export default async function build(
outputFileTracingRoot,
requiredServerFiles.config,
middlewareManifest,
hasInstrumentationHook
hasInstrumentationHook,
hasAppDir
)
})
}
Expand Down Expand Up @@ -3315,11 +3331,13 @@ export default async function build(
require('../export').default

const pagesWorker = createStaticWorker(
'pages',
ipcPort,
ipcValidationKey
incrementalCacheIpcPort,
incrementalCacheIpcValidationKey
)
const appWorker = createStaticWorker(
incrementalCacheIpcPort,
incrementalCacheIpcValidationKey
)
const appWorker = createStaticWorker('app', ipcPort, ipcValidationKey)

const options: ExportOptions = {
isInvokedFromCli: false,
Expand Down
21 changes: 13 additions & 8 deletions packages/next/src/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1830,7 +1830,8 @@ export async function copyTracedFiles(
tracingRoot: string,
serverConfig: { [key: string]: any },
middlewareManifest: MiddlewareManifest,
hasInstrumentationHook: boolean
hasInstrumentationHook: boolean,
hasAppDir: boolean
) {
const outputPath = path.join(distDir, 'standalone')
let moduleType = false
Expand Down Expand Up @@ -1963,12 +1964,11 @@ export async function copyTracedFiles(
moduleType
? `import path from 'path'
import { fileURLToPath } from 'url'
import module from 'module'
const require = module.createRequire(import.meta.url)
const __dirname = fileURLToPath(new URL('.', import.meta.url))
import { startServer } from 'next/dist/server/lib/start-server.js'
`
: `
const path = require('path')
const { startServer } = require('next/dist/server/lib/start-server')`
: `const path = require('path')`
}

const dir = path.join(__dirname)
Expand All @@ -1993,9 +1993,14 @@ const nextConfig = ${JSON.stringify({
})}

process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = nextConfig.experimental && nextConfig.experimental.serverActions
? 'experimental'
: 'next'
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = ${hasAppDir}
? nextConfig.experimental && nextConfig.experimental.serverActions
? 'experimental'
: 'next'
: '';

require('next')
const { startServer } = require('next/dist/server/lib/start-server')

if (
Number.isNaN(keepAliveTimeout) ||
Expand Down
31 changes: 22 additions & 9 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { NextFontManifestPlugin } from './webpack/plugins/next-font-manifest-plu
import { getSupportedBrowsers } from './utils'
import { MemoryWithGcCachePlugin } from './webpack/plugins/memory-with-gc-cache-plugin'
import { getBabelConfigFile } from './get-babel-config-file'
import { defaultOverrides } from '../server/import-overrides'

type ExcludesFalse = <T>(x: T | false) => x is T
type ClientEntries = {
Expand Down Expand Up @@ -1127,6 +1128,14 @@ export default async function getBaseWebpackConfig(
'@opentelemetry/api': 'next/dist/compiled/@opentelemetry/api',
}),

...(hasAppDir
? createRSCAliases(bundledReactChannel, {
reactSharedSubset: false,
reactDomServerRenderingStub: false,
reactProductionProfiling,
})
: {}),

...(config.images.loaderFile
? {
'next/dist/shared/lib/image-loader': config.images.loaderFile,
Expand All @@ -1138,8 +1147,8 @@ export default async function getBaseWebpackConfig(

next: NEXT_PROJECT_ROOT,

'styled-jsx/style$': require.resolve(`styled-jsx/style`),
'styled-jsx$': require.resolve(`styled-jsx`),
'styled-jsx/style$': defaultOverrides['styled-jsx/style'],
'styled-jsx$': defaultOverrides['styled-jsx'],

...customAppAliases,
...customErrorAlias,
Expand Down Expand Up @@ -1273,7 +1282,16 @@ export default async function getBaseWebpackConfig(
}
}

for (const packageName of ['react', 'react-dom']) {
for (const packageName of [
'react',
'react-dom',
...(hasAppDir
? [
`next/dist/compiled/react${bundledReactChannel}`,
`next/dist/compiled/react-dom${bundledReactChannel}`,
]
: []),
]) {
addPackagePath(packageName, dir)
}

Expand Down Expand Up @@ -1541,7 +1559,7 @@ export default async function getBaseWebpackConfig(
// Forcedly resolve the styled-jsx installed by next.js,
// since `resolveExternal` cannot find the styled-jsx dep with pnpm
if (request === 'styled-jsx/style') {
resolveResult.res = require.resolve(request)
resolveResult.res = defaultOverrides['styled-jsx/style']
}

const { res, isEsm } = resolveResult
Expand Down Expand Up @@ -2116,11 +2134,6 @@ export default async function getBaseWebpackConfig(
[require.resolve('next/dynamic')]: require.resolve(
'next/dist/shared/lib/app-dynamic'
),
...createRSCAliases(bundledReactChannel, {
reactSharedSubset: false,
reactDomServerRenderingStub: false,
reactProductionProfiling,
}),
},
},
},
Expand Down
Loading
Loading