readest/apps/readest-app/vitest.config.mts
Huang Xin 5d030abf32
fix(build): repair the Docker and Nix builds after #6368 (#6379)
* fix(build): repair the Docker and Nix builds after #6368

Two main-branch builds broke on 8750c310 and both are fallout from that PR.

**Docker** (`pnpm build-web`: "Can't resolve '@pdfjs/pdf.min.mjs'",
"Can't resolve '@simplecc/simplecc_wasm'"). `setup-vendors` runs in the
`dependencies` stage and its output is not in the build context, so every
directory it creates needs an explicit `COPY --from=dependencies`. Splitting
the bundler-imported modules out of `public/vendor` into `vendor/` left the
new directory with no COPY line. The test derives the expected roots from the
`prepare-vendor` script, so adding another one fails until the Dockerfile
copies it.

**Nix** ("no matching package named `sentry-debug-images` found"). The Linux
CEF build vendors from `Cargo.cef.lock`, which `nix/package.nix` copies over
`Cargo.lock`, and that second lock never learned about the two crates the
sentry `debug-images` feature pulls in. Added `findshlibs` and
`sentry-debug-images` there, plus the dependency entry on `sentry`; both need
only packages the lock already had.

This is also why `nix-deps-check` stayed green on #6368: it hashes
`Cargo.cef.lock`, which that PR did not touch, so the stale vendor set only
surfaced when the full Nix build ran on main.

`cargoHash` is updated in a follow-up commit from the hash the deps-check
prints, since the vendor contents change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style: format the vendor-root docker test

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(nix): update cargoHash for the new sentry debug-images crates

The vendor set gained findshlibs and sentry-debug-images, so the pinned
hash moved. Value taken from the nix-deps-check run on this PR:

  specified: sha256-EPNbiv0YJ79rqBHFCO5gjQwt9Vn1v9HV0ZfH7f2Eo/E=
  got:       sha256-8MIkn2N65P87tG0RncOQtH01SYfRUM4qB6rOzd+fwwQ=

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: one vendor dir, with the bundler importing from packages

#6368 split the vendored modules into a second `vendor/` directory to stop
them shipping twice (Tauri embeds every published file, and `public/` is
published whole). Two vendor directories is the wrong shape, and the copies
were never needed: the aliases can resolve straight at the sources, which is
how `jieba-wasm` has always been imported.

  @pdfjs/*    -> packages/foliate-js/node_modules/pdfjs-dist/legacy/build/*
  @simplecc/* -> packages/simplecc-wasm/dist/web/*

`public/vendor/pdfjs` now holds only what the reader fetches by URL at
runtime — the worker, the WASM decoders, cmaps, standard fonts and the layer
CSS — and `vendor/` is gone, along with `copy-pdfjs-lib`, `copy-simplecc`,
`setup-simplecc`, its Dockerfile COPY and its worktree copy.

Two details this turned up:

- The @pdfjs alias needs an explicit `declare module`. TypeScript inferred
  types for the minified JS while it sat inside the app, but skips JavaScript
  under node_modules, and pdfjs-dist ships `pdf.d.mts`, not the
  `pdf.min.d.mts` that would sit beside the minified build. Only the import's
  side effect is used, so the declaration is bare.
- `packages/simplecc-wasm` is a submodule the worktree script skips, so the
  script now copies its committed `dist/web` into a new worktree instead of a
  vendor directory.

A true `import ... from 'simplecc-wasm'`, matching jieba exactly, would need a
change in that submodule: its `exports` map points at `pkg/`, which is build
output and not committed (only `dist/web` is), and the map forbids other
subpaths.

Verified with a real build: modules resolve with no `vendor/` present,
`out/vendor` holds only pdfjs, `pdf.min.mjs` is bundled into a chunk and not
published, and both jieba and simplecc WASM are emitted once each.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: say why the @pdfjs alias points at the package, not public/

The comments still described a vendored copy. Record the constraint
instead: a module the bundler imports must not also be published, or
Tauri embeds it twice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: drop the vendor/docker config assertions

These assert on config files rather than behaviour: the alias-target test,
the Dockerfile vendor-COPY test, and the pdfjs wasm copy-script test.

The SELF_HOSTED default check in docker-image-defaults.test.ts stays; it
predates this work (#6100) and guards runtime behaviour of the published
image rather than a config shape.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 15:13:35 +02:00

52 lines
1.9 KiB
TypeScript

import path from 'path';
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [tsconfigPaths(), react()],
resolve: {
alias: {
// The @pdfjs alias from tsconfig only resolves within the app's own
// source files. foliate-js/pdf.js lives outside that scope, so Vite
// needs an explicit alias to reach pdfjs-dist. It points at the real
// package rather than a copy under `public/`: a module the bundler
// imports must not be published too, or Tauri embeds it twice (#6368).
'@pdfjs': path.resolve(__dirname, '../../packages/foliate-js/node_modules/pdfjs-dist/legacy/build'),
// `js-mdict` is consumed via tsconfig paths from `packages/js-mdict/src/`.
// Its sources `import 'fflate'` directly — without an alias, vite's
// import-analysis walks up from the redirected file location and fails
// to find fflate (it's installed only in this app's node_modules).
// Pin all `fflate` resolutions to the app's copy to keep js-mdict
// self-contained at the source-tree level.
fflate: path.resolve(__dirname, 'node_modules/fflate'),
},
},
test: {
environment: 'jsdom',
silent: 'passed-only',
setupFiles: ['./vitest.setup.ts'],
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/.claude/**',
// Playwright web e2e specs — run via `pnpm test:e2e:web`, not vitest.
'**/e2e/**',
'**/*.browser.test.ts',
'**/*.browser.test.tsx',
'**/*.tauri.test.ts',
// Android device e2e — run via `pnpm test:android`, not the unit lane.
'**/*.android.test.ts',
],
coverage: {
provider: 'v8',
reporter: ['text', 'text-summary'],
include: ['src/**/*.{ts,tsx}'],
exclude: [
'src/**/*.d.ts',
'src/**/__tests__/**',
'src/**/test/**',
],
},
},
});