【发布时间】:2022-01-23 13:31:45
【问题描述】:
我有一个 Next.js 应用程序,其中包含一个使用 lowDb 的非常简单的数据库。想法是让一个模块具有简单的get 和set 函数,并且在模块内部,将 db 设置为顶级常量:
const dbAdapter = new JSONFile(dbFile)
const db = new Low(dbAdapter)
let randomId = generateRandomId()
console.log(`DB: Using database in ${dbFile}, instance ${randomId}`)
/// A promise we call at the beginning of get and set functions to ensure db is initialized
let initPromise = new Promise<undefined>(async function(resolve, reject){
console.log(`DB: init, reading database ...`)
// Read data from JSON file, this will set db.data content
await db.read()
// If file.json doesn't exist, db.data will be null
// Set default data, node >= 15.x
db.data ||= {
tracks: {},
}
resolve(undefined)
})
export async function getTracks() {
await initPromise
return db.data['tracks']
}
...
然后在多个路由的getServerSideProps 函数内部调用getTracks(),以向SSR 和客户端呈现的页面提供实际数据。
问题似乎是当我在多个页面中使用数据库时,Next.js 会多次实例化这个模块,导致每个页面都有自己独立的数据库(所以无论保存一个页面,另一个页面都没有看,因为每个实例都有自己的内存缓存,并且不会在每次读取时重新读取 db 文件。
这是日志显示的内容:
wait - compiling / (client and server)...
event - compiled client and server successfully in 100 ms (387 modules)
DB: Using database in tracks.json, instance tpzoj
DB: init, reading database ...
然后我导航到另一个页面,这发生了 - 为另一个页面的包再次构建了一个模块,并创建了另一个 db 实例:
wait - compiling /edit (client and server)...
event - compiled client and server successfully in 115 ms (394 modules)
DB: Using database in tracks.json, instance gjndv
DB: init, reading database ...
有没有办法强制 Next.js 只构建某个模块一次(而不是将其单独捆绑到每个页面中)?
【问题讨论】: