diff --git a/CHANGELOG.md b/CHANGELOG.md index f5ecc509c3c4..cf5ebd5fdb6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Remove deprecation warnings by using `Module#registerHooks` instead of `Module#register` on Node 26+ ([#20028](https://github.com/tailwindlabs/tailwindcss/pull/20028)) ## [4.3.0] - 2026-05-08 diff --git a/packages/@tailwindcss-node/src/esm-cache.loader.mts b/packages/@tailwindcss-node/src/esm-cache.loader.mts index edcfc8d778ba..952b2f189d94 100644 --- a/packages/@tailwindcss-node/src/esm-cache.loader.mts +++ b/packages/@tailwindcss-node/src/esm-cache.loader.mts @@ -1,8 +1,22 @@ -import { isBuiltin, type ResolveHook } from 'node:module' +import { + isBuiltin, + type ResolveFnOutput, + type ResolveHook, + type ResolveHookContext, + type ResolveHookSync, +} from 'node:module' export let resolve: ResolveHook = async (specifier, context, nextResolve) => { let result = await nextResolve(specifier, context) + return processResolve(context, result) +} + +export let resolveSync: ResolveHookSync = (specifier, context, nextResolve) => { + let result = nextResolve(specifier, context) + return processResolve(context, result) +} +function processResolve(context: ResolveHookContext, result: ResolveFnOutput) { if (result.url === import.meta.url) return result if (isBuiltin(result.url)) return result if (!context.parentURL) return result diff --git a/packages/@tailwindcss-node/src/index.cts b/packages/@tailwindcss-node/src/index.cts index 4bca0a5e11de..9f27889337d3 100644 --- a/packages/@tailwindcss-node/src/index.cts +++ b/packages/@tailwindcss-node/src/index.cts @@ -1,6 +1,7 @@ import * as Module from 'node:module' import { pathToFileURL } from 'node:url' import * as env from './env' +import { resolveSync } from './esm-cache.loader.mjs' export * from './compile' export * from './instrumentation' export * from './normalize-path' @@ -12,8 +13,14 @@ export { env } // not necessary. if (!process.versions.bun) { // `Module#register` was added in Node v18.19.0 and v20.6.0 + // `Module#registerHooks` was added in Node v22.15.0 and v23.5.0 and is the preferred API since v25.9.0, + // runtime-deprecating `Module#register` since v26 // // Not calling it means that while ESM dependencies don't get reloaded, the // actual included files will because they cache bust directly via `?id=…` - Module.register?.(pathToFileURL(require.resolve('@tailwindcss/node/esm-cache-loader'))) + if (Module.registerHooks) { + Module.registerHooks({ resolve: resolveSync }) + } else { + Module.register?.(pathToFileURL(require.resolve('@tailwindcss/node/esm-cache-loader'))) + } } diff --git a/packages/@tailwindcss-node/src/index.ts b/packages/@tailwindcss-node/src/index.ts index a5e7bf5b4bc3..22a62b248937 100644 --- a/packages/@tailwindcss-node/src/index.ts +++ b/packages/@tailwindcss-node/src/index.ts @@ -1,6 +1,7 @@ import * as Module from 'node:module' import { pathToFileURL } from 'node:url' import * as env from './env' +import { resolveSync } from './esm-cache.loader.mjs' export * from './compile' export * from './instrumentation' export * from './normalize-path' @@ -14,8 +15,14 @@ if (!process.versions.bun) { let localRequire = Module.createRequire(import.meta.url) // `Module#register` was added in Node v18.19.0 and v20.6.0 + // `Module#registerHooks` was added in Node v22.15.0 and v23.5.0 and is the preferred API since v25.9.0, + // runtime-deprecating `Module#register` since v26 // // Not calling it means that while ESM dependencies don't get reloaded, the // actual included files will because they cache bust directly via `?id=…` - Module.register?.(pathToFileURL(localRequire.resolve('@tailwindcss/node/esm-cache-loader'))) + if (Module.registerHooks) { + Module.registerHooks({ resolve: resolveSync }) + } else { + Module.register?.(pathToFileURL(localRequire.resolve('@tailwindcss/node/esm-cache-loader'))) + } }