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', 'useNuxtApp',
'defineNuxtPlugin', 'defineNuxtPlugin',
'useRoute', 'useRoute',
'useRouter' 'useRouter',
'useRuntimeConfig'
], ],
'@vue/composition-api': [ '@vue/composition-api': [
// lifecycle // lifecycle

View File

@ -14,6 +14,15 @@ export const useData = mock()
export const useGlobalData = mock() export const useGlobalData = mock()
export const useHydration = 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` // Auto-import equivalents for `vue-router`
export const useRouter = () => { export const useRouter = () => {
return useNuxtApp()?.legacyNuxt.router as VueRouter return useNuxtApp()?.legacyNuxt.router as VueRouter

View File

@ -1,16 +1,31 @@
import destr from 'destr' import destr from 'destr'
import defu from 'defu' import defu from 'defu'
// Bundled runtime config // Bundled runtime config (injected by nitro)
export const runtimeConfig = process.env.RUNTIME_CONFIG as any const _runtimeConfig = process.env.RUNTIME_CONFIG as any
// Allow override from process.env and deserialize // Allow override from process.env and deserialize
for (const type of ['private', 'public']) { for (const type of ['private', 'public']) {
for (const key in runtimeConfig[type]) { for (const key in _runtimeConfig[type]) {
runtimeConfig[type][key] = destr(process.env[key] || runtimeConfig[type][key]) _runtimeConfig[type][key] = destr(process.env[key] || _runtimeConfig[type][key])
} }
} }
// Export merged config // Named exports
export const config = defu(runtimeConfig.private, runtimeConfig.public) export const privateConfig = deepFreeze(defu(_runtimeConfig.private, _runtimeConfig.public))
export default config 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 type { ServerResponse } from 'http'
import { createRenderer } from 'vue-bundle-renderer' import { createRenderer } from 'vue-bundle-renderer'
import devalue from '@nuxt/devalue' import devalue from '@nuxt/devalue'
import { runtimeConfig } from './config' import { privateConfig, publicConfig } from './config'
// @ts-ignore // @ts-ignore
import htmlTemplate from '#build/views/document.template.mjs' import htmlTemplate from '#build/views/document.template.mjs'
@ -63,7 +63,7 @@ export async function renderMiddleware (req, res: ServerResponse) {
url, url,
req, req,
res, res,
runtimeConfig, runtimeConfig: { private: privateConfig, public: publicConfig },
noSSR: req.spa || req.headers['x-nuxt-no-ssr'], noSSR: req.spa || req.headers['x-nuxt-no-ssr'],
...(req.context || {}) ...(req.context || {})
} }

View File

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

View File

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

View File

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

View File

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