Skip to content

Commit

Permalink
make worker for configuration loading lighter
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Apr 16, 2021
1 parent 5e267c8 commit b342a51
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 100 deletions.
101 changes: 101 additions & 0 deletions packages/next/next-server/server/config-utils-worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { loadEnvConfig } from '@next/env'
import findUp from 'next/dist/compiled/find-up'
import { init as initWebpack } from 'next/dist/compiled/webpack/webpack'
import { CONFIG_FILE, PHASE_DEVELOPMENT_SERVER } from '../lib/constants'
import { NextConfig, normalizeConfig } from './config-shared'
import * as Log from '../../build/output/log'

let installed: boolean = false

export function install(useWebpack5: boolean) {
if (installed) {
return
}
installed = true

initWebpack(useWebpack5)

// hook the Node.js require so that webpack requires are
// routed to the bundled and now initialized webpack version
require('../../build/webpack/require-hook')
}

export type CheckReasons =
| 'test-mode'
| 'no-config'
| 'future-flag'
| 'no-future-flag'
| 'no-webpack-config'
| 'webpack-config'

export type CheckResult = {
enabled: boolean
reason: CheckReasons
}

export async function shouldLoadWithWebpack5(
phase: string,
dir: string
): Promise<CheckResult> {
await loadEnvConfig(dir, phase === PHASE_DEVELOPMENT_SERVER, Log)

const path = await findUp(CONFIG_FILE, {
cwd: dir,
})

if (Number(process.env.NEXT_PRIVATE_TEST_WEBPACK5_MODE) > 0) {
return {
enabled: true,
reason: 'test-mode',
}
}

// No `next.config.js`:
if (!path?.length) {
// Uncomment to add auto-enable when there is no next.config.js
// Use webpack 5 by default in new apps:
return {
enabled: true,
reason: 'no-config',
}
}

// Default to webpack 4 for backwards compatibility on boot:
install(false)

const userConfigModule = require(path)
const userConfig: Partial<NextConfig> = normalizeConfig(
phase,
userConfigModule.default || userConfigModule
)

// Opted-in manually
if (userConfig.future?.webpack5 === true) {
return {
enabled: true,
reason: 'future-flag',
}
}

// Opted-out manually
if (userConfig.future?.webpack5 === false) {
return {
enabled: false,
reason: 'no-future-flag',
}
}

// Uncomment to add auto-enable when there is no custom webpack config
// The user isn't configuring webpack
if (!userConfig.webpack) {
return {
enabled: true,
reason: 'no-webpack-config',
}
}

return {
enabled: false,
reason: 'webpack-config',
}
}
111 changes: 11 additions & 100 deletions packages/next/next-server/server/config-utils.ts
Original file line number Diff line number Diff line change
@@ -1,105 +1,10 @@
import { loadEnvConfig } from '@next/env'
import path from 'path'
import { Worker } from 'jest-worker'
import findUp from 'next/dist/compiled/find-up'
import { init as initWebpack } from 'next/dist/compiled/webpack/webpack'
import { CONFIG_FILE, PHASE_DEVELOPMENT_SERVER } from '../lib/constants'
import { NextConfig, normalizeConfig } from './config-shared'
import * as Log from '../../build/output/log'
import type { CheckReasons, CheckResult } from './config-utils-worker'
import { install, shouldLoadWithWebpack5 } from './config-utils-worker'

let installed: boolean = false

export function install(useWebpack5: boolean) {
if (installed) {
return
}
installed = true

initWebpack(useWebpack5)

// hook the Node.js require so that webpack requires are
// routed to the bundled and now initialized webpack version
require('../../build/webpack/require-hook')
}

type CheckReasons =
| 'test-mode'
| 'no-config'
| 'future-flag'
| 'no-future-flag'
| 'no-webpack-config'
| 'webpack-config'

type CheckResult = {
enabled: boolean
reason: CheckReasons
}

export async function shouldLoadWithWebpack5(
phase: string,
dir: string
): Promise<CheckResult> {
await loadEnvConfig(dir, phase === PHASE_DEVELOPMENT_SERVER, Log)

const path = await findUp(CONFIG_FILE, {
cwd: dir,
})

if (Number(process.env.NEXT_PRIVATE_TEST_WEBPACK5_MODE) > 0) {
return {
enabled: true,
reason: 'test-mode',
}
}

// No `next.config.js`:
if (!path?.length) {
// Uncomment to add auto-enable when there is no next.config.js
// Use webpack 5 by default in new apps:
return {
enabled: true,
reason: 'no-config',
}
}

// Default to webpack 4 for backwards compatibility on boot:
install(false)

const userConfigModule = require(path)
const userConfig: Partial<NextConfig> = normalizeConfig(
phase,
userConfigModule.default || userConfigModule
)

// Opted-in manually
if (userConfig.future?.webpack5 === true) {
return {
enabled: true,
reason: 'future-flag',
}
}

// Opted-out manually
if (userConfig.future?.webpack5 === false) {
return {
enabled: false,
reason: 'no-future-flag',
}
}

// Uncomment to add auto-enable when there is no custom webpack config
// The user isn't configuring webpack
if (!userConfig.webpack) {
return {
enabled: true,
reason: 'no-webpack-config',
}
}

return {
enabled: false,
reason: 'webpack-config',
}
}
export { install, shouldLoadWithWebpack5 }

function reasonMessage(reason: CheckReasons) {
switch (reason) {
Expand All @@ -122,7 +27,13 @@ function reasonMessage(reason: CheckReasons) {

export async function loadWebpackHook(phase: string, dir: string) {
let useWebpack5 = false
const worker: any = new Worker(__filename, { enableWorkerThreads: false })
const worker: any = new Worker(
path.resolve(__dirname, './config-utils-worker.js'),
{
enableWorkerThreads: true,
numWorkers: 1,
}
)
try {
const result: CheckResult = await worker.shouldLoadWithWebpack5(phase, dir)
Log.info(
Expand Down

0 comments on commit b342a51

Please sign in to comment.