Skip to content

Commit 3ea20a6

Browse files
authored
move vite config up to core and fix version loading from core package (#9)
* move vite config up to core and fix version loading from core package json * test package json version extraction for core package Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * up versions
1 parent 7f2668d commit 3ea20a6

9 files changed

Lines changed: 4699 additions & 407 deletions

File tree

package-lock.json

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

packages/bootstrap/src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export const TAG_URL
2-
= 'https://github.com/MavonEngine/Core/archive/refs/tags/0.0.9-alpha.zip'
2+
= 'https://github.com/MavonEngine/Core/archive/refs/tags/0.0.10-alpha.zip'
33

44
export const TEMPLATE_SUBPATH = 'packages/multiplayer-template'

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mavonengine/core",
33
"type": "module",
4-
"version": "0.0.8",
4+
"version": "0.0.9",
55
"description": "",
66
"author": "",
77
"license": "MIT",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { readFileSync } from 'node:fs'
2+
import { beforeEach, describe, expect, it, vi } from 'vitest'
3+
import { createPackageJsonPlugin } from '../../../vite/plugins/packageJsonPlugin.js'
4+
5+
vi.mock('node:fs', () => ({
6+
readFileSync: vi.fn(),
7+
}))
8+
9+
describe('createPackageJsonPlugin', () => {
10+
let resolveHandler: (args: { path: string }) => { path: string, namespace: string }
11+
let loadHandler: (args: { path: string }) => { contents: string, loader: string }
12+
13+
beforeEach(() => {
14+
const plugin = createPackageJsonPlugin('/fake/core/root')
15+
const mockBuild = {
16+
onResolve: vi.fn((_: unknown, handler: typeof resolveHandler) => {
17+
resolveHandler = handler
18+
}),
19+
onLoad: vi.fn((_: unknown, handler: typeof loadHandler) => {
20+
loadHandler = handler
21+
}),
22+
}
23+
plugin.setup(mockBuild)
24+
})
25+
26+
describe('onResolve', () => {
27+
it('resolves @mavonengine/core package.json to coreRoot', () => {
28+
const result = resolveHandler({ path: '@mavonengine/core/package.json' })
29+
expect(result.path).toBe('/fake/core/root/package.json')
30+
expect(result.namespace).toBe('mavonengine-pkg-json')
31+
})
32+
33+
it('returns null for non-core package.json paths', () => {
34+
const result = resolveHandler({ path: '/some/other/package.json' })
35+
expect(result).toBeNull()
36+
})
37+
})
38+
39+
describe('onLoad', () => {
40+
it('generates named exports for valid identifier keys', () => {
41+
vi.mocked(readFileSync).mockReturnValue(JSON.stringify({ name: 'test-pkg', version: '1.0.0' }))
42+
const result = loadHandler({ path: '/fake/package.json' })
43+
expect(result.contents).toContain('export const name = "test-pkg";')
44+
expect(result.contents).toContain('export const version = "1.0.0";')
45+
})
46+
47+
it('filters out non-identifier keys from named exports', () => {
48+
vi.mocked(readFileSync).mockReturnValue(
49+
JSON.stringify({ 'hyphen-key': 'value', '@scoped': 'foo', 'valid': 'yes' }),
50+
)
51+
const result = loadHandler({ path: '/fake/package.json' })
52+
expect(result.contents).not.toContain('export const hyphen-key')
53+
expect(result.contents).not.toContain('export const @scoped')
54+
expect(result.contents).toContain('export const valid = "yes";')
55+
})
56+
57+
it('includes a default export of the full package object', () => {
58+
const pkg = { 'name': 'test', 'version': '1.0.0', 'non-identifier': true }
59+
vi.mocked(readFileSync).mockReturnValue(JSON.stringify(pkg))
60+
const result = loadHandler({ path: '/fake/package.json' })
61+
expect(result.contents).toContain(`export default ${JSON.stringify(pkg)};`)
62+
})
63+
64+
it('sets loader to js', () => {
65+
vi.mocked(readFileSync).mockReturnValue(JSON.stringify({}))
66+
const result = loadHandler({ path: '/fake/package.json' })
67+
expect(result.loader).toBe('js')
68+
})
69+
})
70+
})

packages/core/vite.config.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
1+
import { readFileSync } from 'node:fs'
2+
import { dirname } from 'node:path'
3+
import { fileURLToPath } from 'node:url'
14
import { defineConfig } from 'vite'
25
import glsl from 'vite-plugin-glsl'
6+
import { createPackageJsonPlugin } from './vite/plugins/packageJsonPlugin.js'
7+
8+
const GLSL_FILTER = /\.glsl$/
9+
10+
const coreRoot = dirname(fileURLToPath(import.meta.url))
11+
12+
const mavonEngineGlslPlugin = {
13+
name: 'glsl',
14+
setup(build) {
15+
build.onLoad({ filter: GLSL_FILTER }, (args) => {
16+
return {
17+
contents: `export default ${JSON.stringify(readFileSync(args.path, 'utf8'))}`,
18+
loader: 'js',
19+
}
20+
})
21+
},
22+
}
323

424
export default defineConfig({
525
plugins: [
626
glsl(),
727
],
28+
optimizeDeps: {
29+
esbuildOptions: {
30+
plugins: [
31+
mavonEngineGlslPlugin,
32+
createPackageJsonPlugin(coreRoot),
33+
],
34+
},
35+
},
836
server: {
937
watch: {
1038
// For local npm link dev mode in @mavonengine/core
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { readFileSync } from 'node:fs'
2+
import { resolve } from 'node:path'
3+
4+
const PACKAGE_JSON_FILTER = /[/\\]package\.json$/
5+
const ALL_FILTER = /.*/
6+
const IDENTIFIER_FILTER = /^[a-z_$][\w$]*$/i
7+
8+
/*
9+
* Allows importing package.json as an ES module with named exports so the
10+
* client package can display the correct engine version at runtime.
11+
*/
12+
export function createPackageJsonPlugin(coreRoot) {
13+
return {
14+
name: 'package-json',
15+
setup(build) {
16+
build.onResolve({ filter: PACKAGE_JSON_FILTER }, (args) => {
17+
if (!args.path.includes('@mavonengine/core'))
18+
return null
19+
return { path: resolve(coreRoot, 'package.json'), namespace: 'mavonengine-pkg-json' }
20+
})
21+
build.onLoad({ filter: ALL_FILTER, namespace: 'mavonengine-pkg-json' }, (args) => {
22+
const pkg = JSON.parse(readFileSync(args.path, 'utf8'))
23+
const named = Object.entries(pkg)
24+
.filter(([k]) => IDENTIFIER_FILTER.test(k))
25+
.map(([k, v]) => `export const ${k} = ${JSON.stringify(v)};`)
26+
.join('\n')
27+
return { contents: `${named}\nexport default ${JSON.stringify(pkg)};`, loader: 'js' }
28+
})
29+
},
30+
}
31+
}

packages/multiplayer-template/client/vite.config.js

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,18 @@
1-
import { existsSync, readFileSync } from 'node:fs'
1+
import { existsSync } from 'node:fs'
22
import { dirname, resolve } from 'node:path'
33
import { fileURLToPath } from 'node:url'
44
import config from '@mavonengine/core/vite.config'
55
import vue from '@vitejs/plugin-vue'
66

7-
const GLSL_FILTER = /\.glsl$/
8-
const PACKAGE_JSON_FILTER = /[/\\]package\.json$/
9-
const ALL_FILTER = /.*/
10-
const IDENTIFIER_FILTER = /^[a-z_$][\w$]*$/i
11-
127
const clientRoot = dirname(fileURLToPath(import.meta.url))
138
const templateRoot = resolve(clientRoot, '..')
149
const coreRoot = resolve(clientRoot, '../../core')
1510
const coreSrc = resolve(coreRoot, 'src')
1611
const editorRoot = resolve(clientRoot, '../../editor')
1712
const editorSrc = resolve(editorRoot, 'src/Editor.ts')
1813

19-
// esbuild plugin: handles .glsl imports during dep pre-bundling
20-
const glslPlugin = {
21-
name: 'glsl',
22-
setup(build) {
23-
build.onLoad({ filter: GLSL_FILTER }, (args) => {
24-
return { contents: `export default ${JSON.stringify(readFileSync(args.path, 'utf8'))}`, loader: 'js' }
25-
})
26-
},
27-
}
28-
29-
// esbuild plugin: handles `import { version } from 'package.json' with { type: 'json' }`
30-
// esbuild rejects this because @mavonengine/core's exports field doesn't list package.json
31-
const packageJsonPlugin = {
32-
name: 'package-json',
33-
setup(build) {
34-
build.onResolve({ filter: PACKAGE_JSON_FILTER }, args => ({ path: args.path, namespace: 'pkg-json' }))
35-
build.onLoad({ filter: ALL_FILTER, namespace: 'pkg-json' }, (args) => {
36-
const pkg = JSON.parse(readFileSync(args.path, 'utf8'))
37-
const named = Object.entries(pkg)
38-
.filter(([k]) => IDENTIFIER_FILTER.test(k))
39-
.map(([k, v]) => `export const ${k} = ${JSON.stringify(v)};`)
40-
.join('\n')
41-
return { contents: `${named}\nexport default ${JSON.stringify(pkg)};`, loader: 'js' }
42-
})
43-
},
44-
}
45-
4614
export default {
4715
...config,
48-
optimizeDeps: {
49-
esbuildOptions: {
50-
plugins: [glslPlugin, packageJsonPlugin],
51-
},
52-
},
5316
server: {
5417
...config.server,
5518
fs: {

0 commit comments

Comments
 (0)