针对 Nuxt3 的不同环境使用不同的 Dexie Cloud 配置

问题描述 投票:0回答:1

我正在使用 Nuxt3 和 Dexie Cloud 编写一个应用程序,并使用 PM2 部署到我的 LAN 上的开发 Ubuntu 网络服务器。一切都很好,直到我决定添加另一个部署(我将其视为“生产”)来模仿最终用户的设置。我无法只删除其中的数据库和表,因此我准备在单独的数据库上运行它。

我计划将实例化中的数据库名称更改为变量(

new Dexie(bdVar)
),并且
db.cloud.configure
中的url也相同。

这就是事情爆发的地方......原因......我从哪里获得这些变量的值?

.env
并不像我想象的那样工作(节点、运行时等)。 Nuxt 的
runtimceConfig
...好吧,我仍在努力解决这个问题。

让我概述一下我所拥有的:

// db/index.js
import { Dexie } from 'dexie'
import { dexieCloud } from 'dexie-cloud-addon'

export const db = new Dexie(dexieDb***, {addons: [dexieCloud]})

db.version(1).stores({
  // table definitions
})

db.cloud.configure({
  databaseUrl: dexieDbUrl***,
  requireAuth: true
})
*** means it works fine when string provided

然后我还有一些其他数据库文件,每个文件都有相关的查询/事务

// db/items.dexie.js
import { db } from '~/db/index.js'

export const fetchItems = async (realmId) => {
  const result = await db.items.where('realmId').equals(realmId).sortBy('last_update')
  return result
}
...

然后我有我的 Pinia 商店,物品商店,缩短了,例如

// stores/items.js 
import { fetchItems } from '~/db/items.dexie.js'

export const useItemStore = defineStore('items', () => {
  let items = ref([])

  const getItems = async () => {
    if (items.value.length === 0) items.value = await fetchItems(currentSpace.value.realmId)
    return items
  }

  ...

  return {
    items,
    getItems,
    ...
  }
})

一个简单的页面示例:

// pages/items.vue
<script setup>
const { items } = storeToRefs(useItemStore())

onMounted(async () => {
  if (items.value.length < 1) items.value = await useItemStore().getItems()
})
</script>

<template>
  <div v-for="item in items" :key="item.id">
    {{ item.name }}
  </div>
</template>

我尝试在 nuxt.conf.ts 中添加runtimeConfig:

export default defineNuxtConfig({
  runtimeConfig: {
    dexieDb: '', // .env entry: NUXT_DEXIE_DB
    dexieDbUrl: '', // .env entry: NUXT_DEXIE_DB_URL
  },
})

下一个逻辑步骤(当然是在我的脑海中)是现在访问 db/index.js 中的runtimeConfig:

// db/index.js
import ...

const runtime = useRuntimeConfig()

export const db = new Dexie(runtime.dexieDb, {addons: [dexieCloud]})
...

500 错误确实清楚地说明了这是行不通的:

A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function.

这就是我目前陷入困境的地方。如何使 Dexie 数据库可用,同时使用根据环境而具有不同值的变量,同时使用“插件、Nuxt 钩子、Nuxt 中间件或 Vue 设置函数”?

注意:我需要作为变量获得的一些信息是敏感的。

pm2 nuxt3 dexie
1个回答
0
投票

我带着这个问题上床睡觉。醒来时有一个“解决方案”。尽管可能有更优雅的方法,但这就是我想出的:

首先,我将

db/index.js
移至插件中

// plugins/dexie.js
import { Dexie } from 'dexie'
import { dexieCloud } from 'dexie-cloud-addon'

export default defineNuxtPlugin(nuxtApp => {
  const runtimeConfig = useRuntimeConfig()
  
  const db = new Dexie(runtimeConfig.public.dexieDb, {addons: [dexieCloud]})

  db.version(1).stores({
    // table definitions
  })

  db.cloud.configure({
    databaseUrl: runtimeConfig.public.dexieDbUrl,
    requireAuth: true
  })

  nuxtApp.db = db
})

将变量移至

public runtimeConfig

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      dexieDb: '', // env var NUXT_PUBLIC_DEXIE_DB
      dexieDbUrl: '', // env var NUXT_PUBLIC_DEXIE_DB_URL
    },
  },
  ...
})

然后我更改了数据库方法以期望对数据库的引用

// db/items.dexie.js
export const fetchItems = async (db, realmId) => {
  return await db.items.where('realmId').equals(realmId).sortBy('last_update')
}
...

在商店中,我从 NuxtApp 获取数据库,并将其传递

// stores/items.js 
import { fetchItems } from '~/db/items.dexie.js'

export const useItemStore = defineStore('items', () => {
  const { db } = useNuxtApp()

  let items = ref([])

  const getItems = async () => {
    if (items.value.length === 0) items.value = await fetchItems(db, currentSpace.value.realmId)
    return items
  }

  ...

  return {
    items,
    getItems,
    ...
  }
})

这在开发中效果很好!它使用项目根目录中的

.env

对于“生产”,我需要更新

ecosystem.config.cjs
,添加环境变量(我正在使用PM2

module.exports = {
  apps: [{
      name: 'InstanceName',
      port: '3005',
      exec_mode: 'cluster',
      instances: '2',
      script: './.output/server/index.mjs',
      env: {
        'NUXT_PUBLIC_DEXIE_DB': 'home-db',
        'NUXT_PUBLIC_DEXIE_DB_URL': 'https://xxxxxxxxx.dexie.cloud'
      },
    }]
}

现在我有我的本地开发人员,以及我的 LAN Web 服务器上的两个实例:一个“开发人员”(使用与本地相同的数据库,因此我可以删除和更新。并随心所欲地乱搞)和一个“生产” (使用单独的数据库,就像在实际生产中一样。

我希望这可以帮助那些陷入这个困境的人......

© www.soinside.com 2019 - 2024. All rights reserved.