Skip to content

Commit

Permalink
Skip loading unused plugins in next dev (#37430)
Browse files Browse the repository at this point in the history
* dynamically load plugins; switch to type imports; fix page extensions

* fix default export
  • Loading branch information
shuding committed Jun 3, 2022
1 parent 401a9a4 commit 95bd68d
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 66 deletions.
2 changes: 1 addition & 1 deletion packages/next/build/load-jsconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as Log from './output/log'
import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'
import { readFileSync } from 'fs'
import isError from '../lib/is-error'
import { codeFrameColumns } from 'next/dist/compiled/babel/code-frame'

let TSCONFIG_WARNED = false

Expand All @@ -22,6 +21,7 @@ function parseJsonFile(filePath: string) {
return JSON5.parse(contents)
} catch (err) {
if (!isError(err)) throw err
const { codeFrameColumns } = require('next/dist/compiled/babel/code-frame')
const codeFrame = codeFrameColumns(
String(contents),
{
Expand Down
32 changes: 16 additions & 16 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import MiddlewarePlugin from './webpack/plugins/middleware-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import { JsConfigPathsPlugin } from './webpack/plugins/jsconfig-paths-plugin'
import { DropClientPage } from './webpack/plugins/next-drop-client-page-plugin'
import { TraceEntryPointsPlugin } from './webpack/plugins/next-trace-entrypoints-plugin'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import { ProfilingPlugin } from './webpack/plugins/profiling-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
Expand All @@ -47,16 +46,14 @@ import { regexLikeCss } from './webpack/config/blocks/css'
import { CopyFilePlugin } from './webpack/plugins/copy-file-plugin'
import { FlightManifestPlugin } from './webpack/plugins/flight-manifest-plugin'
import { ClientEntryPlugin } from './webpack/plugins/client-entry-plugin'
import {
import type {
Feature,
SWC_TARGET_TRIPLE,
TelemetryPlugin,
} from './webpack/plugins/telemetry-plugin'
import type { Span } from '../trace'
import { withoutRSCExtensions } from './utils'
import browserslist from 'next/dist/compiled/browserslist'
import loadJsConfig from './load-jsconfig'
import { getMiddlewareSourceMapPlugins } from './webpack/plugins/middleware-source-maps-plugin'
import { loadBindings } from './swc'

const watchOptions = Object.freeze({
Expand Down Expand Up @@ -357,6 +354,7 @@ export default async function getBaseWebpackConfig(
dir,
config
)

const supportedBrowsers = await getSupportedBrowsers(dir, dev, config)

const hasRewrites =
Expand Down Expand Up @@ -607,21 +605,21 @@ export default async function getBaseWebpackConfig(

if (dev) {
customAppAliases[`${PAGES_DIR_ALIAS}/_app`] = [
...config.pageExtensions.reduce((prev, ext) => {
...rawPageExtensions.reduce((prev, ext) => {
prev.push(path.join(pagesDir, `_app.${ext}`))
return prev
}, [] as string[]),
'next/dist/pages/_app.js',
]
customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [
...config.pageExtensions.reduce((prev, ext) => {
...rawPageExtensions.reduce((prev, ext) => {
prev.push(path.join(pagesDir, `_error.${ext}`))
return prev
}, [] as string[]),
'next/dist/pages/_error.js',
]
customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [
...config.pageExtensions.reduce((prev, ext) => {
...rawPageExtensions.reduce((prev, ext) => {
prev.push(path.join(pagesDir, `_document.${ext}`))
return prev
}, [] as string[]),
Expand Down Expand Up @@ -1428,7 +1426,7 @@ export default async function getBaseWebpackConfig(
isEdgeServer &&
!!config.experimental.middlewareSourceMaps &&
!config.productionBrowserSourceMaps
? getMiddlewareSourceMapPlugins()
? require('./webpack/plugins/middleware-source-maps-plugin').getMiddlewareSourceMapPlugins()
: []),
dev && isClient && new ReactRefreshWebpackPlugin(webpack),
// Makes sure `Buffer` and `process` are polyfilled in client and flight bundles (same behavior as webpack 4)
Expand Down Expand Up @@ -1571,12 +1569,14 @@ export default async function getBaseWebpackConfig(
!isLikeServerless &&
(isNodeServer || isEdgeServer) &&
!dev &&
new TraceEntryPointsPlugin({
appDir: dir,
esmExternals: config.experimental.esmExternals,
staticImageImports: !config.images.disableStaticImages,
outputFileTracingRoot: config.experimental.outputFileTracingRoot,
}),
new (require('./webpack/plugins/next-trace-entrypoints-plugin').TraceEntryPointsPlugin)(
{
appDir: dir,
esmExternals: config.experimental.esmExternals,
staticImageImports: !config.images.disableStaticImages,
outputFileTracingRoot: config.experimental.outputFileTracingRoot,
}
),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
Expand Down Expand Up @@ -1671,7 +1671,7 @@ export default async function getBaseWebpackConfig(
})),
!dev &&
isClient &&
new TelemetryPlugin(
new (require('./webpack/plugins/telemetry-plugin').TelemetryPlugin)(
new Map(
[
['swcLoader', useSWCLoader],
Expand Down Expand Up @@ -1795,7 +1795,7 @@ export default async function getBaseWebpackConfig(

const configVars = JSON.stringify({
crossOrigin: config.crossOrigin,
pageExtensions: config.pageExtensions,
pageExtensions: rawPageExtensions,
trailingSlash: config.trailingSlash,
buildActivity: config.devIndicators.buildActivity,
buildActivityPosition: config.devIndicators.buildActivityPosition,
Expand Down
3 changes: 2 additions & 1 deletion packages/next/build/webpack/config/blocks/css/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import curry from 'next/dist/compiled/lodash.curry'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import MiniCssExtractPlugin from '../../../plugins/mini-css-extract-plugin'
import { loader, plugin } from '../../helpers'
import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils'
import { getCssModuleLoader, getGlobalCssLoader } from './loaders'
Expand Down Expand Up @@ -414,6 +413,8 @@ export const css = curry(async function css(

if (ctx.isClient && ctx.isProduction) {
// Extract CSS as CSS file(s) in the client-side production bundle.
const MiniCssExtractPlugin =
require('../../../plugins/mini-css-extract-plugin').default
fns.push(
plugin(
// @ts-ignore webpack 5 compat
Expand Down
61 changes: 32 additions & 29 deletions packages/next/build/webpack/config/blocks/css/loaders/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import MiniCssExtractPlugin from '../../../../plugins/mini-css-extract-plugin'
import type { webpack } from 'next/dist/compiled/webpack/webpack'

export function getClientStyleLoader({
isDevelopment,
Expand All @@ -8,33 +7,37 @@ export function getClientStyleLoader({
isDevelopment: boolean
assetPrefix: string
}): webpack.RuleSetUseItem {
return isDevelopment
? {
loader: 'next-style-loader',
options: {
// By default, style-loader injects CSS into the bottom
// of <head>. This causes ordering problems between dev
// and prod. To fix this, we render a <noscript> tag as
// an anchor for the styles to be placed before. These
// styles will be applied _before_ <style jsx global>.
insert: function (element: Node) {
// These elements should always exist. If they do not,
// this code should fail.
var anchorElement = document.querySelector(
'#__next_css__DO_NOT_USE__'
)!
var parentNode = anchorElement.parentNode! // Normally <head>
if (isDevelopment) {
return {
loader: 'next-style-loader',
options: {
// By default, style-loader injects CSS into the bottom
// of <head>. This causes ordering problems between dev
// and prod. To fix this, we render a <noscript> tag as
// an anchor for the styles to be placed before. These
// styles will be applied _before_ <style jsx global>.
insert: function (element: Node) {
// These elements should always exist. If they do not,
// this code should fail.
var anchorElement = document.querySelector(
'#__next_css__DO_NOT_USE__'
)!
var parentNode = anchorElement.parentNode! // Normally <head>

// Each style tag should be placed right before our
// anchor. By inserting before and not after, we do not
// need to track the last inserted element.
parentNode.insertBefore(element, anchorElement)
},
// Each style tag should be placed right before our
// anchor. By inserting before and not after, we do not
// need to track the last inserted element.
parentNode.insertBefore(element, anchorElement)
},
}
: {
// @ts-ignore: TODO: remove when webpack 5 is stable
loader: MiniCssExtractPlugin.loader,
options: { publicPath: `${assetPrefix}/_next/`, esModule: false },
}
},
}
}

const MiniCssExtractPlugin =
require('../../../../plugins/mini-css-extract-plugin').default
return {
// @ts-ignore: TODO: remove when webpack 5 is stable
loader: MiniCssExtractPlugin.loader,
options: { publicPath: `${assetPrefix}/_next/`, esModule: false },
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../../../utils'
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import type { ConfigurationContext } from '../../../utils'

import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve'

Expand Down
5 changes: 3 additions & 2 deletions packages/next/build/webpack/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { NextConfigComplete } from '../../../server/config-shared'
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import type { NextConfigComplete } from '../../../server/config-shared'

import { base } from './blocks/base'
import { css } from './blocks/css'
import { images } from './blocks/images'
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack/config/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { NextConfigComplete } from '../../../server/config-shared'
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import type { NextConfigComplete } from '../../../server/config-shared'

export type ConfigurationContext = {
supportedBrowsers: string[] | undefined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import type { NextConfig } from '../../../../server/config-shared'

import { getModuleBuildError } from './webpackModuleError'
import { NextConfig } from '../../../../server/config-shared'

export class WellKnownErrorsPlugin {
config: NextConfig
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { codeFrameColumns } from 'next/dist/compiled/babel/code-frame'
import Chalk from 'next/dist/compiled/chalk'
import { SimpleWebpackError } from './simpleWebpackError'

Expand All @@ -24,6 +23,9 @@ export function getScssError(
let frame: string | undefined
if (fileContent) {
try {
const {
codeFrameColumns,
} = require('next/dist/compiled/babel/code-frame')
frame = codeFrameColumns(
fileContent,
{ start: { line: lineNumber, column } },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { readFileSync } from 'fs'
import * as path from 'path'
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import type { NextConfig } from '../../../../server/config-shared'

import { getBabelError } from './parseBabel'
import { getCssError } from './parseCss'
import { getScssError } from './parseScss'
import { getNotFoundError } from './parseNotFoundError'
import { SimpleWebpackError } from './simpleWebpackError'
import isError from '../../../../lib/is-error'
import { NextConfig } from '../../../../server/config-shared'

function getFileData(
compilation: webpack.Compilation,
Expand Down
14 changes: 7 additions & 7 deletions packages/next/server/dev/hot-reloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { denormalizePagePath } from '../../shared/lib/page-path/denormalize-page
import { normalizePathSep } from '../../shared/lib/page-path/normalize-path-sep'
import getRouteFromEntrypoint from '../get-route-from-entrypoint'
import { fileExists } from '../../lib/file-exists'
import { difference } from '../../build/utils'
import { difference, withoutRSCExtensions } from '../../build/utils'
import { NextConfigComplete } from '../config-shared'
import { CustomRoutes } from '../../lib/load-custom-routes'
import { DecodeError } from '../../shared/lib/utils'
Expand Down Expand Up @@ -382,17 +382,17 @@ export default class HotReloader {
private async getWebpackConfig(span: Span) {
const webpackConfigSpan = span.traceChild('get-webpack-config')

const rawPageExtensions = this.hasServerComponents
? withoutRSCExtensions(this.config.pageExtensions)
: this.config.pageExtensions

return webpackConfigSpan.traceAsyncFn(async () => {
const pagePaths = await webpackConfigSpan
.traceChild('get-page-paths')
.traceAsyncFn(() =>
Promise.all([
findPageFile(this.pagesDir, '/_app', this.config.pageExtensions),
findPageFile(
this.pagesDir,
'/_document',
this.config.pageExtensions
),
findPageFile(this.pagesDir, '/_app', rawPageExtensions),
findPageFile(this.pagesDir, '/_document', rawPageExtensions),
])
)

Expand Down
5 changes: 3 additions & 2 deletions packages/next/server/dev/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import crypto from 'crypto'
import fs from 'fs'
import chalk from 'next/dist/compiled/chalk'
import { Worker } from 'next/dist/compiled/jest-worker'
import AmpHtmlValidator from 'next/dist/compiled/amphtml-validator'
import findUp from 'next/dist/compiled/find-up'
import { join as pathJoin, relative, resolve as pathResolve, sep } from 'path'
import React from 'react'
Expand Down Expand Up @@ -164,6 +163,8 @@ export default class DevServer extends Server {
this.nextConfig.experimental &&
this.nextConfig.experimental.amp &&
this.nextConfig.experimental.amp.validator
const AmpHtmlValidator =
require('next/dist/compiled/amphtml-validator') as typeof import('next/dist/compiled/amphtml-validator')
return AmpHtmlValidator.getInstance(validatorPath).then((validator) => {
const result = validator.validateString(html)
ampValidation(
Expand Down Expand Up @@ -270,7 +271,7 @@ export default class DevServer extends Server {
}
})

let wp = (this.webpackWatcher = new Watchpack())
const wp = (this.webpackWatcher = new Watchpack())
const pages = [this.pagesDir]
const app = this.appDir ? [this.appDir] : []
const directories = [...pages, ...app]
Expand Down
1 change: 0 additions & 1 deletion packages/next/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ export default class NextNodeServer extends BaseServer {
if (!this.minimalMode) {
const { ImageOptimizerCache } =
require('./image-optimizer') as typeof import('./image-optimizer')

this.imageResponseCache = new ResponseCache(
new ImageOptimizerCache({
distDir: this.distDir,
Expand Down

0 comments on commit 95bd68d

Please sign in to comment.