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
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.
4. Link the site data into the document root
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.