Skip to content

Commit ce1e2d2

Browse files
abultestreino
andauthored
chore: merge config at build time (#846)
* chore: merge config at build time * comment * Use ViteRestart to detect config changes (#865) --------- Co-authored-by: streino <[email protected]>
1 parent dfea007 commit ce1e2d2

File tree

4 files changed

+53
-42
lines changed

4 files changed

+53
-42
lines changed

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"unplugin-yaml": "^1.3.0",
8181
"vite": "^6.3.4",
8282
"vite-plugin-dynamic-import": "^1.6.0",
83+
"vite-plugin-restart": "^1.0.0",
8384
"vite-plugin-vue-devtools": "^7.7.0",
8485
"vitest": "^3.0.9",
8586
"vue-tsc": "^2.2.0"

src/config.ts

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,5 @@
1-
import config from '@siteConfig/config.yaml'
2-
import merge from 'deepmerge'
3-
4-
const mode = import.meta.env.MODE
5-
const site_id = import.meta.env.VITE_SITE_ID
6-
7-
// Use Vite's import.meta.glob to conditionally load mode-specific configs
8-
// This will actually only include the specific config file of the current mode
9-
// thanks to vite.config.mts dynamicImport plugin
10-
const modeConfigs = import.meta.glob('@siteConfig/config.*.yaml', {
11-
eager: true
12-
})
13-
14-
// Try to find and merge mode-specific config
15-
let finalConfig = config
16-
const modeConfigKey = `/configs/${site_id}/config.${mode}.yaml`
17-
18-
if (modeConfigs[modeConfigKey]) {
19-
console.log(
20-
`Loading and merging config for ${mode} with the default config of ${site_id}`
21-
)
22-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
23-
const configForMode = (modeConfigs[modeConfigKey] as any).default
24-
finalConfig = merge(config, configForMode)
25-
} else {
26-
console.log(
27-
`No specific config found for ${mode}, using default config of ${site_id}`
28-
)
29-
}
30-
31-
export default finalConfig
1+
// __APP_CONFIG__ is exported from {site_id}/config.*.yaml files in vite.config.mts
2+
// TODO: we should type the entire config here
3+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4+
declare const __APP_CONFIG__: any
5+
export default __APP_CONFIG__

vite.config.mts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import vue from '@vitejs/plugin-vue'
2+
import merge from 'deepmerge'
23
import { readFileSync } from 'fs'
34
import { load } from 'js-yaml'
45
import { fileURLToPath, URL } from 'node:url'
@@ -7,6 +8,7 @@ import ViteYaml from 'unplugin-yaml/vite'
78
import { defineConfig, loadEnv } from 'vite'
89
import dynamicImport from 'vite-plugin-dynamic-import'
910
import { createHtmlPlugin } from 'vite-plugin-html'
11+
import ViteRestart from 'vite-plugin-restart'
1012
import vueDevTools from 'vite-plugin-vue-devtools'
1113

1214
import {
@@ -29,10 +31,33 @@ interface Config {
2931
export default defineConfig(({ mode }) => {
3032
const env = loadEnv(mode, process.cwd(), '')
3133
const configDir = `./configs/${env.VITE_SITE_ID}`
32-
const configFileUrl = new URL(`${configDir}/config.yaml`, import.meta.url)
33-
const config = load(readFileSync(configFileUrl, 'utf-8')) as Config
34+
const configFiles = []
35+
36+
// Load base config
37+
const mainConfigFile = `${configDir}/config.yaml`
38+
configFiles.push(mainConfigFile)
39+
let config = load(
40+
readFileSync(new URL(mainConfigFile, import.meta.url), 'utf-8')
41+
) as Config
42+
43+
// Try to load and merge mode-specific config
44+
const modeConfigFile = `${configDir}/config.${mode}.yaml`
45+
configFiles.push(modeConfigFile)
46+
try {
47+
const modeConfig = load(
48+
readFileSync(new URL(modeConfigFile, import.meta.url), 'utf-8')
49+
) as Config
50+
config = merge(config, modeConfig)
51+
console.log(`Merged ${mode} config at build time`)
52+
} catch {
53+
console.log(`No ${mode} config found, using default`)
54+
}
55+
3456
return {
3557
base: '/',
58+
define: {
59+
__APP_CONFIG__: JSON.stringify(config)
60+
},
3661
plugins: [
3762
vueDevTools(),
3863
vue({
@@ -90,16 +115,10 @@ export default defineConfig(({ mode }) => {
90115
routeFile.includes(`custom/${env.VITE_SITE_ID}/routes.ts`)
91116
)
92117
}
93-
// Include only the current mode's config file in the bundle
94-
// to prevent /src/config.ts from including all config files before picking the right one
95-
if (id.includes('/src/config.ts')) {
96-
return files.filter((configFile) =>
97-
configFile.includes(
98-
`configs/${env.VITE_SITE_ID}/config.${mode}.yaml`
99-
)
100-
)
101-
}
102118
}
119+
}),
120+
ViteRestart({
121+
restart: configFiles
103122
})
104123
],
105124
resolve: {

0 commit comments

Comments
 (0)