next.js icon indicating copy to clipboard operation
next.js copied to clipboard

On demand ISR works fine in local machine but fails when deployed to iisnode running in azure windows webaps

Open chethanbr25 opened this issue 2 years ago • 2 comments

Verify canary release

  • [X] I verified that the issue exists in Next.js canary release

Provide environment information

Operating System: Platform: win32 Arch: x64 Version: Windows 10 Enterprise Binaries: Node: 16.13.1 npm: N/A Yarn: N/A pnpm: N/A Relevant packages: next: 12.1.7-canary.23 react: 17.0.2 react-dom: 17.0.2

What browser are you using? (if relevant)

chrome

How are you deploying your application? (if relevant)

next start

Describe the Bug

On demand ISR works on Local machine . But when deployed to windows webapp iisnode revalidate fails with Error revalidating

Expected Behavior

Revalidate should work fine

To Reproduce

// pages/api/revalidate.js export default async function handler(req, res) { // Check for secret to confirm this is a valid request if (req.query.secret !== process.env.MY_SECRET_TOKEN) { return res.status(401).json({ message: "Invalid token" }) }

try {
    await res.unstable_revalidate("/en-us/gentiane-valiquette")
    return res.json({ revalidated: true })
} catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send("Error revalidating")
}

}

//package.json

"scripts": { "start": "node server.js", "dev": "next dev", "build": "next build", "postbuild": "node -e "require('./config/generators').generateSSRWebConfig()"", "export": "npm run check-quality && next build && next export", "postexport": "babel-node -e 'require("./config/generators").generateSitemap()' && babel-node -e 'require("./config/generators").generateSSGWebConfig()'", "preview": "npm --production=false install && next build", "setup-preview": "npm --production=false install && next build", "dev:debug": "cross-env NODE_OPTIONS='--inspect' next dev", "lint": "npm run lint:js && npm run lint:styles && next lint", "lint:fix": "npm run lint:js-fix && npm run lint:styles-fix && next lint", "lint:js": "eslint "./src/pages/.js" "./src/components/**/.js" "./src/adapters//.js"", "lint:js-fix": "eslint "./src/pages/.js" "./src/components//.js" "./src/adapters/**/.js" "./src/store/.js" --fix", "lint:styles": "stylelint "src/components/**/.styles.js" "src/styles//*.css"", "lint:styles-fix": "stylelint "src/components//.styles.js" "src/styles/**/.css" --fix", "eslint-report": "eslint --ext .jsx,.js "./src/components/**" -o report.json -f json",

Server.js
--------------------
// server.js

const { createServer } = require('http') const { parse } = require('url') const next = require('next')

const dev = process.env.NODE_ENV !== 'production' const hostname = 'localhost' const port = process.env.PORT || "3000" // when using middleware hostname and port must be provided below const app = next({ dev, hostname, port }) const handle = app.getRequestHandler()

app.prepare().then(() => { createServer(async (req, res) => { try { // Be sure to pass true as the second argument to url.parse. // This tells it to parse the query portion of the URL. const parsedUrl = parse(req.url, true) const { pathname, query } = parsedUrl

  if (pathname === '/a') {
    await app.render(req, res, '/a', query)
  } else if (pathname === '/b') {
    await app.render(req, res, '/b', query)
  } else {
    await handle(req, res, parsedUrl)
  }
} catch (err) {
  console.error('Error occurred handling', req.url, err)
  res.statusCode = 500
  res.end('internal server error')
}

}).listen(port, (err) => { if (err) throw err console.log(> Ready on http://${hostname}:${port}) }) })

chethanbr25 avatar May 30 '22 13:05 chethanbr25

Hi all,

I've experienced this same issue -- and have also identified a cause, and implemented a temporary patch (which I'm hopeful I won't have to rely on for too long!)

First, the bug appears if you are running Next:

  1. using a Windows virtual folder that is
  2. mounted to a network fileshare.

So to reproduce:

  1. PS> npx create-next-app@latest testapp
  2. Share the testapp folder
  3. PS> New-PSDrive -Name K -PSProvider FileSystem -Root "\\[computerName | IP]\testapp" -Persist
  4. PS> cd K:
  5. PS> npm run build

You'll get this:

> [email protected] build
> next build

info  - Checking validity of types
info  - Creating an optimized production build
Failed to compile.

K:\node_modules\next\dist\build\webpack\loaders\next-client-pages-loader.js?absolutePagePath=private-next-pages%2F_app.js&page=%2F_app!
Module not found: Can't resolve 'private-next-pages/_app.js' in '\\[computerName | IP]\testappt'

K:\node_modules\next\dist\build\webpack\loaders\next-client-pages-loader.js?absolutePagePath=private-next-pages%2Findex.js&page=%2F!
Module not found: Can't resolve 'private-next-pages/index.js' in '\\[computerName/IP]\testapp'

Module not found: Error: Can't resolve './K:/node_modules/next/dist/client/next.js' in '\\[computerName | IP]\testapp'


> webpack config.resolve.alias was incorrectly overridden. https://nextjs.org/docs/messages/invalid-resolve-alias

You can get all kinds of messy additional error messages by running in dev and/or actually installing some additional modules. The key bit of info is already in the simpler messages above, though: Webpack is using a UNC path to look for these files. We never gave it a UNC path; that UNC path should be hidden behind the abstraction of the virtual folder, and yet here it is. And Webpack doesn't seem to like UNC paths, for whatever reason. As a result, the app breaks.

The reason this is happening appears to be the use of the fs.realpathSync.native function in next/lib/get-project-dir.ts:

    const resolvedDir = path.resolve(dir || '.')
    const realDir = fs.realpathSync.native(resolvedDir)

Though I only had limited time to research the difference between realpathSync and realpathSync.native, it looks like the latter is supposed to work better with Windows paths (though I'm not sure in what way). Unfortunately, this case, it exposes the underlying UNC origin of the virtual directory. For instance, assuming your context is the root of the testApp example above, running with a working directory of K:, here's what you get:

input fs.realpathSync fs.realpathSync.native
path.resolve('.') K:\ \[computerName or IP]\testApp

So my temporary patch is just adding to my pipeline a step to modify /node_modules/next/dist/lib/get-project-dir.js such that the above line uses fs.realpathSync instead of fs.realpathSync.native. That allows builds to work properly, including enabling ISR.

I'm sure realpathSync.native was chosen for a reason, so I'm not sure that swapping to realpathSync is a workable permanent fix, but perhaps at the very least it could be used in cases where the underlying path exposed by realpathSync.native is a UNC path, so that whatever the downsides of using realpathSync are would at least be limited only to virtual directory scenarios.

timfitzzz avatar Jun 27 '22 16:06 timfitzzz

Turns out this bug was documented earlier as well here:

https://github.com/vercel/next.js/issues/36707

There hasn't been any action on this ticket, so I may recreate it with my above comment, since it provides more complete diagnostic info than the initial issue contains. I may also submit a PR, although because of the compatibility issues and the fundamental nature of the code involved, I'd rather assist somebody with more experience than propose a fix myself. But I'd rather not have to keep monkeypatching my deployment, and I don't really want to have to maintain a separate branch just for this tiny subtractive fix. :)

timfitzzz avatar Aug 08 '22 03:08 timfitzzz

@timfitzzz This issue is also related to: https://github.com/vercel/next.js/issues/35542. At least the same part of the code is causing both of these problems. For more context, the issue was introduced in https://github.com/vercel/next.js/pull/29205. No idea how to fix it properly though, so I've been patching it in my own deployments too.

mschaul avatar Aug 14 '22 17:08 mschaul

Hi All,

Patching might not be right solution for production. So is there any latest fix available for this issue ?

chethanbr25 avatar Jan 02 '23 06:01 chethanbr25

any updates on this issue?

yl-flyer avatar Feb 17 '23 09:02 yl-flyer