Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet!
- Load compatible plugins sequentially to work around race conditions in Node.js ([#412](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/412))

## [0.7.1] - 2025-10-17

Expand Down
50 changes: 25 additions & 25 deletions src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@ async function loadBuiltinPlugins(): Promise<PluginDetails> {
}

async function loadThirdPartyPlugins(): Promise<PluginDetails> {
let [astro, liquid, marko, twig, hermes, oxc, pug, svelte] = await Promise.all([
loadIfExistsESM('prettier-plugin-astro'),
loadIfExistsESM('@shopify/prettier-plugin-liquid'),
loadIfExistsESM('prettier-plugin-marko'),
loadIfExistsESM('@zackad/prettier-plugin-twig'),
loadIfExistsESM('@prettier/plugin-hermes'),
loadIfExistsESM('@prettier/plugin-oxc'),
loadIfExistsESM('@prettier/plugin-pug'),
loadIfExistsESM('prettier-plugin-svelte'),
])
// These plugins *must* be loaded sequentially. Race conditions are possible
// when using await import(…), require(esm), and Promise.all(…).
let astro = await loadIfExistsESM('prettier-plugin-astro')
let liquid = await loadIfExistsESM('@shopify/prettier-plugin-liquid')
let marko = await loadIfExistsESM('prettier-plugin-marko')
let twig = await loadIfExistsESM('@zackad/prettier-plugin-twig')
let hermes = await loadIfExistsESM('@prettier/plugin-hermes')
let oxc = await loadIfExistsESM('@prettier/plugin-oxc')
let pug = await loadIfExistsESM('@prettier/plugin-pug')
let svelte = await loadIfExistsESM('prettier-plugin-svelte')

return {
parsers: {
Expand Down Expand Up @@ -181,19 +181,19 @@ async function loadCompatiblePlugins() {
'prettier-plugin-jsdoc',
]

// Load all the available compatible plugins up front
// These are wrapped in try/catch internally so failure doesn't cause issues
// Technically we're executing these plugins though
// Even if not enabled
// There is, unfortunately, no way around this currently
return await Promise.all(
plugins.map(async (name) => {
let mod = await loadIfExistsESM(name)

return {
name,
mod,
}
}),
)
let list: { name: string; mod: unknown }[] = []

// Load all the available compatible plugins up front. These are wrapped in
// try/catch internally so failure doesn't cause issues.
//
// We're always executing these plugins even if they're not enabled. Sadly,
// there is no way around this currently.
//
// These plugins *must* be loaded sequentially. Race conditions are possible
// when using await import(…), require(esm), and Promise.all(…).
for (let name of plugins) {
list.push({ name, mod: await loadIfExistsESM(name) })
}

return list
}