npm test # unit tests (vitest)
npm run e2e # end-to-end tests (playwright); starts its own ng serve
npm run lint # eslint
npm run format # prettier, writes
npm run check:lint # what CI enforces: zero errors, warnings not increasing
npm run check:dead # unreachable files and exports, same ideaA pre-commit hook formats staged files and runs eslint over them. It blocks on errors only, not warnings — see below for why.
This codebase had no linter for most of its life, so switching one on produced around 1600 findings. Requiring all of them fixed before anything could be enforced would have meant nothing ever being enforced. Instead there are two ratchets, and one rule about severity.
Severity records whether the codebase is already clean of a rule.
error— no existing violations. Any error is therefore new, and CI fails.warn— violations exist. Each rule's count is recorded inlint-baseline.jsonand can only go down, rule by rule: fixing one rule does not buy room to add to another. A rule the baseline does not list is held at zero, so a newly warned rule is recorded withnpm run check:lint -- --updatewhen it is added.
When you fix a warned rule's last violation, promote it to error in
eslint.config.js. That is how the list shrinks rather than sitting at its
current size forever. Four rules have made that trip already: the two promise
rules, prefer-inject, and no-empty-lifecycle-method.
Unreachable code is tracked the same way by check:dead (knip), which finds
whole files and exports nothing imports — something eslint cannot see. Note that
"not imported" does not always mean "safe to delete": the graph model classes are
referred to by schemaClass name strings rather than by import.
After reducing either count, lock it in:
npm run check:lint -- --update
npm run check:dead -- --updateRoughly 680 warnings live in files people still have to edit. Blocking every commit that touches one would get the hook disabled within a week. The bar for committing is the same as the bar CI enforces: no errors.
Signals and change detection. The app runs zoneless. Nothing patches the
browser's async APIs, so state set from a raw addEventListener, a
ResizeObserver, an IntersectionObserver or a bare setTimeout reaches the
template only if the component says so — a signal, or markForCheck(). Getting
this wrong renders a stale view and throws nothing, so it will not show up as an
error anywhere.
Effects are synchronous. effect(async () => ...) looks fine and quietly
breaks: anything read after the first await is not tracked as a dependency, so
the effect never re-runs for it. Read signals up front, then do the async work.
The backend is local. proxy.conf.js points at http://localhost:8080,
where ContentService, AnalysisService and ExperimentDigester all run. Pointing it
at dev.reactome.org instead sends every API call out through Cloudflare and
back into the same machine's Apache; a repeated e2e run once exhausted Apache's
workers that way and took the origin down. CI sets REACTOME_BACKEND to a public
host because a runner has no local backend.
Tests run against real data. The e2e suite asserts on content from the content service rather than on elements existing, because a page that renders its shell with an empty list looks fine to a container-based assertion. Specs that need endpoints only present on the dev host check for them and skip rather than fail.
projects/ holds two libraries that build to dist/ and are consumed from
there, not from node_modules. Build them before the app will compile:
npm run build:libsThe diagram style library and the theme come built from
ngx-reactome-base; change them
there. Each passing push to its main publishes a build, and
npm update ngx-reactome-cytoscape-style ngx-reactome-style brings it here.
To try a library change in the site before it is merged there, install a
packed build of it -- not npm link or a folder install: a symlinked library
resolves cytoscape from ngx-reactome-base's own node_modules, not this
repo's fork, and the build fails on mismatched types.
# in ngx-reactome-base
npx ng build ngx-reactome-cytoscape-style
(cd dist/ngx-reactome-cytoscape-style && npm pack --pack-destination /tmp)
# here
npm install --no-save /tmp/ngx-reactome-cytoscape-style-0.1.0.tgz
# and afterwards, back to the pinned build
npm install