Skip to content

Commit 7d208c3

Browse files
authored
fix: try to resolve next modules via multiple paths (#479)
* fix: resolve modules as array * chore: test against canary * fix: add paths for next canary * fix: use resolveNextModule in tests * fix: set default next path in tests * fix: use legacy peer deps in ci test * fix: add comments
1 parent c3373d5 commit 7d208c3

File tree

8 files changed

+73
-14
lines changed

8 files changed

+73
-14
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { overrides } = require('@netlify/eslint-config-node/react_config')
33
module.exports = {
44
extends: '@netlify/eslint-config-node/react_config',
55
rules: {
6+
'max-depth': 0,
67
complexity: 0,
78
'fp/no-let': 0,
89
'fp/no-loops': 0,

.github/workflows/test.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ jobs:
2828
node-version: ${{ matrix.node-version }}
2929
check-latest: true
3030
- run: npm ci
31+
name: NPM Install
3132
- name: Linting
3233
run: npm run format:ci
3334
if: "${{ matrix.node-version == '*' }}"
34-
- run: npm test
35+
- name: Run tests against next@latest
36+
run: npm test
37+
- name: Install Next.js Canary
38+
run: npm install -D next@canary --legacy-peer-deps
39+
- name: Run tests against next@canary
40+
run: npm test

helpers/getNextConfig.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ const getNextConfig = async function (failBuild = defaultFailBuild, cwd = getCwd
1313
// site is using `next` inside `onPreBuild`.
1414
/* eslint-disable import/no-dynamic-require */
1515
const { PHASE_PRODUCTION_BUILD } = require(resolveNextModule('next/constants', cwd))
16-
const loadConfig = require(resolveNextModule('next/dist/next-server/server/config', cwd)).default
16+
const loadConfig = require(resolveNextModule(
17+
[
18+
// next <= 11.0.1
19+
'next/dist/next-server/server/config',
20+
// next > 11.0.1
21+
'next/dist/server/config',
22+
],
23+
cwd,
24+
)).default
1725
/* eslint-enable import/no-dynamic-require */
1826

1927
try {

helpers/resolveNextModule.js

+25-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
/**
2+
* Try one or more Next.js imports until one is found.
23
* We can't require() these normally, because the "next" package might not be resolvable from the root of a monorepo
34
*/
4-
const resolveNextModule = (module, nextRoot) => {
5-
// Get the default list of require paths...
6-
const paths = require.resolve.paths(module)
7-
// ...add the root of the Next site to the beginning of that list so we try it first...
8-
paths.unshift(nextRoot)
9-
// ...then resolve the module using that list of paths.
10-
return require.resolve(module, { paths })
5+
const resolveNextModule = (modules, nextRoot) => {
6+
if (!Array.isArray(modules)) {
7+
// eslint-disable-next-line no-param-reassign
8+
modules = [modules]
9+
}
10+
for (const key in modules) {
11+
const module = modules[key]
12+
// Get the default list of require paths...
13+
const paths = require.resolve.paths(module)
14+
// ...add the root of the Next site to the beginning of that list so we try it first...
15+
paths.unshift(nextRoot)
16+
// ...then resolve the module using that list of paths.
17+
try {
18+
const resolved = require.resolve(module, { paths })
19+
if (resolved) {
20+
console.log('resolved', resolved)
21+
return resolved
22+
}
23+
} catch (error) {
24+
// Failed. Trying next.
25+
}
26+
}
27+
28+
throw new Error(`Could not resolve Next module. Tried "${modules.join(', ')}"`)
1129
}
1230

1331
module.exports = resolveNextModule

helpers/verifyBuildTarget.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,17 @@ const verifyBuildTarget = async ({ failBuild, netlifyConfig }) => {
3434
// https://github.com/vercel/next.js/blob/canary/packages/next/telemetry/ci-info.ts
3535

3636
delete require.cache[resolveNextModule('next/dist/telemetry/ci-info', nextRoot)]
37-
delete require.cache[resolveNextModule('next/dist/next-server/server/config', nextRoot)]
37+
delete require.cache[
38+
resolveNextModule(
39+
[
40+
// next <= 11.0.1
41+
'next/dist/next-server/server/config',
42+
// next > 11.0.1
43+
'next/dist/server/config',
44+
],
45+
nextRoot,
46+
)
47+
]
3848

3949
// Clear memoized cache
4050
getNextConfig.clear()

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"prepublishOnly:test": "npm test",
3737
"test:plugin": "npm run build && jest",
3838
"test:src": "jest --config src/tests/jest.config.js",
39-
"test": "npm run test:plugin && npm run test:src"
39+
"test": "run-s test:plugin test:src"
4040
},
4141
"config": {
4242
"eslint": "--cache --format=codeframe --max-warnings=0 \"{src,scripts,tests,.github}/**/*.{js,md,html}\" \"*.{js,md,html}\" \".*.{js,md,html}\"",

src/lib/helpers/getSortedRedirects.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ const getSortedRedirects = (redirects) => {
1313
// Sort the "naked" routes
1414
// eslint-disable-next-line import/no-dynamic-require
1515
const { getSortedRoutes } = require(resolveNextModule(
16-
'next/dist/next-server/lib/router/utils/sorted-routes',
16+
[
17+
// next <= 11.0.1
18+
'next/dist/next-server/lib/router/utils/sorted-routes',
19+
// next > 11.0.1
20+
'next/dist/shared/lib/router/utils/sorted-routes',
21+
],
1722
process.cwd(),
1823
))
1924
const sortedRoutes = getSortedRoutes(routesWithoutExtensions)

test/index.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { dir: getTmpDir } = require('tmp-promise')
77

88
const plugin = require('..')
99
const getNextConfig = require('../helpers/getNextConfig')
10+
const resolveNextModule = require('../helpers/resolveNextModule')
1011

1112
const FIXTURES_DIR = `${__dirname}/fixtures`
1213
const SAMPLE_PROJECT_DIR = `${__dirname}/sample`
@@ -53,8 +54,18 @@ const useFixture = async function (fixtureName) {
5354
// This allows us not to have to mock filesystem operations.
5455
beforeEach(async () => {
5556
delete process.env.NEXT_PRIVATE_TARGET
56-
delete require.cache[require.resolve('next/dist/telemetry/ci-info')]
57-
delete require.cache[require.resolve('next/dist/next-server/server/config')]
57+
delete require.cache[resolveNextModule('next/dist/telemetry/ci-info', process.cwd())]
58+
delete require.cache[
59+
resolveNextModule(
60+
[
61+
// next <= 11.0.1
62+
'next/dist/next-server/server/config',
63+
// next > 11.0.1
64+
'next/dist/server/config',
65+
],
66+
process.cwd(),
67+
)
68+
]
5869

5970
getNextConfig.clear()
6071
const { path, cleanup } = await getTmpDir({ unsafeCleanup: true })

0 commit comments

Comments
 (0)