Skip to content

Commit 1fc0aae

Browse files
authored
Prepare for webpack 5 upgrade (#14268)
Tweaked the config that can already be updated a bit.
1 parent 11753dd commit 1fc0aae

File tree

4 files changed

+72
-49
lines changed

4 files changed

+72
-49
lines changed

packages/next/build/compiler.ts

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,49 @@ function generateStats(result: CompilerResult, stat: Stats): CompilerResult {
1818
return result
1919
}
2020

21+
// Webpack 5 requires the compiler to be closed (to save caches)
22+
// Webpack 4 does not have this close method so in order to be backwards compatible we check if it exists
23+
function closeCompiler(compiler: webpack.Compiler | webpack.MultiCompiler) {
24+
return new Promise((resolve, reject) => {
25+
if ('close' in compiler) {
26+
// @ts-ignore Close only exists on the compiler in webpack 5
27+
return compiler.close((err: any) => (err ? reject(err) : resolve()))
28+
}
29+
30+
resolve()
31+
})
32+
}
33+
2134
export function runCompiler(
2235
config: Configuration | Configuration[]
2336
): Promise<CompilerResult> {
24-
return new Promise(async (resolve, reject) => {
37+
return new Promise((resolve, reject) => {
2538
const compiler = webpack(config)
2639
compiler.run(
2740
(err: Error, statsOrMultiStats: { stats: Stats[] } | Stats) => {
28-
if (err) {
29-
const reason = err?.toString()
30-
if (reason) {
31-
return resolve({ errors: [reason], warnings: [] })
41+
closeCompiler(compiler).then(() => {
42+
if (err) {
43+
const reason = err?.toString()
44+
if (reason) {
45+
return resolve({ errors: [reason], warnings: [] })
46+
}
47+
return reject(err)
3248
}
33-
return reject(err)
34-
}
3549

36-
if ('stats' in statsOrMultiStats) {
37-
const result: CompilerResult = statsOrMultiStats.stats.reduce(
38-
generateStats,
39-
{ errors: [], warnings: [] }
50+
if ('stats' in statsOrMultiStats) {
51+
const result: CompilerResult = statsOrMultiStats.stats.reduce(
52+
generateStats,
53+
{ errors: [], warnings: [] }
54+
)
55+
return resolve(result)
56+
}
57+
58+
const result = generateStats(
59+
{ errors: [], warnings: [] },
60+
statsOrMultiStats
4061
)
4162
return resolve(result)
42-
}
43-
44-
const result = generateStats(
45-
{ errors: [], warnings: [] },
46-
statsOrMultiStats
47-
)
48-
return resolve(result)
63+
})
4964
}
5065
)
5166
})

packages/next/build/webpack-config.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { readFileSync } from 'fs'
44
import chalk from 'next/dist/compiled/chalk'
55
import TerserPlugin from 'next/dist/compiled/terser-webpack-plugin'
66
import path from 'path'
7-
import PnpWebpackPlugin from 'pnp-webpack-plugin'
87
import webpack from 'webpack'
98
import {
109
DOT_NEXT_ALIAS,
@@ -37,7 +36,6 @@ import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
3736
import { CssMinimizerPlugin } from './webpack/plugins/css-minimizer-plugin'
3837
import { JsConfigPathsPlugin } from './webpack/plugins/jsconfig-paths-plugin'
3938
import { DropClientPage } from './webpack/plugins/next-drop-client-page-plugin'
40-
import NextEsmPlugin from './webpack/plugins/next-esm-plugin'
4139
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
4240
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
4341
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
@@ -302,7 +300,7 @@ export default async function getBaseWebpackConfig(
302300
plugins: isWebpack5
303301
? // webpack 5+ has the PnP resolver built-in by default:
304302
[]
305-
: [PnpWebpackPlugin],
303+
: [require('pnp-webpack-plugin')],
306304
}
307305

308306
const webpackMode = dev ? 'development' : 'production'
@@ -347,13 +345,17 @@ export default async function getBaseWebpackConfig(
347345
cacheGroups: {
348346
default: false,
349347
vendors: false,
348+
// In webpack 5 vendors was renamed to defaultVendors
349+
defaultVendors: false,
350350
},
351351
},
352352
prodGranular: {
353353
chunks: 'all',
354354
cacheGroups: {
355355
default: false,
356356
vendors: false,
357+
// In webpack 5 vendors was renamed to defaultVendors
358+
defaultVendors: false,
357359
framework: {
358360
chunks: 'all',
359361
name: 'framework',
@@ -736,7 +738,7 @@ export default async function getBaseWebpackConfig(
736738
'node_modules',
737739
...nodePathList, // Support for NODE_PATH environment variable
738740
],
739-
plugins: [PnpWebpackPlugin],
741+
plugins: isWebpack5 ? [] : [require('pnp-webpack-plugin')],
740742
},
741743
module: {
742744
rules: [
@@ -881,7 +883,10 @@ export default async function getBaseWebpackConfig(
881883
// solution that requires the user to opt into importing specific locales.
882884
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
883885
config.future.excludeDefaultMomentLocales &&
884-
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
886+
new webpack.IgnorePlugin({
887+
resourceRegExp: /^\.\/locale$/,
888+
contextRegExp: /moment$/,
889+
}),
885890
...(dev
886891
? (() => {
887892
// Even though require.cache is server only we have to clear assets from both compilations
@@ -931,22 +936,25 @@ export default async function getBaseWebpackConfig(
931936
config.experimental.modern &&
932937
!isServer &&
933938
!dev &&
934-
new NextEsmPlugin({
935-
filename: (getFileName: Function | string) => (...args: any[]) => {
936-
const name =
937-
typeof getFileName === 'function'
938-
? getFileName(...args)
939-
: getFileName
940-
941-
return name.includes('.js')
942-
? name.replace(/\.js$/, '.module.js')
943-
: escapePathVariables(
944-
args[0].chunk.name.replace(/\.js$/, '.module.js')
945-
)
946-
},
947-
chunkFilename: (inputChunkName: string) =>
948-
inputChunkName.replace(/\.js$/, '.module.js'),
949-
}),
939+
(() => {
940+
const { NextEsmPlugin } = require('./webpack/plugins/next-esm-plugin')
941+
return new NextEsmPlugin({
942+
filename: (getFileName: Function | string) => (...args: any[]) => {
943+
const name =
944+
typeof getFileName === 'function'
945+
? getFileName(...args)
946+
: getFileName
947+
948+
return name.includes('.js')
949+
? name.replace(/\.js$/, '.module.js')
950+
: escapePathVariables(
951+
args[0].chunk.name.replace(/\.js$/, '.module.js')
952+
)
953+
},
954+
chunkFilename: (inputChunkName: string) =>
955+
inputChunkName.replace(/\.js$/, '.module.js'),
956+
})
957+
})(),
950958
config.experimental.conformance &&
951959
!dev &&
952960
new WebpackConformancePlugin({

packages/next/build/webpack/config/blocks/css/index.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const css = curry(async function css(
8989
test: regexLikeCss,
9090
// Use a loose regex so we don't have to crawl the file system to
9191
// find the real file name (if present).
92-
issuer: { test: /pages[\\/]_document\./ },
92+
issuer: /pages[\\/]_document\./,
9393
use: {
9494
loader: 'error-loader',
9595
options: {
@@ -117,8 +117,8 @@ export const css = curry(async function css(
117117
// CSS Modules are only supported in the user's application. We're
118118
// not yet allowing CSS imports _within_ `node_modules`.
119119
issuer: {
120-
include: [ctx.rootDirectory],
121-
exclude: /node_modules/,
120+
and: [ctx.rootDirectory],
121+
not: [/node_modules/],
122122
},
123123
use: getCssModuleLoader(ctx, postCssPlugins),
124124
},
@@ -140,8 +140,8 @@ export const css = curry(async function css(
140140
// Sass Modules are only supported in the user's application. We're
141141
// not yet allowing Sass imports _within_ `node_modules`.
142142
issuer: {
143-
include: [ctx.rootDirectory],
144-
exclude: /node_modules/,
143+
and: [ctx.rootDirectory],
144+
not: [/node_modules/],
145145
},
146146
use: getCssModuleLoader(ctx, postCssPlugins, sassPreprocessors),
147147
},
@@ -188,7 +188,7 @@ export const css = curry(async function css(
188188
// See https://github.com/webpack/webpack/issues/6571
189189
sideEffects: true,
190190
test: regexCssGlobal,
191-
issuer: { include: ctx.customAppFile },
191+
issuer: { and: [ctx.customAppFile] },
192192
use: getGlobalCssLoader(ctx, postCssPlugins),
193193
},
194194
],
@@ -204,7 +204,7 @@ export const css = curry(async function css(
204204
// See https://github.com/webpack/webpack/issues/6571
205205
sideEffects: true,
206206
test: regexSassGlobal,
207-
issuer: { include: ctx.customAppFile },
207+
issuer: { and: [ctx.customAppFile] },
208208
use: getGlobalCssLoader(ctx, postCssPlugins, sassPreprocessors),
209209
},
210210
],
@@ -218,7 +218,7 @@ export const css = curry(async function css(
218218
oneOf: [
219219
{
220220
test: [regexCssGlobal, regexSassGlobal].filter(Boolean),
221-
issuer: { include: [/node_modules/] },
221+
issuer: { and: [/node_modules/] },
222222
use: {
223223
loader: 'error-loader',
224224
options: {
@@ -258,7 +258,7 @@ export const css = curry(async function css(
258258
oneOf: [
259259
{
260260
// This should only be applied to CSS files
261-
issuer: { test: regexLikeCss },
261+
issuer: regexLikeCss,
262262
// Exclude extensions that webpack handles by default
263263
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
264264
use: {

packages/next/build/webpack/plugins/next-esm-plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const PRESETS_WITH_USEBUILTINS = /(^|[\\/])(@babel\/(preset-)?react)([\\/]|$)/
5959
// Matches Babel plugin paths that support the useBuiltIns option
6060
const PLUGINS_WITH_USEBUILTINS = /(^|[\\/])(@babel\/(plugin-)?transform-react-jsx)([\\/]|$)/
6161

62-
export default class NextEsmPlugin implements Plugin {
62+
export class NextEsmPlugin implements Plugin {
6363
options: {
6464
filename: any
6565
chunkFilename: any

0 commit comments

Comments
 (0)