Skip to content

Commit

Permalink
avoid retaining webpack config too long (#32053)
Browse files Browse the repository at this point in the history
avoids keeping the webpack compiler during after webpack build build steps like SSG etc.

(review with ignore whitespace)

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## 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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
  • Loading branch information
sokra authored and Kikobeats committed Dec 3, 2021
1 parent 10de48e commit b6b8d36
Showing 1 changed file with 95 additions and 91 deletions.
186 changes: 95 additions & 91 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,105 +571,112 @@ export default async function build(
ignore: [] as string[],
}))

const runWebpackSpan = nextBuildSpan.traceChild('run-webpack-compiler')
const configs = await runWebpackSpan
.traceChild('generate-webpack-config')
.traceAsyncFn(() =>
Promise.all([
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: false,
config,
target,
pagesDir,
entrypoints: entrypoints.client,
rewrites,
runWebpackSpan,
}),
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
config,
target,
pagesDir,
entrypoints: entrypoints.server,
rewrites,
runWebpackSpan,
}),
hasConcurrentFeatures
? getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
webServerRuntime: true,
config,
target,
pagesDir,
entrypoints: entrypoints.serverWeb,
rewrites,
runWebpackSpan,
})
: null,
])
)
let result: CompilerResult = { warnings: [], errors: [] }
let webpackBuildStart
let telemetryPlugin
await (async () => {
// IIFE to isolate locals and avoid retaining memory too long
const runWebpackSpan = nextBuildSpan.traceChild('run-webpack-compiler')
const configs = await runWebpackSpan
.traceChild('generate-webpack-config')
.traceAsyncFn(() =>
Promise.all([
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: false,
config,
target,
pagesDir,
entrypoints: entrypoints.client,
rewrites,
runWebpackSpan,
}),
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
config,
target,
pagesDir,
entrypoints: entrypoints.server,
rewrites,
runWebpackSpan,
}),
hasConcurrentFeatures
? getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
webServerRuntime: true,
config,
target,
pagesDir,
entrypoints: entrypoints.serverWeb,
rewrites,
runWebpackSpan,
})
: null,
])
)

const clientConfig = configs[0]
const clientConfig = configs[0]

if (
clientConfig.optimization &&
(clientConfig.optimization.minimize !== true ||
(clientConfig.optimization.minimizer &&
clientConfig.optimization.minimizer.length === 0))
) {
Log.warn(
`Production code optimization has been disabled in your project. Read more: https://nextjs.org/docs/messages/minification-disabled`
)
}
if (
clientConfig.optimization &&
(clientConfig.optimization.minimize !== true ||
(clientConfig.optimization.minimizer &&
clientConfig.optimization.minimizer.length === 0))
) {
Log.warn(
`Production code optimization has been disabled in your project. Read more: https://nextjs.org/docs/messages/minification-disabled`
)
}

const webpackBuildStart = process.hrtime()
webpackBuildStart = process.hrtime()

let result: CompilerResult = { warnings: [], errors: [] }
// We run client and server compilation separately to optimize for memory usage
await runWebpackSpan.traceAsyncFn(async () => {
const clientResult = await runCompiler(clientConfig, { runWebpackSpan })
// Fail build if clientResult contains errors
if (clientResult.errors.length > 0) {
result = {
warnings: [...clientResult.warnings],
errors: [...clientResult.errors],
}
} else {
const serverResult = await runCompiler(configs[1], { runWebpackSpan })
const serverWebResult = configs[2]
? await runCompiler(configs[2], { runWebpackSpan })
: null

result = {
warnings: [
...clientResult.warnings,
...serverResult.warnings,
...(serverWebResult?.warnings || []),
],
errors: [
...clientResult.errors,
...serverResult.errors,
...(serverWebResult?.errors || []),
],
// We run client and server compilation separately to optimize for memory usage
await runWebpackSpan.traceAsyncFn(async () => {
const clientResult = await runCompiler(clientConfig, { runWebpackSpan })
// Fail build if clientResult contains errors
if (clientResult.errors.length > 0) {
result = {
warnings: [...clientResult.warnings],
errors: [...clientResult.errors],
}
} else {
const serverResult = await runCompiler(configs[1], { runWebpackSpan })
const serverWebResult = configs[2]
? await runCompiler(configs[2], { runWebpackSpan })
: null

result = {
warnings: [
...clientResult.warnings,
...serverResult.warnings,
...(serverWebResult?.warnings || []),
],
errors: [
...clientResult.errors,
...serverResult.errors,
...(serverWebResult?.errors || []),
],
}
}
}
})
})
result = nextBuildSpan
.traceChild('format-webpack-messages')
.traceFn(() => formatWebpackMessages(result, true))

telemetryPlugin = (clientConfig as webpack.Configuration).plugins?.find(
isTelemetryPlugin
)
})()
const webpackBuildEnd = process.hrtime(webpackBuildStart)
if (buildSpinner) {
buildSpinner.stopAndPersist()
}

result = nextBuildSpan
.traceChild('format-webpack-messages')
.traceFn(() => formatWebpackMessages(result, true))

if (result.errors.length > 0) {
// Only keep the first few errors. Others are often indicative
// of the same problem, but confuse the reader with noise.
Expand Down Expand Up @@ -1871,9 +1878,6 @@ export default async function build(
})
)

const telemetryPlugin = (
clientConfig as webpack.Configuration
).plugins?.find(isTelemetryPlugin)
if (telemetryPlugin) {
const events = eventBuildFeatureUsage(telemetryPlugin)
telemetry.record(events)
Expand Down

0 comments on commit b6b8d36

Please sign in to comment.