是否可以不重建整个应用程序,而只在Nextjs中生成新的静态文件



我刚刚开始使用NextJsgetStaticProps,在build time生成的静态文件是neat。但我的内容并没有保持不变,我需要更新静态文件,但每次修改都要重新构建应用程序,成本很高。有没有办法只生成新的静态文件。getServerSideProps在第一个字节之前花费了大量时间。

根据您的内容类型,增量静态再生可能是一个很好的解决方案。但根据我的经验,它在呈现目录/类别页面时引入了其他问题。由于nextjs不知道你的数据的一部分是否依赖于另一部分,它可能会呈现一个旧的目录页面,其中包含一个指向已不存在的帖子或产品的链接。这通常与动态路由的"回退"功能结合使用。

它也不会在你做出更改后立即刷新你的页面,所以你只有在一段时间后才能看到结果。

可能的解决方法是通过ajax在类别页面上动态加载帖子/产品。你会失去一部分用户体验和SEO,但另一方面,这个解决方案相对容易维护。

还有一个选项,或者更确切地说,通过直接访问自定义服务器中的缓存来重建部分保存的内容。将"清除=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上不起作用,并且在缩放方面存在一些问题。您还应该添加某种安全令牌来清除路由。

如果我理解正确,您正在寻找增量统计再生

要启用它,您需要在getStaticProps中添加一个revalidate时间。当您的内容发生更改并且达到重新验证时间后,将生成一个新的静态页面并由服务器提供服务。根据内容更改的频率,您可以相应地更改重新验证时间。

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-静态再生

最新更新