From 552aa9df1ae670d9c8ee872880af980d72eebc2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyeon=20Kim=20=28=EA=B9=80=EC=A7=80=ED=98=84=29?= Date: Mon, 11 Jan 2021 21:31:31 +0900 Subject: [PATCH] Prevent unpredictable dependency hosting by explicitly resolve module path on webpack.ProvidePlugin (#20971) ProvidePlugin replaces certain identifiers with another modules. As a result, 'buffer' and 'process' modules are added as implicit dependencies to all Next.js plugins. This can be problematic. With "Plug'n'Play" strategy, it don't work at all since they fail-fast with implicit dependencies. With "node_modules" strategy, it might seem OK but actually it can be result into unpredictable behavior since in uses dependency [hoisting](https://yarnpkg.com/advanced/lexicon#hoisting). For example, currently users cannot use next-auth plugin with Plug'n'Play strategy: ![image](https://user-images.githubusercontent.com/4435445/103481517-d5547700-4e1e-11eb-9f23-bc2c9939418e.png) This patch let Next.js properly handles such cases with `require.resolve`. Closes https://github.com/vercel/next.js/issues/20955 ###### References: - https://github.com/nextauthjs/next-auth/pull/1034 --- packages/next/build/webpack-config.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index ef8c4f06a4e0..6338b80b440c 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -911,14 +911,13 @@ export default async function getBaseWebpackConfig( }, plugins: [ hasReactRefresh && new ReactRefreshWebpackPlugin(), - // Makes sure `Buffer` is polyfilled in client-side bundles (same behavior as webpack 4) + // Makes sure `Buffer` and `process` are polyfilled in client-side bundles (same behavior as webpack 4) isWebpack5 && !isServer && - new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }), - // Makes sure `process` is polyfilled in client-side bundles (same behavior as webpack 4) - isWebpack5 && - !isServer && - new webpack.ProvidePlugin({ process: ['process'] }), + new webpack.ProvidePlugin({ + Buffer: [require.resolve('buffer'), 'Buffer'], + process: [require.resolve('process')], + }), // This plugin makes sure `output.filename` is used for entry chunks !isWebpack5 && new ChunkNamesPlugin(), new webpack.DefinePlugin({