Skip to content

Commit

Permalink
fix(nextjs): Fix resolution of request async storage module
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed Oct 16, 2023
1 parent c9aaf8b commit 6b0e33f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 28 deletions.
2 changes: 2 additions & 0 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@
"@sentry/vercel-edge": "7.74.0",
"@sentry/webpack-plugin": "1.20.0",
"chalk": "3.0.0",
"resolve": "1.22.8",
"rollup": "2.78.0",
"stacktrace-parser": "^0.1.10",
"tslib": "^2.4.1 || ^1.9.3"
},
"devDependencies": {
"@types/resolve": "1.20.3",
"@types/webpack": "^4.41.31",
"eslint-plugin-react": "^7.31.11",
"next": "10.1.3"
Expand Down
66 changes: 39 additions & 27 deletions packages/nextjs/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type SentryCliPlugin from '@sentry/webpack-plugin';
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as path from 'path';
import { sync as resolveSync } from 'resolve';

import type { VercelCronsConfig } from '../common/types';
// Note: If you need to import a type from Webpack, do it in `types.ts` and export it from there. Otherwise, our
Expand Down Expand Up @@ -126,7 +127,10 @@ export function constructWebpackConfigFunction(
pageExtensionRegex,
excludeServerRoutes: userSentryOptions.excludeServerRoutes,
sentryConfigFilePath: getUserConfigFilePath(projectDir, runtime),
nextjsRequestAsyncStorageModulePath: getRequestAsyncStorageModuleLocation(rawNewConfig.resolve?.modules),
nextjsRequestAsyncStorageModulePath: getRequestAsyncStorageModuleLocation(
projectDir,
rawNewConfig.resolve?.modules,
),
};

const normalizeLoaderResourcePath = (resourcePath: string): string => {
Expand Down Expand Up @@ -977,39 +981,47 @@ function addValueInjectionLoader(
);
}

function resolveNextPackageDirFromDirectory(basedir: string): string | undefined {
try {
return path.dirname(resolveSync('next/package.json', { basedir }));
} catch {
// Should not happen in theory
return undefined;
}
}

const POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS = [
// Original location of RequestAsyncStorage
// https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts
'next/dist/client/components/request-async-storage.js',
// Introduced in Next.js 13.4.20
// https://github.com/vercel/next.js/blob/e1bc270830f2fc2df3542d4ef4c61b916c802df3/packages/next/src/client/components/request-async-storage.external.ts
'next/dist/client/components/request-async-storage.external.js',
];

function getRequestAsyncStorageModuleLocation(
webpackContextDir: string,
webpackResolvableModuleLocations: string[] | undefined,
): string | undefined {
if (webpackResolvableModuleLocations === undefined) {
return undefined;
}

const absoluteWebpackResolvableModuleLocations = webpackResolvableModuleLocations.map(m => path.resolve(m));
const moduleIsWebpackResolvable = (moduleId: string): boolean => {
let requireResolveLocation: string;
try {
// This will throw if the location is not resolvable at all.
// We provide a `paths` filter in order to maximally limit the potential locations to the locations webpack would check.
requireResolveLocation = require.resolve(moduleId, { paths: webpackResolvableModuleLocations });
} catch {
return false;
}

// Since the require.resolve approach still looks in "global" node_modules locations like for example "/user/lib/node"
// we further need to filter by locations that start with the locations that webpack would check for.
return absoluteWebpackResolvableModuleLocations.some(resolvableModuleLocation =>
requireResolveLocation.startsWith(resolvableModuleLocation),
);
};
const absoluteWebpackResolvableModuleLocations = webpackResolvableModuleLocations.map(loc =>
path.resolve(webpackContextDir, loc),
);

const potentialRequestAsyncStorageLocations = [
// Original location of RequestAsyncStorage
// https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts
'next/dist/client/components/request-async-storage',
// Introduced in Next.js 13.4.20
// https://github.com/vercel/next.js/blob/e1bc270830f2fc2df3542d4ef4c61b916c802df3/packages/next/src/client/components/request-async-storage.external.ts
'next/dist/client/components/request-async-storage.external',
];
for (const webpackResolvableLocations of absoluteWebpackResolvableModuleLocations) {
const nextPackageDir = resolveNextPackageDirFromDirectory(webpackResolvableLocations);
if (nextPackageDir) {
const asyncLocalStorageLocation = POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS.find(loc =>
fs.existsSync(path.join(nextPackageDir, '..', loc)),
);
if (asyncLocalStorageLocation) {
return asyncLocalStorageLocation;
}
}
}

return potentialRequestAsyncStorageLocations.find(potentialLocation => moduleIsWebpackResolvable(potentialLocation));
return undefined;
}
11 changes: 10 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6206,7 +6206,7 @@
dependencies:
"@types/node" "*"

"@types/resolve@^1.17.0":
"@types/resolve@1.20.3", "@types/resolve@^1.17.0":
version "1.20.3"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.3.tgz#066742d69a0bbba8c5d7d517f82e1140ddeb3c3c"
integrity sha512-NH5oErHOtHZYcjCtg69t26aXEk4BN2zLWqf7wnDZ+dpe0iR7Rds1SPGEItl3fca21oOe0n3OCnZ4W7jBxu7FOw==
Expand Down Expand Up @@ -26364,6 +26364,15 @@ resolve@1.20.0:
is-core-module "^2.2.0"
path-parse "^1.0.6"

resolve@1.22.8:
version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"

resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
Expand Down

0 comments on commit 6b0e33f

Please sign in to comment.