refactor: env config (#769)

This commit is contained in:
三咲智子 Kevin Deng 2023-01-04 21:26:30 +08:00 committed by GitHub
parent 9d5dc1bc3d
commit f892722220
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 121 additions and 64 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import buildInfo from 'virtual:build-info'
import { buildInfo } from 'virtual:build-info'
const timeAgoOptions = useTimeAgoOptions()
@ -35,10 +35,10 @@ function toggleDark() {
<span v-else>
{{ $t('nav.built_at', [$d(buildTimeDate, 'shortDate')]) }}
</span>
<template v-if="buildInfo.version">
&middot;
v{{ buildInfo.version }}
</template>
<!-- TODO click version to show changelog -->
<span v-if="buildInfo.env === 'release'">v{{ buildInfo.version }}</span>
<span v-else>{{ buildInfo.env }}</span>
<template v-if="buildInfo.commit && buildInfo.branch !== 'release'">
&middot;
<NuxtLink

View file

@ -1,6 +1,7 @@
<script setup lang="ts">
const env = useRuntimeConfig().public.env
const sub = env === 'local' ? 'dev' : env === 'staging' ? 'preview' : 'alpha'
import { buildInfo } from 'virtual:build-info'
const { env } = buildInfo
</script>
<template>
@ -17,7 +18,7 @@ const sub = env === 'local' ? 'dev' : env === 'staging' ? 'preview' : 'alpha'
>
<img :alt="$t('app_logo')" src="/logo.svg" shrink-0 aspect="1/1" sm:h-8 xl:h-10 class="rtl-flip">
<div hidden xl:block>
{{ $t('app_name') }} <sup text-sm italic text-secondary mt-1>{{ sub }}</sup>
{{ $t('app_name') }} <sup text-sm italic text-secondary mt-1>{{ env === 'release' ? 'alpha' : env }}</sup>
</div>
</NuxtLink>
</template>

View file

@ -1,13 +1,11 @@
import { pwaInfo } from 'virtual:pwa-info'
import type { Link } from '@unhead/schema'
import type { Directions } from 'vue-i18n-routing'
import { buildInfo } from 'virtual:build-info'
import { APP_NAME } from '~/constants'
import type { LocaleObject } from '#i18n'
export function setupPageHeader() {
const isDev = process.dev
const isPreview = useRuntimeConfig().public.env === 'staging'
const i18n = useI18n()
const link: Link[] = []
@ -42,7 +40,13 @@ export function setupPageHeader() {
lang: () => i18n.locale.value,
dir: () => localeMap[i18n.locale.value] ?? 'auto',
},
titleTemplate: title => `${title ? `${title} | ` : ''}${APP_NAME}${isDev ? ' (dev)' : isPreview ? ' (preview)' : ''}`,
titleTemplate: (title) => {
let titleTemplate = title ? `${title} | ` : ''
titleTemplate += APP_NAME
if (buildInfo.env !== 'release')
titleTemplate += ` (${buildInfo.env})`
return titleTemplate
},
link,
})
}

39
config/env.ts Normal file
View file

@ -0,0 +1,39 @@
import Git from 'simple-git'
import { isDevelopment } from 'std-env'
export { version } from '../package.json'
/**
* Environment variable `PULL_REQUEST` provided by Netlify.
* @see {@link https://docs.netlify.com/configure-builds/environment-variables/#git-metadata}
*
* Whether triggered by a GitHub PR
*/
export const isPR = process.env.PULL_REQUEST === 'true'
/**
* Environment variable `CONTEXT` provided by Netlify.
* @see {@link https://docs.netlify.com/configure-builds/environment-variables/#build-metadata}
*
* Whether triggered by PR, `deploy-preview` or `dev`.
*/
export const isPreview = isPR || process.env.CONTEXT === 'deploy-preview' || process.env.CONTEXT === 'dev'
const git = Git()
export const getGitInfo = async () => {
const branch = await git.revparse(['--abbrev-ref', 'HEAD'])
const commit = await git.revparse(['HEAD'])
return { branch, commit }
}
export const getEnv = async () => {
const { commit, branch } = await getGitInfo()
const env = isDevelopment
? 'dev'
: isPreview
? 'preview'
: branch === 'main'
? 'main'
: 'release'
return { commit, branch, env } as const
}

View file

@ -1,7 +1,7 @@
import { isCI, isDevelopment } from 'std-env'
import type { VitePWANuxtOptions } from '../modules/pwa/types'
const isPreview = process.env.PULL_REQUEST === 'true'
import { APP_NAME } from '../constants'
import { getEnv } from './env'
export const pwa: VitePWANuxtOptions = {
mode: isCI ? 'production' : 'development',
@ -13,12 +13,15 @@ export const pwa: VitePWANuxtOptions = {
strategies: 'injectManifest',
injectRegister: false,
includeManifestIcons: false,
manifest: {
manifest: async () => {
const { env } = await getEnv()
const envName = `${env !== 'release' ? '' : ` (${env})`}`
return {
scope: '/',
id: '/',
name: `Elk${isCI ? isPreview ? ' (preview)' : '' : ' (dev)'}`,
short_name: `Elk${isCI ? isPreview ? ' (preview)' : '' : ' (dev)'}`,
description: `A nimble Mastodon Web Client${isCI ? isPreview ? ' (preview)' : '' : ' (development)'}`,
name: `${APP_NAME}${envName}`,
short_name: `${APP_NAME}${envName}`,
description: `A nimble Mastodon Web Client${envName}`,
theme_color: '#ffffff',
icons: [
{
@ -38,8 +41,9 @@ export const pwa: VitePWANuxtOptions = {
type: 'image/png',
purpose: 'any maskable',
},
*/
*/
],
}
},
injectManifest: {
globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm}'],

View file

@ -1,20 +1,23 @@
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
import Git from 'simple-git'
import { version } from '../package.json'
import { getEnv, version } from '../config/env'
import type { BuildInfo } from '~/types'
export default defineNuxtModule({
meta: {
name: 'elk:build-info',
},
async setup() {
const git = Git()
async setup(_options, nuxt) {
const { env, commit, branch } = await getEnv()
nuxt.options.runtimeConfig.public.env = env
const buildInfo: BuildInfo = {
version,
time: +Date.now(),
commit: await git.revparse(['HEAD']),
branch: await git.revparse(['--abbrev-ref', 'HEAD']),
commit,
branch,
env,
}
addVitePlugin({
name: 'elk:build-info',
resolveId(id) {
@ -23,7 +26,7 @@ export default defineNuxtModule({
},
load(id) {
if (id === 'virtual:build-info')
return `export default ${JSON.stringify(buildInfo, null, 2)}`
return `export const buildInfo = ${JSON.stringify(buildInfo, null, 2)}`
},
})
},

View file

@ -1,5 +1,5 @@
import { defineNuxtModule } from '@nuxt/kit'
import type { VitePluginPWAAPI } from 'vite-plugin-pwa'
import type { VitePWAOptions, VitePluginPWAAPI } from 'vite-plugin-pwa'
import { VitePWA } from 'vite-plugin-pwa'
import type { Plugin } from 'vite'
import type { VitePWANuxtOptions } from './types'
@ -32,14 +32,17 @@ export default defineNuxtModule<VitePWANuxtOptions>({
if (plugin)
throw new Error('Remove vite-plugin-pwa plugin from Vite Plugins entry in Nuxt config file!')
})
nuxt.hook('vite:extendConfig', (viteInlineConfig, { isClient }) => {
nuxt.hook('vite:extendConfig', async (viteInlineConfig, { isClient }) => {
viteInlineConfig.plugins = viteInlineConfig.plugins || []
const plugin = viteInlineConfig.plugins.find(p => p && typeof p === 'object' && 'name' in p && p.name === 'vite-plugin-pwa')
if (plugin)
throw new Error('Remove vite-plugin-pwa plugin from Vite Plugins entry in Nuxt config file!')
configurePWAOptions(options, nuxt)
const plugins = VitePWA(options)
const resolvedOptions: Partial<VitePWAOptions> = {
...options,
manifest: options.manifest ? await options.manifest() : undefined,
}
configurePWAOptions(resolvedOptions, nuxt)
const plugins = VitePWA(resolvedOptions)
viteInlineConfig.plugins.push(plugins)
if (isClient)
vitePwaClientPlugin = plugins.find(p => p.name === 'vite-plugin-pwa') as Plugin

View file

@ -1,6 +1,9 @@
import type { VitePWAOptions } from 'vite-plugin-pwa'
import type { ManifestOptions, VitePWAOptions } from 'vite-plugin-pwa'
import type { Overwrite } from '../../types/utils'
export interface VitePWANuxtOptions extends Partial<VitePWAOptions> {}
export type VitePWANuxtOptions = Overwrite<Partial<VitePWAOptions>, {
manifest?: () => Promise<Partial<ManifestOptions>>
}>
declare module '@nuxt/schema' {
interface NuxtConfig {

View file

@ -3,9 +3,9 @@ import Inspect from 'vite-plugin-inspect'
import { isCI, isDevelopment } from 'std-env'
import { i18n } from './config/i18n'
import { pwa } from './config/pwa'
import { isPreview } from './config/env'
const { resolve } = createResolver(import.meta.url)
const isPreview = process.env.PULL_REQUEST === 'true' || process.env.CONTEXT === 'deploy-preview' || process.env.CONTEXT === 'dev'
export default defineNuxtConfig({
typescript: {
@ -90,7 +90,7 @@ export default defineNuxtConfig({
inviteToken: '',
},
public: {
env: isCI ? isPreview ? 'staging' : 'production' : 'local',
env: '', // set in build-info module
pwaEnabled: !isDevelopment || process.env.VITE_DEV_PWA === 'true',
translateApi: '',
},

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import buildInfo from 'virtual:build-info'
import { buildInfo } from 'virtual:build-info'
let showCommit = $ref(false)
let showCommit = $ref(buildInfo.env !== 'release' && buildInfo.env !== 'dev')
const builtTime = useFormattedDateTime(buildInfo.time)
const handleShowCommit = () => {
@ -35,8 +35,8 @@ const handleShowCommit = () => {
>
<template #content>
<div font-mono>
v{{ buildInfo.version }}
<span v-if="showCommit">({{ buildInfo.commit.slice(0, 7) }})</span>
<span>{{ buildInfo.env === 'release' ? `v${buildInfo.version}` : buildInfo.env }}</span>
<span v-if="showCommit"> ({{ buildInfo.commit.slice(0, 7) }})</span>
</div>
</template>
</SettingsItem>

View file

@ -39,7 +39,7 @@ async function fetchAppInfo(origin: string, server: string) {
const app: AppInfo = await $fetch(`https://${server}/api/v1/apps`, {
method: 'POST',
body: {
client_name: APP_NAME + (config.public.env === 'local' ? ' (dev)' : ''),
client_name: APP_NAME + (config.public.env !== 'release' ? ` (${config.public.env})` : ''),
website: 'https://elk.zone',
redirect_uris: getRedirectURI(origin, server),
scopes: 'read write follow push',

3
shims.d.ts vendored
View file

@ -4,6 +4,5 @@
declare module 'virtual:build-info' {
import type { BuildInfo } from '~/types'
const buildInfo: BuildInfo
export default buildInfo
export const buildInfo: BuildInfo
}

View file

@ -69,6 +69,7 @@ export interface BuildInfo {
commit: string
time: number
branch: string
env: 'preview' | 'main' | 'dev' | 'release'
}
export type FontSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'