Files
orrisroot 79e0e2295f feat: migrate from Create React App to Vite
react-scripts 4 on React 17 no longer builds on a current toolchain.
Move to Vite 8 with React 19 and TypeScript 7, and take the same shape
as the other converted sites.

- react-router-dom v5 -> react-router v8: Switch/Redirect become
  Routes/Navigate, and withRouter gives way to useLocation and
  useNavigate; the original /modules/... addresses are kept
- swap the unmaintained dependencies: axios -> ky, react-html-parser
  -> @orrisroot/react-html-parser, react-ga -> react-ga4,
  react-helmet -> @dr.pogodin/react-helmet, moment -> date-fns,
  react-spinner-material -> a CSS spinner, and a local HashLink in
  place of react-router-hash-link
- drop react-app-polyfill, the jest setup, xregexp and the unused
  async-lock, rc-tree, react-overlays and react-image-lightbox
- replace ESLint with Biome, yarn with npm, and match the other sites'
  tsconfigs and sanitize.css base stylesheet
- serve static-contents/ next to the repository with sirv in the dev
  and preview servers, keeping it out of dist/
- convert the page components to function components; each module
  loads its index once, sharing the request under StrictMode
- resolve relative links in page bodies the way a browser does, since
  react-router 8 resolves them against the route hierarchy
- fix the glossary search restricted to a category, whose query
  matched nothing
- set the GA4 measurement ID replacing the shut-down UA property
- correct the keywords meta tag copied from dynamicbrain
- write down the data layout and the deployment procedure
2026-09-15 12:56:11 +09:00

5.0 KiB

Invertebrate Brain Platform

Static front-end for the archived Invertebrate Brain Platform site, built with Vite, React and TypeScript.

Requirements

  • Node.js 20.19+ / 22.12+ (Vite 8)
  • npm

Setup

npm install

Site data

The pages are rendered from JSON dumped out of the original XOOPS installation by xoops-static-exporter (sites/invbrain.neuroinf.jp/).

All of it lives in static-contents/, which sits next to the repository rather than inside it:

invbrain.neuroinf.jp/
├── invbrain.neuroinf.jp/  this repository
├── deploy.sh
└── static-contents/
    ├── modules/           one directory per source XOOPS module
    │   ├── credits/       index.json, <page id>.json
    │   ├── documents/     pico: index.json, <content id>.json, images/
    │   ├── htmldocs/      pico: index.json, <content id>.json, IVBPF/
    │   ├── newdb*/        CosmoDB: index.json, <item id>.json, extract/, images/
    │   ├── PubMedPDF/     index.json
    │   ├── xfileuploader/ files linked from the pages
    │   └── xwords/        index.json
    ├── static/            static HTML trees linked from the pages
    ├── uploads/           files linked from the pages
    ├── common/            files linked from the pages
    └── rss.xml

The app keeps the original XOOPS addresses (/modules/<module>/...), so its routes share modules/ with the data. That works because the data files are all index.json, <id>.json and linked assets, none of which is a page URL, and a real file always wins over the SPA fallback.

Each module fetches its own index.json the first time one of its pages is shown, rather than all of them at start up.

The dev and preview servers mount static-contents/ at the site root. It is deliberately kept out of dist/: it runs to about 68 GB, and the web server maps it in directly. It is generated content and is not tracked in git.

Scripts

Command Description
npm run dev Start the dev server on http://localhost:5173
npm run build Type-check and build into dist/
npm run preview Serve the production build on http://localhost:4173
npm run lint Lint with Biome
npm run format Format with Biome
npm run check Lint, format and organize imports, applying the safe fixes

@types/node is pinned to the major that matches the Node runtime in use (24); .ncurc.js keeps npm-check-updates from bumping it past that.

There is currently no test suite.

Deployment

Build locally, then run ../deploy.sh, which does steps 2 to 4 below against the archive host. The server does not need a toolchain.

1. Build and check

npm ci
npm run check         # biome, writes fixes
npm run build         # runs tsc -b, then vite build
npm run preview       # localhost:4173 , serves dist/ + static-contents/

2. Send up the site data

About 68 GB, most of it under modules/newdb5/extract/. The server mirrors the local layout: static-contents/ sits next to the document root.

/data/www/invbrain.neuroinf.jp/
├── html/                  document root
└── static-contents/
rsync -a --delete static-contents/ \
    user@server:/data/www/invbrain.neuroinf.jp/static-contents/

3. Push the build

rsync -a --delete dist/ user@server:/data/www/invbrain.neuroinf.jp/html/

--delete clears out the previous build, and with it the data symlinks from step 4; they are recreated right after.

cd /data/www/invbrain.neuroinf.jp/html
ln -sfn ../static-contents/* .

That links every top-level entry of static-contents/ — currently modules/, static/, uploads/, common/ and rss.xml. The links are relative, so the whole tree can be moved without rewriting them.

Apache needs Options FollowSymLinks, AllowOverride All and Require all granted on the document root, and Options FollowSymLinks with Require all granted on static-contents/. Use symlinks rather than Alias: an aliased /modules is outside the document root, so .htaccess no longer sends the page URLs under it to index.html.

5. Check the deployed site

curl -I https://invbrain.neuroinf.jp/rss.xml                      # 200
curl -I https://invbrain.neuroinf.jp/modules/htmldocs/index.json  # 200

Then load /, a CosmoDB list and detail page (/modules/newdb5/list.php?id=2), /modules/PubMedPDF/, /modules/xwords/ and /modules/credits/ in a browser and confirm the images resolve.

Upgrading from v1.0.0

v1.0.0 already served the data from the same paths, so the data layout is unchanged and step 2 only has to transfer what differs.

Google Analytics

GOOGLE_ANALYTICS_TRACKING_ID in src/config.ts carries the GA4 measurement ID that replaced the Universal Analytics property shut down in 2023. Emptying it disables tracking.