Skip to content

Commit 3997fbd

Browse files
authored
Use explicit import() expressions in plugin load arrays for bundler compatibility (#450)
1 parent 125a8bc commit 3997fbd

File tree

4 files changed

+115
-42
lines changed

4 files changed

+115
-42
lines changed

knip.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"ignore": ["src/**/*.d.ts", "tests/fixtures/**"],
66
"ignoreDependencies": [
77
"@ianvs/prettier-plugin-sort-imports",
8+
"@prettier/plugin-oxc",
89
"@prettier/plugin-hermes",
910
"@prettier/plugin-pug",
1011
"@shopify/prettier-plugin-liquid",

src/create-plugin.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import { isAbsolute } from 'path'
12
import type { Parser, ParserOptions, Plugin, Printer } from 'prettier'
23
import { getTailwindConfig } from './config'
34
import { createMatcher } from './options'
45
import { loadIfExists, maybeResolve } from './resolve'
5-
import type { TransformOptions } from './transform'
6+
import type { PluginLoad, TransformOptions } from './transform'
67
import type { TransformerEnv } from './types'
7-
import { isAbsolute } from 'path'
88

99
export function createPlugin(transforms: TransformOptions<any>[]) {
1010
// Prettier parsers and printers may be async functions at definition time.
@@ -142,8 +142,6 @@ function createPrinter({
142142
return printer
143143
}
144144

145-
type PluginLoad = string | Plugin<any>
146-
147145
async function loadPlugins<T>(fns: PluginLoad[]) {
148146
let plugin: Plugin<T> = {
149147
parsers: Object.create(null),
@@ -153,8 +151,8 @@ async function loadPlugins<T>(fns: PluginLoad[]) {
153151
languages: [],
154152
}
155153

156-
for (let moduleName of fns) {
157-
let loaded = typeof moduleName === 'string' ? await loadIfExistsESM(moduleName) : moduleName
154+
for (let source of fns) {
155+
let loaded = await loadPlugin(source)
158156
Object.assign(plugin.parsers!, loaded.parsers ?? {})
159157
Object.assign(plugin.printers!, loaded.printers ?? {})
160158
Object.assign(plugin.options!, loaded.options ?? {})
@@ -166,39 +164,50 @@ async function loadPlugins<T>(fns: PluginLoad[]) {
166164
return plugin
167165
}
168166

169-
async function loadIfExistsESM(name: string): Promise<Plugin<any>> {
170-
let mod = await loadIfExists<Plugin<any>>(name)
167+
const EMPTY_PLUGIN: Plugin<any> = {
168+
parsers: {},
169+
printers: {},
170+
languages: [],
171+
options: {},
172+
defaultOptions: {},
173+
}
171174

172-
return (
173-
mod ?? {
174-
parsers: {},
175-
printers: {},
176-
languages: [],
177-
options: {},
178-
defaultOptions: {},
179-
}
180-
)
175+
async function loadPlugin(source: PluginLoad): Promise<Plugin<any>> {
176+
if ('importer' in source && typeof source.importer === 'function') {
177+
return normalizePlugin(await source.importer())
178+
}
179+
180+
return source
181181
}
182182

183-
function findEnabledPlugin(options: ParserOptions<any>, name: string) {
183+
function normalizePlugin(source: unknown): Plugin<any> {
184+
if (source === null || typeof source !== 'object') return EMPTY_PLUGIN
185+
let maybeModule = source as { default?: unknown }
186+
let plugin = maybeModule.default
187+
return (plugin && typeof plugin === 'object' ? plugin : source) as Plugin<any>
188+
}
184189

190+
function findEnabledPlugin(options: ParserOptions<any>, name: string) {
185191
for (let plugin of options.plugins) {
186192
if (plugin instanceof URL) {
187193
if (plugin.protocol !== 'file:') continue
188194
if (plugin.hostname !== '') continue
189195

190196
plugin = plugin.pathname
191-
} if (typeof plugin !== 'string') {
197+
}
198+
199+
if (typeof plugin !== 'string') {
192200
if (!plugin.name) {
193201
continue
194202
}
195203
plugin = plugin.name
196204
}
197205

198-
199-
if (plugin === name || (isAbsolute(plugin) && plugin.includes(name) && maybeResolve(name) === plugin)) {
200-
return loadIfExistsESM(name)
201-
206+
if (
207+
plugin === name ||
208+
(isAbsolute(plugin) && plugin.includes(name) && maybeResolve(name) === plugin)
209+
) {
210+
return loadIfExists<Plugin<any>>(name)
202211
}
203212
}
204213
}

src/index.ts

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ function transformDynamicJsAttribute(attr: any, env: TransformerEnv) {
106106
)
107107
}
108108

109-
function addChange(start: number | null | undefined, end: number | null | undefined, after: string) {
109+
function addChange(
110+
start: number | null | undefined,
111+
end: number | null | undefined,
112+
after: string,
113+
) {
110114
if (start == null || end == null) return
111115

112116
let offsetStart = start - expressionPrefix.length
@@ -1038,7 +1042,7 @@ type HtmlNode =
10381042
let html = defineTransform<HtmlNode>({
10391043
staticAttrs: ['class'],
10401044

1041-
load: ['prettier/plugins/html'],
1045+
load: [{ name: 'prettier/plugins/html', importer: () => import('prettier/plugins/html') }],
10421046
compatible: ['prettier-plugin-organize-attributes'],
10431047

10441048
parsers: {
@@ -1060,7 +1064,7 @@ type GlimmerNode =
10601064

10611065
let glimmer = defineTransform<GlimmerNode>({
10621066
staticAttrs: ['class'],
1063-
load: ['prettier/plugins/glimmer'],
1067+
load: [{ name: 'prettier/plugins/glimmer', importer: () => import('prettier/plugins/glimmer') }],
10641068

10651069
parsers: {
10661070
glimmer: {},
@@ -1110,15 +1114,46 @@ let js = defineTransform<import('@babel/types').Node>({
11101114
'babel-flow': { load: [prettierParserBabel] },
11111115
'babel-ts': { load: [prettierParserBabel] },
11121116
__js_expression: { load: [prettierParserBabel] },
1113-
typescript: { load: ['prettier/plugins/typescript'] },
1114-
meriyah: { load: ['prettier/plugins/meriyah'] },
1115-
acorn: { load: ['prettier/plugins/acorn'] },
1116-
flow: { load: ['prettier/plugins/flow'] },
1117-
oxc: { load: ['@prettier/plugin-oxc'] },
1118-
'oxc-ts': { load: ['@prettier/plugin-oxc'] },
1119-
hermes: { load: ['@prettier/plugin-hermes'] },
1117+
typescript: {
1118+
load: [
1119+
{
1120+
name: 'prettier/plugins/typescript',
1121+
importer: () => import('prettier/plugins/typescript'),
1122+
},
1123+
],
1124+
},
1125+
meriyah: {
1126+
load: [
1127+
{ name: 'prettier/plugins/meriyah', importer: () => import('prettier/plugins/meriyah') },
1128+
],
1129+
},
1130+
acorn: {
1131+
load: [{ name: 'prettier/plugins/acorn', importer: () => import('prettier/plugins/acorn') }],
1132+
},
1133+
flow: {
1134+
load: [{ name: 'prettier/plugins/flow', importer: () => import('prettier/plugins/flow') }],
1135+
},
1136+
oxc: {
1137+
load: [{ name: '@prettier/plugin-oxc', importer: () => import('@prettier/plugin-oxc') }],
1138+
},
1139+
'oxc-ts': {
1140+
load: [{ name: '@prettier/plugin-oxc', importer: () => import('@prettier/plugin-oxc') }],
1141+
},
1142+
hermes: {
1143+
load: [
1144+
{ name: '@prettier/plugin-hermes', importer: () => import('@prettier/plugin-hermes') },
1145+
],
1146+
},
11201147
astroExpressionParser: {
1121-
load: ['prettier-plugin-astro'],
1148+
load: [
1149+
{
1150+
name: 'prettier-plugin-astro',
1151+
importer: () => {
1152+
// @ts-expect-error - This plugin doesn't have types
1153+
return import('prettier-plugin-astro')
1154+
},
1155+
},
1156+
],
11221157
staticAttrs: ['class'],
11231158
dynamicAttrs: ['class:list'],
11241159
},
@@ -1133,7 +1168,7 @@ type SvelteNode = import('svelte/compiler').AST.SvelteNode & {
11331168

11341169
let svelte = defineTransform<SvelteNode>({
11351170
staticAttrs: ['class'],
1136-
load: ['prettier-plugin-svelte'],
1171+
load: [{ name: 'prettier-plugin-svelte', importer: () => import('prettier-plugin-svelte') }],
11371172

11381173
parsers: {
11391174
svelte: {},
@@ -1179,7 +1214,15 @@ type AstroNode =
11791214
let astro = defineTransform<AstroNode>({
11801215
staticAttrs: ['class', 'className'],
11811216
dynamicAttrs: ['class:list', 'className'],
1182-
load: ['prettier-plugin-astro'],
1217+
load: [
1218+
{
1219+
name: 'prettier-plugin-astro',
1220+
importer: () => {
1221+
// @ts-expect-error - This plugin doesn't have types
1222+
return import('prettier-plugin-astro')
1223+
},
1224+
},
1225+
],
11831226

11841227
parsers: {
11851228
astro: {},
@@ -1192,7 +1235,7 @@ type MarkoNode = import('@marko/compiler').types.Node
11921235

11931236
let marko = defineTransform<MarkoNode>({
11941237
staticAttrs: ['class'],
1195-
load: ['prettier-plugin-marko'],
1238+
load: [{ name: 'prettier-plugin-marko', importer: () => import('prettier-plugin-marko') }],
11961239

11971240
parsers: {
11981241
marko: {},
@@ -1224,7 +1267,15 @@ type TwigNode =
12241267

12251268
let twig = defineTransform<TwigNode>({
12261269
staticAttrs: ['class'],
1227-
load: ['@zackad/prettier-plugin-twig'],
1270+
load: [
1271+
{
1272+
name: '@zackad/prettier-plugin-twig',
1273+
importer: () => {
1274+
// @ts-expect-error - This plugin doesn't have types
1275+
return import('@zackad/prettier-plugin-twig')
1276+
},
1277+
},
1278+
],
12281279

12291280
parsers: {
12301281
twig: {},
@@ -1240,7 +1291,7 @@ interface PugNode {
12401291

12411292
let pug = defineTransform<PugNode>({
12421293
staticAttrs: ['class'],
1243-
load: ['@prettier/plugin-pug'],
1294+
load: [{ name: '@prettier/plugin-pug', importer: () => import('@prettier/plugin-pug') }],
12441295

12451296
parsers: {
12461297
pug: {},
@@ -1259,7 +1310,12 @@ type LiquidNode =
12591310

12601311
let liquid = defineTransform<LiquidNode>({
12611312
staticAttrs: ['class'],
1262-
load: ['@shopify/prettier-plugin-liquid'],
1313+
load: [
1314+
{
1315+
name: '@shopify/prettier-plugin-liquid',
1316+
importer: () => import('@shopify/prettier-plugin-liquid'),
1317+
},
1318+
],
12631319

12641320
parsers: { 'liquid-html': {} },
12651321

src/transform.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ export function defineTransform<T>(opts: TransformOptions<T>) {
55
return opts
66
}
77

8+
export interface LazyPluginLoad {
9+
name: string
10+
importer: () => Promise<unknown>
11+
}
12+
13+
export type PluginLoad = LazyPluginLoad | Plugin<any>
14+
815
export interface TransformOptions<T> {
916
/**
1017
* Static attributes that are supported by default
@@ -19,7 +26,7 @@ export interface TransformOptions<T> {
1926
/**
2027
* Load the given plugins for the parsers and printers
2128
*/
22-
load?: Array<string | Plugin<any>>
29+
load?: PluginLoad[]
2330

2431
/**
2532
* A list of compatible, third-party plugins for this transformation step
@@ -39,7 +46,7 @@ export interface TransformOptions<T> {
3946
/**
4047
* Load the given plugins for the parsers and printers
4148
*/
42-
load?: Array<string | Plugin<any>>
49+
load?: PluginLoad[]
4350

4451
/**
4552
* Static attributes that are supported by default

0 commit comments

Comments
 (0)