Files
wehub-resource-sync f1ba9c6c36
/ test (push) Failing after 1s
/ build-and-push-to-ghcr (push) Has been skipped
chore: import upstream snapshot with attribution
2026-07-13 12:23:39 +08:00

133 lines
7.1 KiB
Markdown

# Contributing to Reader
Thanks for your interest in contributing. This is the open source branch of the codebase that runs at `https://r.jina.ai` and `https://s.jina.ai`. The MongoDB-backed SaaS storage layer is not part of this branch — local development uses the stateless / bucket-cached modes only.
If you're not sure where to start, take a look at [architecture.md](./architecture.md) first.
## Local development
### Requirements
- **Node.js 22+** — earlier versions will not build.
- **Docker** *(optional)* — only needed if you want to run the bucket-cached storage mode against a local MinIO. Pure stateless mode needs nothing extra.
- **LibreOffice** *(optional)* — only needed if you want to test MS Office document handling locally.
### First-time setup
```bash
git clone git@github.com:jina-ai/reader.git
cd reader
npm install
# Optional: only if you want the local bucket cache
docker compose up -d
```
`docker compose up -d` starts:
| Service | Port(s) | Purpose |
| ------- | -------------- | ------------------------------------------------------------------ |
| `minio` | `9000`, `9001` | S3-compatible object storage for cached pages. Console on `:9001`. |
### Running the server
In VSCode, press `F5` to launch the debugger.
Or, after exporting the environment variables (see below):
```bash
docker compose up -d
npm run dev
```
### Useful scripts
- `npm run build` — TypeScript compile (also runs an integrity check).
- `npm run build:watch` — incremental build.
- `npm run start` — run the compiled `crawl` entrypoint.
- `npm run dry-run` — run `search.js` with `NODE_ENV=dry-run` to resolve the DI graph and exit. Used to warm `NODE_COMPILE_CACHE` in the Dockerfile.
- `npm run lint` — ESLint over `.js` / `.ts`.
## Environment variables
Reader picks up configuration from environment variables. The most relevant ones for local development are:
### Storage & data
| Variable | Notes |
| -------------------------- | ------------------------------------------------------------------------------------- |
| `GCP_STORAGE_ENDPOINT` | Object storage endpoint (use the local MinIO endpoint for dev). Enables Stage 1 bucket-cached mode. |
| `GCP_STORAGE_BUCKET` | Bucket name for cached objects. |
| `GCP_STORAGE_ACCESS_KEY` | MinIO root user locally. |
| `GCP_STORAGE_SECRET_KEY` | MinIO root password locally. |
| `GCP_STORAGE_REGION` | Optional; for parity with GCS. |
| `GCLOUD_PROJECT` | Alternative trigger for the bucket layer when combined with `GCP_STORAGE_ENDPOINT`. |
| `CACHE_LOCAL_STORAGE_ROOT` | Filesystem root for local cache (alternative to object storage in stateless modes). |
### Vendors & integrations
| Variable | Purpose |
| ------------------------------------------------- | -------------------------------------------------------------------- |
| `JINA_SERP_API_KEY` / `JINA_SERP_API_ORIGIN` | Jina SERP backend. |
| `JINA_SERP_API_POLICY` | SERP routing policy. |
| `SERPER_SEARCH_API_KEY` | serper.dev search backend. |
| `THORDATA_PROXY_URL` / `THORDATA_PROXY_URL_ALT` | Thordata residential proxy. |
| `THORDATA_SERP_API_KEY` | Thordata SERP API. |
| `BRIGHTDATA_PROXY_URL` / `BRIGHTDATA_ISP_PROXY_URL` / `BRIGHTDATA_SERP_API_KEY` | BrightData proxy + SERP. |
| `CLOUD_FLARE_API_KEY` | Required for the `cf-browser-rendering` engine. |
| `STRIPE_SECRET_KEY` / `STRIPE_WEBHOOK_KEY` | Billing integration. |
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `OPENROUTER_API_KEY` / `GOOGLE_AI_STUDIO_API_KEY` / `REPLICATE_API_KEY` | LLM/VLM access. |
### Overrides & toggles
| Variable | Purpose |
| --------------------------------- | ------------------------------------------------------------------ |
| `PORT` | HTTP port. |
| `NODE_ENV` | `dry-run` is recognized for offline `search` runs. |
| `DEBUG_BROWSER` | Run headless Chrome with non-headless / debug behavior. |
| `OVERRIDE_CHROME_EXECUTABLE_PATH` | Use a specific Chrome binary instead of the bundled Puppeteer one. |
| `OVERRIDE_JINA_VLM_URL` | Point at a different VLM endpoint. |
| `OVERRIDE_READERLM_V` | Switch between ReaderLM versions. |
| `OVERRIDE_GOOGLE_DOMAIN` / `OVERRIDE_BING_DOMAIN` | Use a regional search domain. |
| `OVERRIDE_MANAGE_SERVER_URL` | Redirect calls to the management server. |
| `JINA_BOGO_SITES_RESORT_ORIGIN` | Origin for the bogo-sites resort list. |
| `JINA_CRAWLER_OFFLOAD_ORIGIN` | Offload crawler traffic to a peer cluster. |
| `PREFERRED_PROXY_COUNTRY` | Hint for proxy country selection. |
| `SLACK_REPORT_WEBHOOK_URL` | Slack channel for runtime reports. |
### `SECRETS_COMBINED`
You can pass a base64-encoded JSON object via `SECRETS_COMBINED` to bundle multiple variables into one. See `src/services/envconfig.ts`.
## Tests
The repo uses the Node.js built-in test runner (no Jest, no Vitest).
```bash
npm run test:unit # unit tests
npm run test:e2e # end-to-end tests (slower, hits docker services)
npm test # both
npm run test:unit:coverage
npm run test:e2e:coverage
npm run test:coverage # combined coverage report (c8)
```
Tests are written in TypeScript under `tests/` and compiled into `tests-build/` before running. The test entrypoints are `tests-build/run-unit.js` and `tests-build/run.js`.
## Submitting changes
1. Open an issue first if the change is non-trivial — it saves churn for both sides.
2. Keep PRs focused. A bug fix and a refactor in the same PR are harder to review and revert.
3. Run `npm run lint` and `npm test` before pushing.
4. Reference the issue in the PR description if one exists.
## Reporting issues
Bug reports are most useful when they include:
- The exact URL (for `r.jina.ai`) or query (for `s.jina.ai`).
- The request headers in use, especially any `x-*` overrides.
- The expected vs actual output.
Open an issue on GitHub and we'll take a look.