如何解决是否可以不重建整个应用程序而仅在 Nextjs 中生成新的静态文件?
我刚刚开始使用 NextJs getStaticProps
,在 build time
生成的静态文件整洁。但我的内容不会保持不变,我需要更新静态文件,但每次修改时重建应用程序的成本很高。有没有办法只生成新的静态文件。 getServerSideProps
原来花费了大量时间直到第一个字节。
解决方法
如果我理解正确,您正在寻找增量静态再生。
要启用它,您需要在 revalidate
中添加 getStaticProps
时间。当您的内容发生更改并达到重新验证时间后,将生成一个新的静态页面并由服务器提供服务。根据您的内容更改频率,您可以相应地更改重新验证时间。
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,},// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10,// In seconds
}
}
参考
https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration
,根据您的内容类型 Incremental Statatic Regeneration 可能是一个很好的解决方案。但根据我的经验,它在呈现目录/类别页面时引入了其他问题。由于 nextjs 不知道您的数据的一部分是否依赖于其他数据,因此它可能会呈现旧的目录页面,其中包含指向不再存在的帖子或产品的链接。这通常与动态路由的“回退”功能结合使用。
它也不会在您进行更改后立即刷新您的页面,因此您只能在一段时间后看到结果。
可能的解决方法是通过 ajax 动态加载类别页面上的帖子/产品。您将失去一部分 UX 和 SEO,但另一方面,此解决方案相对易于维护。
还有一个选项,或者更确切地说,通过直接访问自定义服务器中的缓存来重建部分保存的内容。将“purge=1”添加到您要刷新的页面地址。
const { ServerResponse,createServer } = require('http')
const next = require('next')
const { promises } = require('fs')
const path = require('path')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const purgeByPath = async url => {
const pathname = url == '/' ? '/index' : url
const fullPathname = `.next/server/pages${pathname}`
const fullPathHTML = `${fullPathname}.html`
const fullPathJSON = `${fullPathname}.json`
try {
await promises.unlink(fullPathHTML)
await promises.unlink(fullPathJSON)
} catch (err) {
console.log(`Could not unlink cache files: ${err}`)
}
await app.incrementalCache.cache.del(pathname)
let req = new Request(process.env.BASE_HOST + url)
let res = new ServerResponse(req)
await app.renderToHTML(req,res,url,{ _nextDataReq: true })
}
app.prepare().then(() => {
createServer(async (req,res) => {
const url = new URL(req.url,"http://localhost:3000/")
if (req.method == 'POST' && req.url == '/purge-cache') {
let raw = ''
req.on('data',chunk => raw += chunk)
req.on('end',async () => {
const data = JSON.parse(raw)
if (!data || !data.urls) {
res.statusCode = 400
res.end()
return
}
for (let url of data.urls) {
console.log(`Cleaning cache on: ${url}`)
await purgeByPath(url)
}
res.end()
})
} else if (url.searchParams.get('purge') == '1') {
await purgeByPath(req.url)
res.end()
} else {
handle(req,res)
}
}).listen(3000,(err) => {
if (err) throw err
console.log(`> Ready on http://localhost:3000/`)
})
})
静态缓存由两部分组成:
- 位于
.next/server/pages
的静态缓存文件,其中每个路由可能有两个文件 html 和 json。您很可能需要同时删除两者。 - 内存缓存。一旦您的应用程序缓存了一个页面并将其保存到内存中,它就不会转到硬盘驱动器上的文件,而是从内存中加载内容。所以你也需要删除它。
未记录缓存实现,可能会在未来版本中交换或删除。
这不适用于 vercel,并且在缩放方面存在一些问题。您还应该添加某种安全令牌来清除路由。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。