Skip to content

fix: try to resolve next modules via multiple paths #479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 5, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { overrides } = require('@netlify/eslint-config-node/react_config')
module.exports = {
extends: '@netlify/eslint-config-node/react_config',
rules: {
'max-depth': 0,
complexity: 0,
'fp/no-let': 0,
'fp/no-loops': 0,
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ jobs:
node-version: ${{ matrix.node-version }}
check-latest: true
- run: npm ci
name: NPM Install
- name: Linting
run: npm run format:ci
if: "${{ matrix.node-version == '*' }}"
- run: npm test
- name: Run tests against next@latest
run: npm test
- name: Install Next.js Canary
run: npm install -D next@canary --legacy-peer-deps
- name: Run tests against next@canary
run: npm test
5 changes: 4 additions & 1 deletion helpers/getNextConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const getNextConfig = async function (failBuild = defaultFailBuild, cwd = getCwd
// site is using `next` inside `onPreBuild`.
/* eslint-disable import/no-dynamic-require */
const { PHASE_PRODUCTION_BUILD } = require(resolveNextModule('next/constants', cwd))
const loadConfig = require(resolveNextModule('next/dist/next-server/server/config', cwd)).default
const loadConfig = require(resolveNextModule(
['next/dist/next-server/server/config', 'next/dist/server/config'],
cwd,
)).default

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE

/* eslint-enable import/no-dynamic-require */

try {
Expand Down
32 changes: 25 additions & 7 deletions helpers/resolveNextModule.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
/**
* Try one or more Next.js imports until one is found.
* We can't require() these normally, because the "next" package might not be resolvable from the root of a monorepo
*/
const resolveNextModule = (module, nextRoot) => {
// Get the default list of require paths...
const paths = require.resolve.paths(module)
// ...add the root of the Next site to the beginning of that list so we try it first...
paths.unshift(nextRoot)
// ...then resolve the module using that list of paths.
return require.resolve(module, { paths })
const resolveNextModule = (modules, nextRoot) => {
if (!Array.isArray(modules)) {
// eslint-disable-next-line no-param-reassign
modules = [modules]
}
for (const key in modules) {
const module = modules[key]
// Get the default list of require paths...
const paths = require.resolve.paths(module)
// ...add the root of the Next site to the beginning of that list so we try it first...
paths.unshift(nextRoot)
// ...then resolve the module using that list of paths.
try {
const resolved = require.resolve(module, { paths })
if (resolved) {
console.log('resolved', resolved)
return resolved
}
} catch (error) {
// Failed. Trying next.
}
}

throw new Error(`Could not resolve Next module. Tried "${modules.join(', ')}"`)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ez


module.exports = resolveNextModule
2 changes: 1 addition & 1 deletion helpers/verifyBuildTarget.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const verifyBuildTarget = async ({ failBuild, netlifyConfig }) => {
// https://github.com/vercel/next.js/blob/canary/packages/next/telemetry/ci-info.ts

delete require.cache[resolveNextModule('next/dist/telemetry/ci-info', nextRoot)]
delete require.cache[resolveNextModule('next/dist/next-server/server/config', nextRoot)]
delete require.cache[resolveNextModule(['next/dist/next-server/server/config', 'next/dist/server/config'], nextRoot)]

// Clear memoized cache
getNextConfig.clear()
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"prepublishOnly:test": "npm test",
"test:plugin": "npm run build && jest",
"test:src": "jest --config src/tests/jest.config.js",
"test": "npm run test:plugin && npm run test:src"
"test": "run-s test:plugin test:src"
},
"config": {
"eslint": "--cache --format=codeframe --max-warnings=0 \"{src,scripts,tests,.github}/**/*.{js,md,html}\" \"*.{js,md,html}\" \".*.{js,md,html}\"",
Expand Down
2 changes: 1 addition & 1 deletion src/lib/helpers/getSortedRedirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const getSortedRedirects = (redirects) => {
// Sort the "naked" routes
// eslint-disable-next-line import/no-dynamic-require
const { getSortedRoutes } = require(resolveNextModule(
'next/dist/next-server/lib/router/utils/sorted-routes',
['next/dist/next-server/lib/router/utils/sorted-routes', 'next/dist/shared/lib/router/utils/sorted-routes'],
process.cwd(),
))
const sortedRoutes = getSortedRoutes(routesWithoutExtensions)
Expand Down
7 changes: 5 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const { dir: getTmpDir } = require('tmp-promise')

const plugin = require('..')
const getNextConfig = require('../helpers/getNextConfig')
const resolveNextModule = require('../helpers/resolveNextModule')

const FIXTURES_DIR = `${__dirname}/fixtures`
const SAMPLE_PROJECT_DIR = `${__dirname}/sample`
Expand Down Expand Up @@ -53,8 +54,10 @@ const useFixture = async function (fixtureName) {
// This allows us not to have to mock filesystem operations.
beforeEach(async () => {
delete process.env.NEXT_PRIVATE_TARGET
delete require.cache[require.resolve('next/dist/telemetry/ci-info')]
delete require.cache[require.resolve('next/dist/next-server/server/config')]
delete require.cache[resolveNextModule('next/dist/telemetry/ci-info', process.cwd())]
delete require.cache[
resolveNextModule(['next/dist/next-server/server/config', 'next/dist/server/config'], process.cwd())
]

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