Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
a9efef9
feat: add tsgo transpile path
johnnyreilly Jul 26, 2026
8aea9d4
fix: load tsgo API via ESM import
Copilot Jul 26, 2026
c91793d
Restrict execution-test TS matrix to tsgo version
Copilot Jul 26, 2026
e5d83a3
chore: explicitly use typescript@7.1.0-dev.20260725.1
johnnyreilly Jul 27, 2026
79969fe
Port build to TypeScript 7 native API
Copilot Jul 27, 2026
eb11d2a
fix: large
johnnyreilly Jul 27, 2026
ab27f47
fix native API execution test defaults
Copilot Jul 27, 2026
b1584f0
chore: remove test
johnnyreilly Jul 27, 2026
160cfbc
fix: remove unused
johnnyreilly Jul 27, 2026
8837e21
fix: happify ashley
johnnyreilly Jul 27, 2026
2f39b35
fix: use TS7 API in comparison test harness
Copilot Jul 27, 2026
b43cd7b
fix: getProgram
johnnyreilly Jul 27, 2026
3a95d01
feat: extra diagnostics
johnnyreilly Jul 27, 2026
1946462
feat: match existing formatting
johnnyreilly Jul 27, 2026
a53a6ae
chore: regenerate yarn.lock
johnnyreilly Jul 27, 2026
941b103
chore: remove happypack
johnnyreilly Jul 27, 2026
6308ac9
fix: aliasResolution
johnnyreilly Jul 27, 2026
5bc54c3
chore: bump version
johnnyreilly Jul 28, 2026
728126f
fix: colors
johnnyreilly Jul 28, 2026
4b4b502
fix: webpack 4
johnnyreilly Jul 28, 2026
0df23d5
chore: rename
johnnyreilly Jul 28, 2026
708516c
chore: remove unused
johnnyreilly Jul 28, 2026
3f74f96
fix: rootDir in tests
johnnyreilly Jul 28, 2026
e1e5451
fix: outputs
johnnyreilly Jul 28, 2026
23bd3c2
fix: declarationOutput
johnnyreilly Jul 28, 2026
6e60b89
fix: declaration tests
johnnyreilly Jul 28, 2026
1410354
fix: dependency
johnnyreilly Jul 28, 2026
d575ff2
fix: output
johnnyreilly Jul 28, 2026
a244231
fix: declarationWathc
johnnyreilly Jul 28, 2026
75806f2
chore: upgrade prettier
johnnyreilly Jul 28, 2026
3e65ec3
fix: reportFiels
johnnyreilly Jul 28, 2026
1addd9c
fix: test
johnnyreilly Jul 28, 2026
b3c69dc
fix: onlyCompileBundledFiles
johnnyreilly Jul 28, 2026
f4a084e
fix: style
johnnyreilly Jul 28, 2026
37ab093
fix: otherLoadersWatch
johnnyreilly Jul 28, 2026
6478b96
feat: settings.json
johnnyreilly Jul 28, 2026
d950c34
fix: output
johnnyreilly Jul 28, 2026
8772ce2
chore: add setings
johnnyreilly Jul 28, 2026
40c615b
fix: resolveJsonModule
johnnyreilly Jul 28, 2026
7c2cd2f
fix: tsconfileInvalid
johnnyreilly Jul 28, 2026
a748617
fix: tsconfileInvalidFile
johnnyreilly Jul 28, 2026
8a31a57
revert last fix
johnnyreilly Jul 28, 2026
3d820e7
Comment out DIAGNOSTIC_CODE_FILE_NOT_FOUND constant
johnnyreilly Jul 29, 2026
369662d
chore: skip test
johnnyreilly Jul 29, 2026
fd26794
fix: yarn comparison-tests --single-test nodeModulesMeaningfulErrorWh…
johnnyreilly Jul 29, 2026
ed48b6c
fix: output
johnnyreilly Jul 29, 2026
99cd5ab
chore: temp files better
johnnyreilly Jul 29, 2026
12a5727
feat: virtual file system
johnnyreilly Jul 29, 2026
146ab6f
fix: sourceMapsShouldConsiderInputSourceMap
johnnyreilly Jul 29, 2026
24b68eb
fix: allow spike rm
johnnyreilly Jul 29, 2026
a0c7665
fix: Windows comparison-test failures in the tsgo API backend
johnnyreilly Jul 29, 2026
9ee491e
Merge branch 'main' into copilot/implement-new-tsgo-api-support
johnnyreilly Jul 29, 2026
d1f2c8a
docs: edit AGENTS.md / deps for sourceMaps test / time
johnnyreilly Jul 30, 2026
e328ca6
Merge branch 'copilot/implement-new-tsgo-api-support' of https://gith…
johnnyreilly Jul 30, 2026
d3f88f5
refactor: remove unverified Windows-fix leftovers proven unnecessary …
johnnyreilly Jul 30, 2026
20ecf52
chore: "target": "es2022"
johnnyreilly Jul 30, 2026
17931f7
feat: chalk -> picocolors
johnnyreilly Jul 30, 2026
41c3f49
feat: picocolors -> styleText
johnnyreilly Jul 30, 2026
0872890
fix: test
johnnyreilly Jul 30, 2026
cb1445a
fix: eslint -> oxlint
johnnyreilly Jul 30, 2026
fc38c61
feat: styleText -> picocolors
johnnyreilly Jul 30, 2026
0a18cb1
chore: clean unused
johnnyreilly Aug 1, 2026
543d282
chore: knip / upgrade deps
johnnyreilly Aug 3, 2026
280927f
fix: execution tests
johnnyreilly Aug 3, 2026
166991b
chore: remove experimentalWatchApi references
johnnyreilly Aug 3, 2026
3824fc0
chore: remove experimentalWatchApi tests
johnnyreilly Aug 5, 2026
9a48632
chore: remove reference to watchapi in tests
johnnyreilly Aug 5, 2026
3012754
fix: loader options hash
johnnyreilly Aug 5, 2026
841d4f2
fix: loader options hash
johnnyreilly Aug 5, 2026
569b4f6
fix: loader options hash
johnnyreilly Aug 5, 2026
65850bb
chore: update to latest nightly
johnnyreilly Aug 20, 2026
b3973b6
chore: upgrade lint-staged
johnnyreilly Aug 20, 2026
58d7682
feat: transpileApi
johnnyreilly Aug 20, 2026
5987326
fix: normalize transpileModule/transpileDeclaration fileName for Windows
johnnyreilly Aug 20, 2026
183c948
fix: transpileDeclaration panics on Windows given an absolute fileName
johnnyreilly Aug 20, 2026
55c582a
docs: reduce comment verbosity - needs another pass
johnnyreilly Aug 29, 2026
88ac1bc
chore: remove workarounds no longer required since https://github.com…
johnnyreilly Aug 29, 2026
40e9a06
chore: function expressions to function declarations
johnnyreilly Aug 29, 2026
57b5b56
feat: knip
johnnyreilly Aug 29, 2026
d729ab0
refactor: use API-provided startPosition/endPosition instead of a man…
johnnyreilly Aug 29, 2026
f755256
fix: knip / simplify execution tests
johnnyreilly Aug 29, 2026
8e4ece2
fix: tests
johnnyreilly Aug 29, 2026
40c23fd
fix: dont alias types
johnnyreilly Aug 29, 2026
1bd5e2a
chore: trim comments
johnnyreilly Aug 29, 2026
d75642f
refactor: simplify logger
johnnyreilly Aug 29, 2026
837cf94
refactor: simplify logger
johnnyreilly Aug 29, 2026
5c5af41
Change ColorFn type to an interface
johnnyreilly Aug 29, 2026
434f1e3
Fix type annotation in ColorFn interface
johnnyreilly Aug 29, 2026
a192e11
chore: onlyCompileBundledFiles/context removed as options
johnnyreilly Aug 30, 2026
29a65af
refactor: naming
johnnyreilly Aug 30, 2026
97d509e
feat: remove fs-extra
johnnyreilly Aug 30, 2026
23530be
feat: remove rimraf
johnnyreilly Aug 30, 2026
eb80012
feat: remove mkdirp
johnnyreilly Aug 30, 2026
ab167e7
chore: remove compilerOptions loader option
johnnyreilly Aug 30, 2026
82f8016
test: regenerate snapshots affected by compilerOptions harness defaul…
johnnyreilly Aug 30, 2026
dc790e2
docs: CHANGELOG
johnnyreilly Aug 30, 2026
b40a0c3
fix: resolve .mts/.cts relative imports for dependency tracking
johnnyreilly Aug 30, 2026
74c2eaa
perf: only force a full snapshot rescan once per build, not per file
johnnyreilly Aug 30, 2026
7aa9725
perf: memoize direct-import resolution across a build's dependant rec…
johnnyreilly Aug 30, 2026
b231e4f
fix: key directImportsCache by FilePathKey, not raw file name
johnnyreilly Aug 30, 2026
722be6a
refactor: naming
johnnyreilly Aug 30, 2026
b4d8ef6
perf: memoize the .d.ts dependency scan across a build
johnnyreilly Aug 30, 2026
45e6c97
refactor: names
johnnyreilly Aug 30, 2026
e628934
fix: cap orphan-file synthetic projects with LRU eviction
johnnyreilly Aug 30, 2026
348721c
fix: canonicalize configFilePath/syntheticConfig* via FilePath
johnnyreilly Aug 30, 2026
643ed05
refactor: rename
johnnyreilly Aug 30, 2026
be1aa69
refactor: names
johnnyreilly Aug 30, 2026
e077ba7
refactor: thread resolvedFilePathCache instead of storing it twice
johnnyreilly Aug 30, 2026
e306615
refactor: rename
johnnyreilly Aug 30, 2026
606b064
feat: split diagnostics
johnnyreilly Aug 30, 2026
b2c2053
feat: format
johnnyreilly Aug 30, 2026
3b497a5
Merge branch 'main' of https://github.com/TypeStrong/ts-loader into c…
johnnyreilly Sep 1, 2026
aeef357
fix: benchmark close issue
johnnyreilly Sep 1, 2026
beaaaf7
fix: bound benchmark scenario wall-clock time to fit CI's job timeout
johnnyreilly Sep 1, 2026
0f8b8d4
perf: batch transitive-dependant recheck to once per build, not once …
johnnyreilly Sep 2, 2026
ac72bcb
chore: newer TypeScript version
johnnyreilly Sep 2, 2026
6a7b6f0
feat: perf optimisations
johnnyreilly Sep 2, 2026
2ab2522
feat: perf tweaks
johnnyreilly Sep 2, 2026
e4dffcb
Merge branch 'main' of https://github.com/TypeStrong/ts-loader into c…
johnnyreilly Sep 2, 2026
a497b81
fix: format
johnnyreilly Sep 2, 2026
804677b
chore: optimisations
johnnyreilly Sep 2, 2026
485d360
Merge branch 'main' of https://github.com/TypeStrong/ts-loader into c…
johnnyreilly Sep 2, 2026
5c0e923
fix: improve transpile by applying @andrewbranch's git diff from http…
johnnyreilly Sep 2, 2026
2ea9106
fix: typo
johnnyreilly Sep 2, 2026
5c79661
feat: have one base snapshot per total webpack build rather than one …
johnnyreilly Sep 3, 2026
2efb611
docs: cleanup unused
johnnyreilly Sep 19, 2026
8a5ae38
feat: migrate to new snapshot API from https://github.com/microsoft/T…
johnnyreilly Sep 19, 2026
eb9f8fb
fix: resolve two Windows/virtual-file panics in the new snapshot API
johnnyreilly Sep 21, 2026
f596acd
chore: add standalone repro for the "no project found for opened file…
johnnyreilly Sep 22, 2026
7422cd7
fix: canonicalize openFiles/fileNotifications casing to match openPro…
johnnyreilly Sep 23, 2026
626abe3
fix: upgrade typescript nightly and fix fallout on all platforms
johnnyreilly Oct 2, 2026
ebd98d6
Merge branch 'main' of https://github.com/TypeStrong/ts-loader into c…
johnnyreilly Oct 4, 2026
33fb225
fix: format
johnnyreilly Oct 4, 2026
d43f13a
chore: execution tests on mac
johnnyreilly Oct 4, 2026
9b85c6d
chore: lose unstable as mentioned in https://github.com/microsoft/Typ…
johnnyreilly Oct 10, 2026
02cdb1a
fix: can do prerelease
johnnyreilly Oct 10, 2026
c74e88c
docs: README
johnnyreilly Oct 10, 2026
45fc2cb
fix: logger not respecting option
johnnyreilly Oct 10, 2026
43736ef
fix: typescript version
johnnyreilly Oct 10, 2026
1e7369e
chore: version upgrade
johnnyreilly Oct 16, 2026
d260ed1
fix: lockfile churn
johnnyreilly Oct 16, 2026
b8b9bab
Merge branch 'main' into copilot/implement-new-tsgo-api-support
johnnyreilly Oct 16, 2026
60699b2
Merge remote-tracking branch 'origin/main' into copilot/implement-new…
johnnyreilly Oct 16, 2026
e761f46
chore: upgrade to 7.1.0-beta
johnnyreilly Oct 20, 2026
6639a9d
feat: newImportedFileWatch test
johnnyreilly Oct 21, 2026
f423480
refactor: use createPrograms for orphan files instead of synthetic ts…
johnnyreilly Oct 21, 2026
aea29d5
fix: don't export SyntheticProgram (knip)
johnnyreilly Oct 21, 2026
f7ad9ac
refactor: layer webpack-supplied content into the snapshot instead of…
johnnyreilly Oct 21, 2026
98f5094
docs: add an example
johnnyreilly Oct 21, 2026
6a5da4d
docs: README and CHANGELOG fixes for 7.1.0-beta
johnnyreilly Oct 21, 2026
99a450f
fix: detect filesystem case sensitivity and pass it to the API
johnnyreilly Oct 21, 2026
141bc0f
docs: point README at examples/simple and drop links to removed examples
johnnyreilly Oct 21, 2026
1d09475
docs: describe project references support accurately for v10
johnnyreilly Oct 21, 2026
11b19ee
test: fail watch tests promptly and support deleting files in patches
johnnyreilly Oct 21, 2026
e3d7012
fix: recheck dependants of deleted and re-created files in watch mode
johnnyreilly Oct 21, 2026
8e5ec26
fix: send real-cased paths to the TypeScript API
johnnyreilly Oct 21, 2026
d159d32
fix: evict synthetic programs in a request of their own
johnnyreilly Oct 21, 2026
add2615
perf: share one synthetic program across all orphan files
johnnyreilly Oct 21, 2026
5415d07
test: add orphanDependantWatch comparison test
johnnyreilly Oct 21, 2026
70f3507
Update CHANGELOG with details on unsupported features
johnnyreilly Oct 22, 2026
049a29a
Update README to remove v10 upgrade notes
johnnyreilly Oct 22, 2026
2358fe9
docs: improve README
johnnyreilly Oct 22, 2026
a6edcbc
chore: prepare 10.0.0-beta.0 release
johnnyreilly Oct 22, 2026
6d52b07
fix: report diagnostics for unbundled project files and drop stale ones
johnnyreilly Oct 22, 2026
98b1d22
fix: resolve import dependencies with the native module resolver
johnnyreilly Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 38 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"permissions": {
"defaultMode": "dontAsk",
"allow": [
"Edit",
"Write",
"Bash(rm -rf .spike-tmp*)",
"Bash(npm run build *)",
"Bash(npm run lint *)",
"Bash(npm run format *)",
"Bash(npm test *)",
"Bash(npm run comparison-tests *)",
"Bash(npm run execution-tests *)",
"Bash(npm run clean *)",
"Bash(npm install *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git stash *)",
"Bash(git checkout *)",
"Bash(git clean *)",
"Bash(npm ls *)",
"Bash(npm view *)",
"Bash(npm root *)",
"Bash(npm config *)",
"Bash(node *)",
"Bash(node_modules/.bin/tsc *)",
"Bash(npx tsc *)",
"Bash(npx mocha *)",
"Bash(grep *)",
"Read(//usr/local/lib/node_modules/**)",
"Bash(rm -rf .test)",
"Bash(FORCE_COLOR=1 node node_modules/mocha/bin/_mocha test/comparison-tests/create-and-execute-test.js --reporter spec --test-to-run * --timeout 25000)",
"Bash(node node_modules/mocha/bin/_mocha test/comparison-tests/create-and-execute-test.js --reporter spec --test-to-run * --timeout 25000)",
"Bash(echo \"PID $!\")"
]
}
}
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint",
"oxc.oxc-vscode",
"esbenp.prettier-vscode"
],

Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.ts eol=lf
*.js eol=lf
*.vue eol=lf

test/** linguist-detectable=false
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ jobs:
lint:
name: lint
uses: ./.github/workflows/lint.yml

format:
name: format
uses: ./.github/workflows/format.yml

knip:
name: knip
uses: ./.github/workflows/knip.yml
50 changes: 25 additions & 25 deletions .github/workflows/execution-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
node: [26, 24, 22]
ts: [5.7.2, 5.8.2, 5.9.2, 6.0.2] # next excluded for now
ts: [7.1.0-beta, next]
webpack: [4, 5]
runs-on: ubuntu-latest
steps:
Expand All @@ -33,41 +33,41 @@ jobs:
- name: test
run: npm run execution-tests

# execution_test_macos:
# name: macOS
# strategy:
# matrix:
# node: [26, 24, 22]
# ts: [5.7.2, 5.8.2, 5.9.2, 6.0.2] # next excluded for now
# webpack: [4, 5]
# runs-on: macos-latest
# steps:
# - uses: actions/checkout@v7
execution_test_macos:
name: macOS
strategy:
matrix:
node: [26, 24, 22]
ts: [7.1.0-beta, next]
webpack: [4, 5]
runs-on: macos-latest
steps:
- uses: actions/checkout@v7

# - name: install node
# uses: actions/setup-node@v7
# with:
# node-version: ${{ matrix.node }}
# cache: npm
- name: install node
uses: actions/setup-node@v7
with:
node-version: ${{ matrix.node }}
cache: npm

# - uses: ./.github/actions/build-ts-loader
- uses: ./.github/actions/build-ts-loader

# - name: install typescript
# run: npm install -D typescript@${{ matrix.ts }}
- name: install typescript
run: npm install -D typescript@${{ matrix.ts }}

# - name: install webpack 4
# if: matrix.webpack == 4
# run: npm install -D webpack@^4.47.0 karma-webpack@^4.0.2
- name: install webpack 4
if: matrix.webpack == 4
run: npm install -D webpack@^4.47.0 karma-webpack@^4.0.2

# - name: test
# run: npm run execution-tests
- name: test
run: npm run execution-tests

execution_test_windows:
name: windows
strategy:
matrix:
node: [26, 24, 22]
ts: [5.7.2, 5.8.2, 5.9.2, 6.0.2] # next excluded for now
ts: [7.1.0-beta, next]
webpack: [4, 5]
runs-on: windows-latest
steps:
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: format

on:
workflow_call:

jobs:
format:
name: format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm

- name: install
run: npm ci

- name: format:check
run: npm run format:check
22 changes: 22 additions & 0 deletions .github/workflows/knip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: knip

on:
workflow_call:

jobs:
knip:
name: knip
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm

- name: install
run: npm ci

- name: knip
run: npm run knip
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ jobs:

- run: npm install -g npm@latest

- run: npm publish
# Pre-releases go to the `next` dist-tag so they never become `latest`
- run: npm publish ${{ github.event.release.prerelease && '--tag next' || '' }}
env:
NPM_CONFIG_PROVENANCE: true
# NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} no longer needed with trusted publishing and OIDC token generation
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ npm-debug.log
/**/node_modules
/dist
/test/execution-tests/**/dist
/**/.happypack
/**/.cache-loader
!build.js
/**/debug.log
.pnp
.pnp.js
!.eslintrc.js
.vs/**
.pnpm-store
.pnpm-store
.DS_Store
dist
30 changes: 30 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "unicorn", "oxc"],
"categories": {
"correctness": "error"
},
"options": {
"typeAware": true,
"typeCheck": true
},
"rules": {
"typescript/unbound-method": "off",
"typescript/consistent-type-imports": "error",
"no-unused-vars": [
"error",
{
"args": "all",
"argsIgnorePattern": "^_",
"caughtErrors": "all",
"caughtErrorsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
]
},
"env": {
"builtin": true
}
}
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"oxc.oxc-vscode",
"esbenp.prettier-vscode"
]
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"sed": true,
"npm": true,
"git check-ignore": true
}
},
"editor.formatOnSave": true
}
51 changes: 45 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,31 @@ ts-loader is a TypeScript loader for webpack, enabling webpack to compile `.ts`

Use `npm` (not yarn or pnpm).

## Style

Prefer function declarations for named functions, especially reusable helpers. Use `function name(...) {}` instead of `const name = (...) => {}` when the function needs a name, as this is generally preferred for readability and consistency.

Prefer `interface` over `type` for object shapes when possible, as interfaces have better performance and tooling support in TypeScript.

## Comments

Keep comments in `src/` sparse: only the non-obvious _why_ (a Windows-only path quirk, an undocumented API behavior, a deliberate divergence from classic ts-loader's output) earns one, and it should be as short as it can be while still saying that. Don't add a comment that restates what a well-named identifier or the code's own shape already makes clear. Before trimming or removing an existing comment, weigh what it would cost to rediscover - some encode a hard-won finding (a repro script, a real Windows CI failure) that isn't obvious from the code alone; when in doubt, shorten rather than delete. `src/typeScriptApi.ts` is the densest file by necessity (most of ts-loader's TypeScript-API-specific behavior lives there); see "Testing on Windows CI" below for its most common recurring gotcha.

## Key commands

Note: test scripts clean test directories first using `git clean -xfd`.

```bash
npm run build # compile src/ → dist/ (tsc --project "./src")
npm run lint # type-check + ESLint (no separate typecheck script)
npm run lint # type-check + oxlint (no separate typecheck script)
npm test # full test suite (comparison + execution tests)
npm run comparison-tests # fast subset: compare webpack output against snapshots
npm run execution-tests # run compiled code via Karma/Jasmine
npm run benchmark # compare this build's compile speed against another ts-loader checkout
```

To run a single test:

```bash
npm run comparison-tests -- --single-test <testName>
npm run execution-tests -- --single-test <testName> --watch
Expand Down Expand Up @@ -52,7 +63,7 @@ Three separate jobs (`probe_ubuntu`/`probe_macos`/`probe_windows`), each gated b

Requires `gh` CLI authenticated with the `workflow` scope (`gh auth login`, then `gh auth refresh -s workflow` if `gh auth status` doesn't already list `workflow` — both scopes need a human to complete the browser device-flow prompt, they can't be scripted).

````bash
```bash
# trigger — omit single_test/match_test to run the full comparison-test suite;
# omit os (or pass os=all) to run on every platform
gh workflow run test-probe.yml --repo TypeStrong/ts-loader \
Expand All @@ -68,7 +79,7 @@ gh run watch <run-id> --repo TypeStrong/ts-loader --exit-status # blocks until
gh run view <run-id> --repo TypeStrong/ts-loader --json status,conclusion

gh run view <run-id> --repo TypeStrong/ts-loader --log-failed # full failure log text
````
```

## Execution tests (`test/execution-tests/`)

Expand All @@ -79,9 +90,12 @@ Full docs: [`test/execution-tests/README.md`](test/execution-tests/README.md)
Tests prefixed with a TypeScript version (e.g. `2.0.3_es2016`) are skipped when the installed TypeScript is older than that prefix.

Every `webpack.config.js` in this pack must include this alias so the local ts-loader is resolved:

```js
// for test harness purposes only
module.exports.resolveLoader = { alias: { 'ts-loader': path.join(__dirname, "../../../index.js") } }
module.exports.resolveLoader = {
alias: { 'ts-loader': path.join(__dirname, '../../../index.js') },
};
```

```bash
Expand All @@ -90,9 +104,34 @@ npm run execution-tests -- --single-test <name> # one test
npm run execution-tests -- --single-test <name> --watch # watch mode (open http://localhost:9876/)
```

## Testing on Windows CI

macOS/Linux passing locally does **not** mean Windows passes — this codebase has repeatedly had Windows-only comparison-test failures with no macOS/Linux equivalent. The recurring root cause: `src/typeScriptApi.ts` calls into the TypeScript API (`typescript/sync`), whose `program.getSourceFileNames()`/`getConfigFileNames()`/internal lookups return forward-slash-normalized paths on every OS (the long-standing TS compiler convention), while Node's own `path.resolve`/`path.join`/`path.normalize` return OS-native (backslash on Windows) paths. Any place that builds a path with Node's `path` module and then compares it against, or hands it to, something expecting the API's own spelling — a `Set`/`Map` keyed by API-returned names, or webpack's `addDependency`/`addBuildDependency` (which rejects non-native absolute paths) — silently breaks on Windows only. When investigating a new Windows-only failure, check for this pattern first (search for `path.resolve`/`path.join`/`path.normalize` near any `program.get*`/`toComparablePath` usage in `src/typeScriptApi.ts`).

### Windows test probe workflow

`.github/workflows/windows-test-probe.yml` (registered on `main`, so dispatchable against any branch/ref) runs just the Windows comparison tests via `workflow_dispatch` — much faster than the full `push.yml` matrix (which also runs the Ubuntu suite and the full Node/TS/webpack execution-test matrix). Use it to iterate on Windows-only failures without asking a human to relay CI output.

Requires `gh` CLI authenticated with the `workflow` scope (`gh auth login`, then `gh auth refresh -s workflow` if `gh auth status` doesn't already list `workflow` — both scopes need a human to complete the browser device-flow prompt, they can't be scripted).

````bash
# trigger — omit both inputs to run the full comparison-test suite
gh workflow run windows-test-probe.yml --repo TypeStrong/ts-loader \
--ref <branch> -f single_test=<name> # one test
gh workflow run windows-test-probe.yml --repo TypeStrong/ts-loader \
--ref <branch> -f match_test='^(testA|testB)$' # several, by regex

# the trigger command prints the run URL directly - grab the numeric id from it, then:
gh run watch <run-id> --repo TypeStrong/ts-loader --exit-status # blocks until done

# `gh run watch` can itself fail on a transient network blip even when the run
# succeeded - always verify conclusion this way rather than trusting its exit code
gh run view <run-id> --repo TypeStrong/ts-loader --json status,conclusion

gh run view <run-id> --repo TypeStrong/ts-loader --log-failed # full failure log text
## Benchmark tests (`test/benchmark-tests/`)

Answers "did this get faster or slower?", not "is the output correct?" - the comparison/execution packs never record timing, so this is a separate harness. It generates a synthetic project on the fly and times ts-loader compiling it (cold build, and incremental rebuild after touching a low-fan-out vs. high-fan-out file, under both `transpileOnly: true`/`false`), comparing two ts-loader checkouts (this build vs. another, e.g. `main`), each in its own process but run concurrently so host noise hits both sides equally and the relative numbers stay meaningful on noisy CI hosts.
Answers "did this get faster or slower?", not "is the output correct?" - the comparison/execution packs never record timing, so this is a separate harness. It generates a synthetic project on the fly and times ts-loader compiling it (cold build, and incremental rebuild after touching a low-fan-out vs. high-fan-out file, under both `transpileOnly: true`/`false`, plus a cold build and high-fan-out rebuild of an all-orphan-files variant), comparing two ts-loader checkouts (this build vs. another, e.g. `main`), each in its own process but run concurrently so host noise hits both sides equally and the relative numbers stay meaningful on noisy CI hosts.

Full docs: [`test/benchmark-tests/README.md`](test/benchmark-tests/README.md)

Expand All @@ -101,6 +140,6 @@ Full docs: [`test/benchmark-tests/README.md`](test/benchmark-tests/README.md)
```bash
npm run benchmark -- --root-a . --root-b . # sanity check against itself, expect ~0% deltas
npm run benchmark -- --root-a . --root-b ../ts-loader-main # compare against another built checkout
```
````

Always add or update tests when fixing bugs or adding features — see [CONTRIBUTING.md](CONTRIBUTING.md).
Loading
Loading