Skip to content

Commit 352d1b9

Browse files
authored
Ensure Symbol.dispose and Symbol.asyncDispose are available (#15404)
We recently introduced some better instrumentation (#15303) which uses the new `using` keyword. I made sure that this was compiled correctly for environments where `using` is not available yet. The issue is that this also relies on `Symbol.dispose` being available. In my testing on our minimal required Node.js version (18) it did work fine. However, turns out that I was using `18.20.x` locally where `Symbol.dispose` **_is_** available, but on older version of Node.js 18 (e.g.: `18.17.x`) it is **_not_** available. This now results in some completely broken builds, e.g.: when running on Cloudflare Pages. See: #15399 I could reproduce this error in CI, by temporarily downgrading the used Node.js version to `18.17.0`. See: <img width="1142" alt="image" src="https://github.com/user-attachments/assets/5bf30f80-9ca0-40d9-ad02-d1ffb4e0e5dd" /> Implementing the proper polyfill, as recommended by the TypeScript docs ( see: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#:~:text=Symbol.dispose,-??=%20Symbol(%22Symbol.dispose ), the error goes away. (If you look at CI after the polyfill, it still fails but for different reasons unrelated to this change) Fixes: #15399 --- ## Test plan 1. I reproduced it in CI, and I kept the commits so that you can take a look where it fails with the `Object not disposable`. 2. Using the provided reproduction from #15399: ### Before It works on Node.js v18.20.x, but switching to Node.js v18.17.x you can see it fail: <img width="1607" alt="image" src="https://github.com/user-attachments/assets/cb6ab73a-8eb2-4003-bab7-b2390f1c879d" /> ### After Using pnpm's overrides, we can apply the fix from this PR and test it in the reproduction. You'll notice that it now works in both Node.js v18.20.x and v18.17.x <img width="1604" alt="image" src="https://github.com/user-attachments/assets/b3a65557-0658-4cb0-a2f9-e3079c7936d5" />
1 parent a39d036 commit 352d1b9

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Fixed
11+
12+
- Ensure `Symbol.dispose` and `Symbol.asyncDispose` are polyfilled ([#15404](https://github.com/tailwindlabs/tailwindcss/pull/15404))
1113

1214
## [4.0.0-beta.7] - 2024-12-13
1315

@@ -763,3 +765,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
763765
- Move the CLI into a separate `@tailwindcss/cli` package ([#13095](https://github.com/tailwindlabs/tailwindcss/pull/13095))
764766

765767
## [4.0.0-alpha.1] - 2024-03-06
768+

packages/@tailwindcss-node/src/instrumentation.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
import { DefaultMap } from '../../tailwindcss/src/utils/default-map'
22
import * as env from './env'
33

4+
// See: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#:~:text=Symbol.dispose,-??=%20Symbol(%22Symbol.dispose
5+
// @ts-expect-error — Ensure Symbol.dispose exists
6+
Symbol.dispose ??= Symbol('Symbol.dispose')
7+
// @ts-expect-error — Ensure Symbol.asyncDispose exists
8+
Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose')
9+
410
export class Instrumentation implements Disposable {
511
#hits = new DefaultMap(() => ({ value: 0 }))
612
#timers = new DefaultMap(() => ({ value: 0n }))
713
#timerStack: { id: string; label: string; namespace: string; value: bigint }[] = []
814

9-
constructor(private defaultFlush = (message: string) => process.stderr.write(`${message}\n`)) {}
15+
constructor(
16+
private defaultFlush = (message: string) => void process.stderr.write(`${message}\n`),
17+
) {}
1018

1119
hit(label: string) {
1220
this.#hits.get(label).value++

0 commit comments

Comments
 (0)