Skip to content

Commit

Permalink
use webpack resolve api to resolve in externals config (#21205)
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jan 17, 2021
1 parent f40a41c commit 9c4d368
Show file tree
Hide file tree
Showing 4 changed files with 745 additions and 311 deletions.
4 changes: 2 additions & 2 deletions errors/invalid-webpack-5-version.md
Expand Up @@ -2,11 +2,11 @@

#### Why This Error Occurred

While leveraging webpack 5 support in Next.js the minimum required version of `v5.11.1` was not met. This version is needed while leveraging webpack 5 support with Next.js as early versions are missing patches that cause unexpected behavior.
While leveraging webpack 5 support in Next.js the minimum required version of `v5.15.0` was not met. This version is needed while leveraging webpack 5 support with Next.js as early versions are missing patches that cause unexpected behavior.

#### Possible Ways to Fix It

Upgrade the version of webpack 5 being used with Next.js to at least `v5.11.1` by updating your resolutions field for `webpack` in your `package.json`.
Upgrade the version of webpack 5 being used with Next.js to at least `v5.15.0` by updating your resolutions field for `webpack` in your `package.json`.

### Useful Links

Expand Down
66 changes: 48 additions & 18 deletions packages/next/build/webpack-config.ts
Expand Up @@ -562,9 +562,13 @@ export default async function getBaseWebpackConfig(
config.conformance
)

function handleExternals(context: any, request: any, callback: any) {
async function handleExternals(
context: string,
request: string,
getResolve: () => (context: string, request: string) => Promise<string>
) {
if (request === 'next') {
return callback(undefined, `commonjs ${request}`)
return `commonjs ${request}`
}

const notExternalModules = [
Expand All @@ -578,7 +582,7 @@ export default async function getBaseWebpackConfig(
]

if (notExternalModules.indexOf(request) !== -1) {
return callback()
return
}

// We need to externalize internal requests for files intended to
Expand All @@ -600,26 +604,28 @@ export default async function getBaseWebpackConfig(
// Absolute requires (require('/foo')) are extremely uncommon, but
// also have no need for customization as they're already resolved.
if (isLocal && !isLikelyNextExternal) {
return callback()
return
}

const resolve = getResolve()

// Resolve the import with the webpack provided context, this
// ensures we're resolving the correct version when multiple
// exist.
let res: string
try {
res = require.resolve(request, { paths: [context] })
res = await resolve(context, request)
} catch (err) {
// If the request cannot be resolved, we need to tell webpack to
// "bundle" it so that webpack shows an error (that it cannot be
// resolved).
return callback()
return
}

// Same as above, if the request cannot be resolved we need to have
// webpack "bundle" it so it surfaces the not found error.
if (!res) {
return callback()
return
}

let isNextExternal: boolean = false
Expand All @@ -631,7 +637,7 @@ export default async function getBaseWebpackConfig(
)

if (!isNextExternal) {
return callback()
return
}
}

Expand All @@ -646,7 +652,7 @@ export default async function getBaseWebpackConfig(
// we need to bundle the code (even if it _should_ be external).
let baseRes: string | null
try {
baseRes = require.resolve(request, { paths: [dir] })
baseRes = await resolve(dir, request)
} catch (err) {
baseRes = null
}
Expand All @@ -660,7 +666,7 @@ export default async function getBaseWebpackConfig(
// if res and baseRes are symlinks they could point to the the same file
realpathSync(baseRes) !== realpathSync(res))
) {
return callback()
return
}
}

Expand All @@ -671,15 +677,15 @@ export default async function getBaseWebpackConfig(
// This is the @babel/plugin-transform-runtime "helpers: true" option
res.match(/node_modules[/\\]@babel[/\\]runtime[/\\]/))
) {
return callback()
return
}

// Webpack itself has to be compiled because it doesn't always use module relative paths
if (
res.match(/node_modules[/\\]webpack/) ||
res.match(/node_modules[/\\]css-loader/)
) {
return callback()
return
}

// Anything else that is standard JavaScript within `node_modules`
Expand All @@ -701,11 +707,10 @@ export default async function getBaseWebpackConfig(
)
: request

return callback(undefined, `commonjs ${externalRequest}`)
return `commonjs ${externalRequest}`
}

// Default behavior: bundle the code!
callback()
}

const emacsLockfilePattern = '**/.#*'
Expand All @@ -719,10 +724,35 @@ export default async function getBaseWebpackConfig(
: !isServerless
? [
isWebpack5
? ({ context, request }, callback) =>
handleExternals(context, request, callback)
: (context, request, callback) =>
handleExternals(context, request, callback),
? ({
context,
request,
getResolve,
}: {
context: string
request: string
getResolve: () => (
context: string,
request: string
) => Promise<string>
}) => handleExternals(context, request, getResolve)
: (
context: string,
request: string,
callback: (err?: Error, result?: string | undefined) => void
) =>
handleExternals(
context,
request,
() => (resolveContext: string, requestToResolve: string) =>
new Promise((resolve) =>
resolve(
require.resolve(requestToResolve, {
paths: [resolveContext],
})
)
)
).then((result) => callback(undefined, result), callback),
]
: [
// When the 'serverless' target is used all node_modules will be compiled into the output bundles
Expand Down
22 changes: 14 additions & 8 deletions packages/next/bundles/yarn.lock
Expand Up @@ -227,14 +227,19 @@ electron-to-chromium@^1.3.634:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz#8d1591eeca6b257d380061a2c04f0b3cc6c9e33b"
integrity sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ==

enhanced-resolve@^5.3.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz#c89b0c34f17f931902ef2913a125d4b825b49b6f"
integrity sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA==
enhanced-resolve@^5.7.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c"
integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"

es-module-lexer@^0.3.26:
version "0.3.26"
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.3.26.tgz#7b507044e97d5b03b01d4392c74ffeb9c177a83b"
integrity sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==

escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
Expand Down Expand Up @@ -505,9 +510,9 @@ watchpack@^2.0.0:
source-map "^0.6.1"

"webpack5@npm:webpack@5":
version "5.12.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.12.3.tgz#2682aeb6bdf5622a365ef855392f8fa338bcaa28"
integrity sha512-7tiQmcTnKhZwbf7X7sEfXe0pgkGjUZjT6JfYkZHvvIb4/ZsXl1rJu5PxsJoN7W3v5sNSP/8TgBoiOdDqVdvK5w==
version "5.15.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.15.0.tgz#63d7b6228a4e15ee8c89899c2cfdd993e809bdd2"
integrity sha512-y/xG+ONDz78yn3VvP6gAvGr1/gkxOgitvHSXBmquyN8KDtrGEyE3K9WkXOPB7QmfcOBCpO4ELXwNcCYQnEmexA==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.45"
Expand All @@ -517,7 +522,8 @@ watchpack@^2.0.0:
acorn "^8.0.4"
browserslist "^4.14.5"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.3.1"
enhanced-resolve "^5.7.0"
es-module-lexer "^0.3.26"
eslint-scope "^5.1.1"
events "^3.2.0"
glob-to-regexp "^0.4.1"
Expand Down
964 changes: 681 additions & 283 deletions packages/next/compiled/webpack/bundle5.js

Large diffs are not rendered by default.

0 comments on commit 9c4d368

Please sign in to comment.