build: move web/ from pnpm to npm

Replace pnpm-lock.yaml with package-lock.json and drop pnpm-workspace.yaml.
The three security overrides move to package.json#overrides, which npm reads
natively; allowBuilds for esbuild is unnecessary because npm runs dependency
build scripts by default.

android/build:web drove the web build through corepack pnpm, so it would have
broken once web/pnpm-lock.yaml was gone. It now uses npm --prefix.

Fresh resolution picks up patched versions the old lockfile had pinned below,
so npm audit reports no advisories where pnpm audit reported eight.
This commit is contained in:
tiennm99 committed 2026-08-17 11:54:24 +07:00
1 parent 6dcbdbd51d
commit 1c1bab8733
13 files changed
+8660 -5537

No files matched your search

+4 -10
View File
@@ -1,24 +1,18 @@
name: Set up web toolchain
description: >
Installs pnpm and Node, then restores web/ dependencies from the lockfile.
Installs Node, then restores web/ dependencies from the lockfile.
Node stays in lockstep with .github/actions/setup-android so the SvelteKit
app is tested and bundled into the APK on the same runtime.
runs:
using: composite
steps:
# Must precede setup-node: `cache: pnpm` needs the pnpm binary to
# resolve the store path.
- uses: pnpm/action-setup@v6
with:
package_json_file: web/package.json
- uses: actions/setup-node@v7
with:
node-version: '24'
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
cache: npm
cache-dependency-path: web/package-lock.json
- run: pnpm install --frozen-lockfile
- run: npm ci
shell: bash
working-directory: web
+2 -2
View File
@@ -28,12 +28,12 @@ jobs:
# ci.yml does not run on tags, so this is the only gate before signing.
- name: Test web
run: pnpm test
run: npm test
working-directory: web
# Base "" — the APK loads the bundle from the domain root.
- name: Build web
run: pnpm build
run: npm run build
working-directory: web
- uses: ./.github/actions/setup-android
+2 -2
View File
@@ -44,7 +44,7 @@ jobs:
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
- run: pnpm test
- run: npm test
working-directory: web
build:
@@ -68,7 +68,7 @@ jobs:
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
- run: pnpm ${{ matrix.script }}
- run: npm run ${{ matrix.script }}
working-directory: web
- uses: actions/upload-artifact@v7
with:
+3 -3
View File
@@ -9,7 +9,7 @@ Live: [tiennm99.github.io/loto](https://tiennm99.github.io/loto)
| Path | What it is |
|------|------------|
| [`web/`](web) | SvelteKit static app — the game itself. pnpm, Vitest, deployed to GitHub Pages and Firebase Hosting. |
| [`web/`](web) | SvelteKit static app — the game itself. npm, Vitest, deployed to GitHub Pages and Firebase Hosting. |
| [`android/`](android) | Capacitor wrapper that bundles `web/build` into an APK. npm + Gradle; the native project sits in `android/android/`. |
`android/` builds `web/` as part of its own build, so a change under `web/`
@@ -20,7 +20,7 @@ pin between them — they ship from the same commit.
```bash
# web
cd web && pnpm install && pnpm dev
cd web && npm install && npm run dev
# android debug APK (builds web/ first)
cd android && npm ci && npm run build && npm run assemble:debug
@@ -44,7 +44,7 @@ only the tag-driven release stands apart.
consumer downloads the artifact rather than rebuilding it:
```
test (pnpm test)
test (npm test)
└── build (root, base "") ── deploy-firebase push to main
│ ├─ preview-firebase PR from this repo
│ └─ android-debug unsigned APK artifact
+1 -1
View File
@@ -14,7 +14,7 @@ time. No network is required at runtime.
```
../web/
└── pnpm run build → ../web/build/ (SvelteKit static output)
└── npm run build → ../web/build/ (SvelteKit static output)
↓
npx cap sync
↓
+1 -1
View File
@@ -4,7 +4,7 @@
"private": true,
"description": "Capacitor wrapper that bundles the web/ app into a fully-offline Android APK.",
"scripts": {
"build:web": "corepack pnpm@11.1.1 --dir ../web install --frozen-lockfile && corepack pnpm@11.1.1 --dir ../web run build",
"build:web": "npm --prefix ../web ci && npm --prefix ../web run build",
"sync": "cap sync android",
"build": "npm run build:web && npm run sync",
"open": "cap open android",
+11 -11
View File
@@ -30,7 +30,7 @@ app into a fully-offline APK.
## Requirements
[Node.js](https://nodejs.org) 18+ and [pnpm](https://pnpm.io).
[Node.js](https://nodejs.org) 18+ and npm.
---
@@ -39,8 +39,8 @@ app into a fully-offline APK.
```sh
git clone https://github.com/tiennm99/loto
cd loto
pnpm install
pnpm dev # dev server at http://localhost:5173
npm install
npm run dev # dev server at http://localhost:5173
```
---
@@ -49,12 +49,12 @@ pnpm dev # dev server at http://localhost:5173
| Command | Description |
|---|---|
| `pnpm dev` | Start development server |
| `pnpm build` | Production build (root base path) |
| `pnpm build:gh` | Production build for GitHub Pages (`/loto` base path) |
| `pnpm preview` | Preview production build locally |
| `pnpm test` | Run unit tests |
| `pnpm lint` | ESLint check |
| `npm run dev` | Start development server |
| `npm run build` | Production build (root base path) |
| `npm run build:gh` | Production build for GitHub Pages (`/loto` base path) |
| `npm run preview` | Preview production build locally |
| `npm test` | Run unit tests |
| `npm run lint` | ESLint check |
---
@@ -67,7 +67,7 @@ Copy `.env.example` to `.env.local` and set:
| `CODESERVER_HOST` | Hostname for code-server reverse-proxy dev (optional) |
| `CODESERVER_PORT` | Port for code-server proxy (optional) |
When running inside code-server use `pnpm dev:codeserver` and open
When running inside code-server use `npm run dev:codeserver` and open
`https://<CODESERVER_HOST>/absproxy/<CODESERVER_PORT>/` (use `/absproxy/`, not
`/proxy/` — the latter strips the path prefix and breaks SvelteKit routing).
@@ -119,7 +119,7 @@ The script auto-discovers all available `vi-*` voices and writes an updated mani
## Deployment
Deployed to GitHub Pages by the `deploy-pages` job in
`.github/workflows/ci.yml` on push to `main`. Build command: `pnpm build:gh`
`.github/workflows/ci.yml` on push to `main`. Build command: `npm run build:gh`
(sets `/loto` base path). Static output in `build/`.
The same workflow also deploys the base-`""` build to Firebase Hosting and
+2 -2
View File
@@ -50,8 +50,8 @@
| `svelte.config.js` | adapter-static (HTML export), dual basePath via BUILD_PROFILE env, SvelteKit PWA plugin config. |
| `vite.config.js` | Tailwind + SvelteKit + PWA plugins. codeserver HMR config (port, allowedHosts, hmr). |
| `package.json` | SvelteKit 2, Svelte 5 (runes), Tailwind 4, Vite, @vite-pwa/sveltekit. Scripts: dev, dev:codeserver, build, build:gh, lint, test, test:watch. |
| `.github/workflows/ci.yml` | Repo-root pipeline for push/PR. `test` (`pnpm test`) gates a two-profile `build` matrix; the artifacts feed `deploy-pages` (canonical, `https://tiennm99.github.io/loto/`), `deploy-firebase`, `preview-firebase`, and `android-debug`. |
| `.github/actions/setup-web/` | Composite action: pnpm + Node 24 + `pnpm install --frozen-lockfile` in `web/`. Shared by `ci.yml` and `android-release.yml`. |
| `.github/workflows/ci.yml` | Repo-root pipeline for push/PR. `test` (`npm test`) gates a two-profile `build` matrix; the artifacts feed `deploy-pages` (canonical, `https://tiennm99.github.io/loto/`), `deploy-firebase`, `preview-firebase`, and `android-debug`. |
| `.github/actions/setup-web/` | Composite action: Node 24 + `npm ci` in `web/`. Shared by `ci.yml` and `android-release.yml`. |
| `eslint.config.mjs` | ESLint 9 flat config (@eslint/js + eslint-plugin-svelte). Declares Svelte 5 rune globals. |
| `jsconfig.json` | Path alias `$lib`, no checkJs. |
| `.gitignore` | Excludes node_modules, build, .env.local, etc. |
+3 -3
View File
@@ -17,7 +17,7 @@ either profile without code changes.
Canonical deploy. Wired via the `deploy-pages` job in
`.github/workflows/ci.yml`: on push to `main`, the `build (gh)` job runs
`pnpm build:gh` and uploads `build/`; `deploy-pages` downloads that artifact
`npm run build:gh` and uploads `build/`; `deploy-pages` downloads that artifact
and publishes it. Both are gated on the `test` job.
One-time setup (already done; documented for restoration):
@@ -137,10 +137,10 @@ Generates:
One workflow, `.github/workflows/ci.yml`, covers PRs and pushes to `main`:
- **`test`** — `pnpm test`. Every other job depends on it, so a red suite
- **`test`** — `npm test`. Every other job depends on it, so a red suite
blocks all deploys.
- **`build`** — a two-entry matrix producing the only two web builds in the
run: `pnpm build` (base `""`, artifact `web-build`) and `pnpm build:gh`
run: `npm run build` (base `""`, artifact `web-build`) and `npm run build:gh`
(base `/loto`, artifact `web-build-gh`).
- **`deploy-pages`** — canonical deploy; publishes `web-build-gh`.
- **`deploy-firebase`** / **`preview-firebase`** — Firebase live channel on
+8631
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1,7 +1,6 @@
{
"name": "loto",
"version": "0.1.0",
"packageManager": "pnpm@11.1.1",
"private": true,
"type": "module",
"scripts": {
-5494
View File
File diff suppressed because it is too large. Load diff
-7
View File
@@ -1,7 +0,0 @@
overrides:
serialize-javascript: ^7.0.5
cookie: ^0.7.2
ws: ^8.20.1
allowBuilds:
esbuild: true