Skip to content

Commit 908f169

Browse files
Don’t use Promise.all when dynamically loading compatible plugins (#412)
* Don’t use `Promise.all` when waiting on dynamic imports * Update changelog
1 parent a0fea3f commit 908f169

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

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

1212
## [0.7.1] - 2025-10-17
1313

src/plugins.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,16 @@ async function loadBuiltinPlugins(): Promise<PluginDetails> {
131131
}
132132

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

145145
return {
146146
parsers: {
@@ -181,19 +181,19 @@ async function loadCompatiblePlugins() {
181181
'prettier-plugin-jsdoc',
182182
]
183183

184-
// Load all the available compatible plugins up front
185-
// These are wrapped in try/catch internally so failure doesn't cause issues
186-
// Technically we're executing these plugins though
187-
// Even if not enabled
188-
// There is, unfortunately, no way around this currently
189-
return await Promise.all(
190-
plugins.map(async (name) => {
191-
let mod = await loadIfExistsESM(name)
192-
193-
return {
194-
name,
195-
mod,
196-
}
197-
}),
198-
)
184+
let list: { name: string; mod: unknown }[] = []
185+
186+
// Load all the available compatible plugins up front. These are wrapped in
187+
// try/catch internally so failure doesn't cause issues.
188+
//
189+
// We're always executing these plugins even if they're not enabled. Sadly,
190+
// there is no way around this currently.
191+
//
192+
// These plugins *must* be loaded sequentially. Race conditions are possible
193+
// when using await import(…), require(esm), and Promise.all(…).
194+
for (let name of plugins) {
195+
list.push({ name, mod: await loadIfExistsESM(name) })
196+
}
197+
198+
return list
199199
}

0 commit comments

Comments
 (0)