Files
brainatlas.brain.riken.jp/vite.config.ts
T
orrisroot 20dd4f2a72 feat: serve the atlas data from XOOPS-style paths
v2.0.0 put every atlas under /data/<atlas>/, which broke the original
/<atlas>/static/ download links and kept the data out of the modules/
layout the other sites use.

- read tree.json and items.json from /<atlas>/modules/xoonips/ and
  link the files under /<atlas>/modules/xoonips/file/
- redirect download.php, the v2.0.0 /data/ paths and the older
  /<atlas>/file/ paths with a 301
- send directories without an index.html to the SPA as well: the
  atlas directories now exist on disk, and the old rule served them
  as a 404
2026-09-14 13:19:50 +09:00

63 lines
2.4 KiB
TypeScript

import fs from 'node:fs';
import path from 'node:path';
import react from '@vitejs/plugin-react';
import sirv from 'sirv';
import type { Connect, Plugin, ResolvedConfig } from 'vite';
import { defineConfig } from 'vite';
/**
* `static-contents/` holds the dumped atlas data (`<atlas>/modules/xoonips/`, `<atlas>/static/`).
* It sits next to the repository and is served from the site root next to
* `public/`, but it is deliberately kept out of the bundle: it runs to
* gigabytes of frozen data that the web server maps in directly. The dev and
* preview servers mount it so that both behave like production.
*/
const staticContents = (): Plugin => {
let dir: string;
const mount = (middlewares: { use: (fn: Connect.NextHandleFunction) => void }, dev: boolean) => {
if (fs.existsSync(dir)) {
// maxAge 0 makes sirv send `Cache-Control: public, max-age=0`, so the
// browser revalidates against the ETag instead of falling back to
// heuristic caching. Without it a re-dump, or another site served
// from the same localhost port, is answered from a stale cache.
middlewares.use(sirv(dir, { dev, etag: true, maxAge: 0 }));
}
};
return {
name: 'brainatlas:static-contents',
configResolved(config: ResolvedConfig) {
dir = path.resolve(config.root, '../static-contents');
},
configureServer(server) {
mount(server.middlewares, true);
},
configurePreviewServer(server) {
mount(server.middlewares, false);
},
};
};
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), staticContents()],
optimizeDeps: { exclude: ['fs'] },
build: {
sourcemap: true,
rolldownOptions: {
external: ['fs'],
output: {
// react and react-dom are over 200 kB together, which would
// push a single dependency chunk past the 500 kB warning
// threshold. They also change far less often than the rest,
// so split them off and let the two cache independently.
codeSplitting: {
groups: [
{ name: 'vendor-react', test: /node_modules\/(react|react-dom|scheduler)\// },
{ name: 'vendor-misc', test: /node_modules\// },
],
},
},
},
},
});