feat(nuxt3, bridge): useRuntimeConfig (#625)

Co-Authored-By: Daniel Roe <daniel@roe.dev>
This commit is contained in:
pooya parsa 2021-10-02 22:30:20 +02:00 committed by GitHub
parent e9a903f136
commit 45b4946026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 13 deletions

View File

@ -14,7 +14,8 @@ const identifiers = {
'useNuxtApp',
'defineNuxtPlugin',
'useRoute',
'useRouter'
'useRouter',
'useRuntimeConfig'
],
'@vue/composition-api': [
// lifecycle

View File

@ -14,6 +14,15 @@ export const useData = mock()
export const useGlobalData = mock()
export const useHydration = mock()
// Runtime config helper
export const useRuntimeConfig = () => {
const app = useNuxtApp().legacyApp
if (!app._$config) {
app._$config = reactive(app.$config)
}
return app._$config
}
// Auto-import equivalents for `vue-router`
export const useRouter = () => {
return useNuxtApp()?.legacyNuxt.router as VueRouter

View File

@ -1,16 +1,31 @@
import destr from 'destr'
import defu from 'defu'
// Bundled runtime config
export const runtimeConfig = process.env.RUNTIME_CONFIG as any
// Bundled runtime config (injected by nitro)
const _runtimeConfig = process.env.RUNTIME_CONFIG as any
// Allow override from process.env and deserialize
for (const type of ['private', 'public']) {
for (const key in runtimeConfig[type]) {
runtimeConfig[type][key] = destr(process.env[key] || runtimeConfig[type][key])
for (const key in _runtimeConfig[type]) {
_runtimeConfig[type][key] = destr(process.env[key] || _runtimeConfig[type][key])
}
}
// Export merged config
export const config = defu(runtimeConfig.private, runtimeConfig.public)
export default config
// Named exports
export const privateConfig = deepFreeze(defu(_runtimeConfig.private, _runtimeConfig.public))
export const publicConfig = deepFreeze(_runtimeConfig.public)
// Default export (usable for server)
export default privateConfig
// Utils
function deepFreeze (object: Record<string, any>) {
const propNames = Object.getOwnPropertyNames(object)
for (const name of propNames) {
const value = object[name]
if (value && typeof value === 'object') {
deepFreeze(value)
}
}
return Object.freeze(object)
}

View File

@ -1,7 +1,7 @@
import type { ServerResponse } from 'http'
import { createRenderer } from 'vue-bundle-renderer'
import devalue from '@nuxt/devalue'
import { runtimeConfig } from './config'
import { privateConfig, publicConfig } from './config'
// @ts-ignore
import htmlTemplate from '#build/views/document.template.mjs'
@ -63,7 +63,7 @@ export async function renderMiddleware (req, res: ServerResponse) {
url,
req,
res,
runtimeConfig,
runtimeConfig: { private: privateConfig, public: publicConfig },
noSSR: req.spa || req.headers['x-nuxt-no-ssr'],
...(req.context || {})
}

View File

@ -1,4 +1,4 @@
import { getCurrentInstance } from 'vue'
import { getCurrentInstance, reactive } from 'vue'
import type { App, VNode } from 'vue'
import { createHooks, Hookable } from 'hookable'
import { defineGetter } from './utils'
@ -107,6 +107,14 @@ export function createNuxtApp (options: CreateOptions) {
nuxt.payload = window.__NUXT__ || {}
}
// Expose runtime config
if (process.server) {
nuxt.provide('config', options.ssrContext.runtimeConfig.private)
nuxt.payload.config = options.ssrContext.runtimeConfig.public
} else {
nuxt.provide('config', reactive(nuxt.payload.config))
}
return nuxt
}
@ -182,3 +190,7 @@ export function useNuxtApp (): NuxtApp {
return vm.appContext.app.$nuxt
}
export function useRuntimeConfig (): Record<string, any> {
return useNuxtApp().$config
}

View File

@ -4,7 +4,8 @@ const identifiers = {
'asyncData',
'defineNuxtComponent',
'useNuxtApp',
'defineNuxtPlugin'
'defineNuxtPlugin',
'useRuntimeConfig'
],
'#meta': [
'useMeta'

View File

@ -4,5 +4,9 @@ export default defineNuxtConfig({
buildDir: process.env.NITRO_BUILD_DIR,
nitro: {
output: { dir: process.env.NITRO_OUTPUT_DIR }
},
publicRuntimeConfig: {
// @ts-ignore TODO: Fix schema types
testConfig: '123'
}
})

View File

@ -1,3 +1,10 @@
<template>
<div>Hello Vue</div>
<div>
<h1>Hello Vue 3</h1>
<div>Config: {{ $config.testConfig }}</div>
</div>
</template>
<script setup>
const $config = useRuntimeConfig()
</script>