Skip to content

Commit d56c4a0

Browse files
authored
Merge pull request #303 from knockout/modern-tooling/phase-1-bun
Replace Karma with Vitest, add Bun support
2 parents 5aa1833 + 46ae4b5 commit d56c4a0

80 files changed

Lines changed: 2700 additions & 18632 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/lint-and-typecheck.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
# Combined lint, format, and typecheck workflow.
2-
# Replaces separate eslint.yml, prettier.yml, and run-tsc.yml to avoid
3-
# running npm install three times.
42
name: Lint & Typecheck
53

64
on:
@@ -15,14 +13,11 @@ jobs:
1513
- name: Checkout code
1614
uses: actions/checkout@v6
1715

18-
- name: Setup Node.js
19-
uses: actions/setup-node@v6
20-
with:
21-
node-version: 22.x
22-
cache: 'npm'
16+
- name: Setup Bun
17+
uses: oven-sh/setup-bun@v2
2318

2419
- name: Install dependencies
25-
run: npm install
20+
run: bun install --frozen-lockfile
2621

2722
- name: Check Prettier
2823
run: make format
@@ -34,4 +29,4 @@ jobs:
3429
run: make
3530

3631
- name: Typecheck
37-
run: npx tsc
32+
run: bunx tsc

.github/workflows/main-build.yml

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,37 @@
22
name: Build
33

44
on:
5-
# Runs on pushes targeting the default branch
65
push:
76
branches: ["main"]
8-
# Allows you to run this workflow manually from the Actions tab
97
workflow_dispatch:
108

119
jobs:
1210
test:
1311
runs-on: ubuntu-latest
14-
15-
strategy:
16-
matrix:
17-
node-version: [24.x]
12+
container:
13+
image: mcr.microsoft.com/playwright:v1.59.1-noble
1814

1915
steps:
2016
- name: Checkout code
2117
uses: actions/checkout@v6
2218

23-
- name: Setup Node.js
24-
uses: actions/setup-node@v6
25-
with:
26-
node-version: ${{ matrix.node-version }}
27-
cache: 'npm'
19+
- name: Install system dependencies
20+
run: apt-get update && apt-get install -y unzip make
2821

29-
- name: Install dependencies
30-
run: npm install
22+
- name: Setup Bun
23+
uses: oven-sh/setup-bun@v2
3124

32-
- name: Audit for vulnerabilities (prod-mode)
33-
run: npm audit --audit-level=high --production
25+
- name: Install dependencies
26+
run: bun install --frozen-lockfile
3427

3528
- name: Run Build
3629
run: make
3730

3831
- name: Run tests
39-
run: make test-headless
32+
run: bunx vitest run
33+
env:
34+
HOME: /root
35+
VITEST_BROWSERS: chromium,firefox,webkit
4036

4137
- name: Upload build artifacts
4238
uses: actions/upload-artifact@v7

.github/workflows/publish-check.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ jobs:
1414
- name: Checkout code
1515
uses: actions/checkout@v6
1616

17+
- name: Setup Bun
18+
uses: oven-sh/setup-bun@v2
19+
1720
- name: Setup Node.js
1821
uses: actions/setup-node@v6
1922
with:
20-
node-version: 22.x
21-
cache: 'npm'
23+
node-version: 24.x
2224

2325
- name: Install dependencies
24-
run: npm install
26+
run: bun install --frozen-lockfile
2527

2628
- name: Build all packages
2729
run: make

.github/workflows/test-headless.yml

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,33 @@
22
name: Check Tests
33

44
on:
5-
# Runs for every pull-requests created
65
pull_request:
7-
# Allows you to run this workflow manually from the Actions tab
86
workflow_dispatch:
97

108
jobs:
11-
testheadless:
9+
test:
1210
runs-on: ubuntu-latest
13-
14-
strategy:
15-
matrix:
16-
node-version: [24]
17-
run: ['test-headless','test-headless-jquery', 'test-headless-ff']
11+
container:
12+
image: mcr.microsoft.com/playwright:v1.59.1-noble
1813

1914
steps:
2015
- name: Checkout code
2116
uses: actions/checkout@v6
2217

23-
- name: Setup Node.js
24-
uses: actions/setup-node@v6
25-
with:
26-
node-version: ${{ matrix.node-version }}
27-
cache: 'npm'
18+
- name: Install system dependencies
19+
run: apt-get update && apt-get install -y unzip make
20+
21+
- name: Setup Bun
22+
uses: oven-sh/setup-bun@v2
2823

2924
- name: Install dependencies
30-
run: npm install
25+
run: bun install --frozen-lockfile
3126

3227
- name: Run Build
3328
run: make
3429

35-
- name: Run ${{ matrix.run }}
36-
run: make ${{ matrix.run }}
30+
- name: Run Tests
31+
run: bunx vitest run
32+
env:
33+
HOME: /root
34+
VITEST_BROWSERS: chromium,firefox,webkit

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ builds/**/meta
3434
.vscode/settings.json
3535
.playwright-mcp
3636
.playwright-cli
37+
__screenshots__

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bun 1.3.12

.vscode/launch.json

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
{
2-
// Use IntelliSense to learn about possible attributes.
3-
// Hover to view descriptions of existing attributes.
4-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
52
"version": "0.2.0",
63
"configurations": [
74
{
85
"type": "chrome",
96
"request": "attach",
10-
"name": "Attach to Karma-Chrome",
11-
"sourceMaps": true,
12-
// "restart": true,
13-
// "timeout":180000,
14-
"port": 9222,
7+
"name": "Attach to Vitest Browser",
8+
"sourceMaps": true,
9+
"port": 9222,
1510
"webRoot": "${workspaceFolder}"
1611
}
1712
]
18-
}
13+
}

AGENTS.md

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Lerna monorepo with npm workspaces. Current version: see `lerna.json`.
5151
```
5252
packages/ # 25 modular @tko/* packages (all TypeScript)
5353
builds/ # 2 bundled distributions (knockout, reference)
54-
tools/ # Shared build config (build.mk, karma.conf.js, repackage.mjs)
54+
tools/ # Shared build config (build.mk, repackage.mjs)
5555
skills/ # AI agent skills (on-demand workflow instructions)
5656
tko.io/ # Documentation site (Astro + Starlight, deployed to GitHub Pages)
5757
Makefile # Top-level build orchestrator
@@ -63,25 +63,26 @@ Key packages: `@tko/observable`, `@tko/computed`, `@tko/bind`,
6363
Builds: `@tko/build.knockout` (backwards-compatible) and
6464
`@tko/build.reference` (modern/recommended).
6565

66+
## Prerequisites
67+
68+
- **Bun** — package manager and script runner. Install via [mise](https://mise.jdx.dev/): `mise install` (reads `.tool-versions`), or [bun.sh](https://bun.sh).
69+
- Use `bun install` instead of `npm install`.
70+
6671
## Build Commands
6772

6873
All builds use Make + esbuild. Run from the repo root:
6974

7075
```bash
71-
npm install # Install all dependencies (uses npm workspaces)
76+
bun install # Install all dependencies (uses Bun workspaces)
7277
make # Build all packages (ESM, CommonJS, MJS)
73-
make test # Run all tests with Electron
74-
make test-headless # Run all tests with headless Chrome
75-
make test-headless-ff # Run all tests with headless Firefox
76-
make test-headless-jquery # Run tests with jQuery enabled
77-
make test-coverage # Run tests and generate coverage report
78+
make test # Run all tests (Vitest, headless Chromium via Playwright)
79+
bunx vitest run # Same as make test, directly
7880
make eslint # Run ESLint
7981
make eslint-fix # Run ESLint with auto-fix
8082
make format # Check Prettier formatting
8183
make format-fix # Fix Prettier formatting
8284
make tsc # TypeScript type-check (no emit)
8385
make dts # Generate TypeScript declaration files
84-
make knip # Run Knip for Linting imports and exports
8586
make sweep # Clean dist/ and coverage/ dirs
8687
make clean # Full clean (node_modules, lockfiles, dist)
8788
```
@@ -91,17 +92,14 @@ Make targets (they include `tools/build.mk`).
9192

9293
## Testing
9394

94-
- **Runner**: Karma
95-
- **Frameworks**: Mocha + Chai + Sinon
96-
- **Browsers**: Electron (default), Chrome Headless, Firefox Headless
97-
- **Coverage**: nyc/Istanbul (~89% statements, ~83% branches)
98-
- **Test files**: `packages/*/spec/` directories
99-
100-
Use Mocha/Chai/Sinon for repository tests.
95+
- **Runner**: Vitest browser mode (Playwright, headless Chromium)
96+
- **Assertions**: Chai (expect) + Sinon (spies/stubs/timers)
97+
- **Config**: `vitest.config.ts` at repo root
98+
- **Test files**: `packages/*/spec/**/*.ts`, `builds/*/spec/**/*.js`
99+
- **Run**: `bunx vitest run` (all tests) or `bunx vitest run <path>` (single file)
101100

102-
Do not:
103-
- split shared specs into runner-specific versions while they still need to run
104-
in the browser harness
101+
Tests run in a real browser via Playwright — not jsdom. This is required
102+
because TKO does low-level DOM manipulation, MutationObserver, and event handling.
105103

106104
## Code Style
107105

@@ -231,7 +229,7 @@ When validating `tko.io` documentation changes with the local docs site:
231229

232230
## Important Guidelines
233231

234-
- Do not modify `tools/build.mk` or `tools/karma.conf.js` without understanding
232+
- Do not modify `tools/build.mk` or `vitest.config.ts` without understanding
235233
the full impact — they are shared across all 25+ packages.
236234
- Do not add runtime dependencies to core packages. TKO is zero-dependency.
237235
- The `builds/` packages bundle everything into a single distributable.

AI_COMPLIANCE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ security-critical rule.
8484

8585
- `.github/workflows/`
8686
- `tools/build.mk`
87-
- `tools/karma.conf.js`
87+
- `vitest.config.ts`
8888
- release and publish controls (`.changeset/`, release scripts/workflows)
8989
- authentication/publishing and CI secret flow configuration
9090

Makefile

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
NPX := npx
2-
NODE := node
3-
NPM := npm
4-
LERNA := npx lerna
1+
BUNX := bunx
2+
LERNA := $(BUNX) lerna
53
DOCKER := docker
64

75
# Some make settings
@@ -15,50 +13,38 @@ default: all
1513

1614
package.json:
1715

18-
node_modules: package-lock.json
16+
node_modules: package.json bun.lock packages/*/package.json
17+
bun install
1918

20-
all:: node_modules package-lock.json
19+
all:: node_modules
2120
$(LERNA) --concurrency $(CONCURRENCY) exec --stream -- $(MAKE)
2221

23-
test:
24-
$(LERNA) exec --stream -- $(MAKE) test
25-
26-
test-headless:
27-
$(LERNA) exec --stream -- $(MAKE) test-headless
28-
29-
# Instrumentalization via CLI: $(LERNA) exec --stream -- $(NPX) instrument dist --in-place
30-
# We have done it with a Esbuild-Plugin in the karma.conf.js-file
31-
# To manually merge coverage files: $(NPX) nyc merge coverage ../../coverage-temp/coverage-final.json
32-
test-coverage:
33-
$(LERNA) exec --stream -- $(MAKE) test-coverage
34-
$(NPX) nyc report --reporter=html --reporter=text --reporter=cobertura --report-dir=coverage --temp-dir=coverage-temp --exclude="**/browser.min.js" --exclude="**/spec/*" > COVERAGE.md
35-
36-
test-headless-jquery:
37-
$(LERNA) exec --stream -- $(MAKE) test-headless-jquery
22+
test test-headless:
23+
$(BUNX) vitest run
3824

3925
test-headless-ff:
40-
$(LERNA) exec --stream -- $(MAKE) test-headless-ff
26+
VITEST_BROWSERS=firefox $(BUNX) vitest run
4127

42-
ci:
43-
$(LERNA) exec --stream --concurrency=1 -- $(MAKE) test-ci
28+
test-headless-jquery:
29+
VITEST_BROWSERS=chromium $(BUNX) vitest run
4430

4531
format:
46-
$(NPX) prettier . --check
32+
$(BUNX) prettier . --check
4733

4834
format-fix:
49-
$(NPX) prettier . --write
35+
$(BUNX) prettier . --write
5036

5137
tsc:
52-
$(NPX) tsc
38+
$(BUNX) tsc
5339

5440
eslint:
55-
$(NPX) eslint .
41+
$(BUNX) eslint .
5642

5743
eslint-fix:
58-
$(NPX) eslint . --fix
44+
$(BUNX) eslint . --fix
5945

6046
dts:
61-
$(NPX) tsc --build tsconfig.dts.json
47+
$(BUNX) tsc --build tsconfig.dts.json
6248

6349
docker-build:
6450
$(DOCKER) build . --tag tko
@@ -77,20 +63,18 @@ bump:
7763
publish-unpublished: all link
7864
$(LERNA) publish from-package
7965

80-
package-lock.json: package.json packages/*/package.json
81-
$(NPM) i
66+
bun.lock: package.json packages/*/package.json
67+
bun install
8268

8369
package.json:
8470

85-
install: node_modules
86-
8771
outdated-list:
88-
$(NPM) outdated
72+
bun outdated
8973

9074
outdated-upgrade:
91-
$(NPM) upgrade-interactive --latest
75+
bun upgrade-interactive --latest
9276

93-
install: package-lock.json
77+
install: bun.lock
9478

9579
sweep:
9680
rm -rf packages/*/dist/*
@@ -100,12 +84,9 @@ sweep:
10084

10185
clean: sweep
10286
rm -rf node_modules/
103-
rm -f package-lock.json
104-
rm -rf packages/*/package-lock.json
105-
rm -rf builds/*/package-lock.json
10687

10788

10889
# Local linking of these packages, so they
10990
# are available for local testing/dev.
11091
link:
111-
$(LERNA) exec --stream -- npm link
92+
$(LERNA) exec --stream -- bun link

0 commit comments

Comments
 (0)