lang.lapyst.dev/vite.config.ts

147 lines
5.7 KiB
TypeScript

import { ConfigEnv, Plugin, ViteDevServer, defineConfig } from 'vite'
import { join } from 'node:path';
import { readFile as readFileAsync } from 'node:fs/promises';
import { writeFileSync } from 'node:fs';
import react from '@vitejs/plugin-react-swc';
import { monaco } from '@bithero/monaco-editor-vite-plugin';
import parseStyleToJs from 'style-to-js';
import { preload_assets, typegroup_assets, defaultPreloadFilters, mock_requests } from '@bithero/vite-plugins';
import { sourcegen } from '@bithero/vite-plugins';
import { spawn } from 'node:child_process';
function DataHotReload(): Plugin {
return {
name: 'data-hot-reload',
configureServer(server: ViteDevServer) {
server.watcher.add(join(process.cwd(), '.tmp', 'data'));
},
handleHotUpdate({ file, server }) {
if (file.endsWith('langref.json')) {
console.log("langref.json updated...");
server.ws.send({
type: "custom",
event: "langref-update",
});
}
},
};
}
export default defineConfig((env: ConfigEnv) => ({
root: 'src',
publicDir: '../public',
plugins: [
sourcegen({
name: 'bh-langref',
sourceIds: [ 'lapyst/langref.jsx' ],
patterns: '.tmp/data/*.json',
handleFileEvent(event, info, ctx) {},
async codegen(sourceId, ctx) {
const raw = await readFileAsync(join(process.cwd(), '.tmp', 'data', 'langref.json'), {encoding: 'utf-8'});
const data = JSON.parse(raw);
function mkComponent(key: string, value: any) {
const name = key.replace(/^\/language\/ref\//, '').replace(/\//, '_');
const content = value.content
.replaceAll(/\bclass=\"/g, 'className="')
.replaceAll(/\bstyle=\"(.*?)\"/gs, (m, p1) => {
let style = parseStyleToJs(p1);
return `style={${JSON.stringify(style)}}`;
})
.replaceAll(/\<(img|col) (.*?)\>/gs, '<$1 $2/>')
.replaceAll(/\<code\>(.*?)<\/code\>/gs, (m, p1) => {
p1 = p1.replaceAll(/(`|\\)/g, '\\$1');
return `<code>{\`${p1}\`}</code>`;
})
.replaceAll(/\<pre (.*?)\>(.*?)\<\/pre\>/gs, (m, p1, p2) => {
p2 = p2.replaceAll(
/(?<=^|a\>)(.*?)(?=\<a|$)/gs,
(m,p1) => {
p1 = p1
.replaceAll(/(`|\\)/g, '\\$1')
.replaceAll(/&amp;/g, '&')
.replaceAll(/&lt;/g, '<')
.replaceAll(/&gt;/g, '>')
return `{\`${p1}\`}`;
}
);
return `<pre ${p1}>${p2}</pre>`;
})
;
return `export const ${name} = () => { return (<div><h1>${value.title}</h1>${content}</div>); }`;
}
const code = [
'import React from \'react\';',
`export const nav_data = ${JSON.stringify(data.nav)};`,
...Object.entries(data.pages as Record<string, any>).map(([key, value]) => mkComponent(key, value)),
].join('\n');
writeFileSync('./.tmp/website.jsx', code, {encoding: 'utf-8'});
return code;
},
}),
react(),
mock_requests({
mocks: [
{
url: '/data/releases.json',
file: [
{ version: '1.0.1', latest: true, date: '2023-10-09' },
{
version: '1.0.0', latest: false, date: '2023-10-09', changelog: 'initial release :D',
downloads: [
{ filename: 'lapyst-1.0.0-1_x86_64.pkg.tar.zst', location: '', kind: 'archlinux' },
{ filename: 'lapyst-1.0.0.tar.gz', location: '', kind: 'linux_generic' },
]
}
],
},
{
url: /^\/data\/.*\.json$/,
file: (url) => readFileAsync(join(process.cwd(), '.tmp', url), {encoding: 'utf-8'}),
}
],
}),
// preload_assets({
// filters: [
// ...defaultPreloadFilters(),
// { type: 'fetch', filter: /^\/data\/.*\.json$/i }
// ]
// }),
typegroup_assets(),
DataHotReload(),
monaco(),
// bp5(),
],
worker: {
format: 'es',
} as any,
resolve: {
alias: [
{
// used in css/scss to resolve css files in node_modules packages
find: /~(.+)/,
replacement: join(process.cwd(), 'node_modules/$1'),
},
],
},
build: {
outDir: '../dist',
emptyOutDir: true,
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
// Trying to move the monaco-editor into it's own file / chunk...
'monaco-editor': ['monaco-editor'],
'react': ['react', 'react-dom', 'react-router'],
},
},
},
},
}));