Skip to content

Commit 3f370d6

Browse files
committed
refactor(oxfmt): Intro loadCached JS helper (oxc-project#21696)
Prepare for upcoming svelte+astro plugins.
1 parent 38d1e82 commit 3f370d6

1 file changed

Lines changed: 31 additions & 35 deletions

File tree

apps/oxfmt/src-js/libs/apis.ts

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,19 @@ const CACHES = {
2121
oxfmtPlugin: null as Plugin | null,
2222
};
2323

24+
async function loadCached<K extends keyof typeof CACHES>(
25+
key: K,
26+
loader: () => Promise<NonNullable<(typeof CACHES)[K]>>,
27+
): Promise<NonNullable<(typeof CACHES)[K]>> {
28+
CACHES[key] ??= await loader();
29+
return CACHES[key]!;
30+
}
31+
32+
// ---
33+
2434
async function loadPrettier(): Promise<typeof import("prettier")> {
25-
if (!CACHES.prettier) {
26-
CACHES.prettier = await import("prettier");
35+
return loadCached("prettier", async () => {
36+
const prettier = await import("prettier");
2737

2838
// NOTE: This is needed for xxx-in-js formatting to work correctly.
2939
//
@@ -37,7 +47,7 @@ async function loadPrettier(): Promise<typeof import("prettier")> {
3747
// In call sites, Prettier checks `if (!options.parentParser)`, so as long as the default is falsy,
3848
// there should be no side effects on other calls that don't set these fields.
3949
// @ts-expect-error: Use internal API
40-
const { formatOptionsHiddenDefaults } = CACHES.prettier.__internal;
50+
const { formatOptionsHiddenDefaults } = prettier.__internal;
4151
// For html(angular)-in-js: Prevent attribute level formatting from running.
4252
// (e.g., CSS in `style="..."` attributes, JS in `onclick="..."` event handlers)
4353
// This does NOT affect `<style>`/`<script>` tags, they are always formatted.
@@ -53,8 +63,9 @@ async function loadPrettier(): Promise<typeof import("prettier")> {
5363
formatOptionsHiddenDefaults.__onHtmlRoot = null;
5464
// For md-in-js: Use `~` instead of `` ` `` for code fences
5565
formatOptionsHiddenDefaults.__inJsTemplate = null;
56-
}
57-
return CACHES.prettier;
66+
67+
return prettier;
68+
});
5869
}
5970

6071
// ---
@@ -199,23 +210,17 @@ export async function formatEmbeddedDoc({
199210
// Tailwind CSS support
200211
// ---
201212

202-
async function loadTailwindPlugin(): Promise<typeof import("prettier-plugin-tailwindcss")> {
203-
if (!CACHES.tailwindPlugin) {
204-
CACHES.tailwindPlugin = await import("prettier-plugin-tailwindcss");
205-
}
206-
return CACHES.tailwindPlugin;
207-
}
208-
209-
// ---
210-
211213
/**
212214
* Load Tailwind CSS plugin.
213215
* Option mapping (sortTailwindcss.xxx → tailwindXxx) is also done in Rust side.
214216
*/
215217
async function setupTailwindPlugin(options: Options): Promise<void> {
216-
const tailwindPlugin = CACHES.tailwindPlugin ?? (await loadTailwindPlugin());
218+
CACHES.tailwindPlugin ??= await loadCached(
219+
"tailwindPlugin",
220+
() => import("prettier-plugin-tailwindcss"),
221+
);
217222
options.plugins ??= [];
218-
options.plugins.push(tailwindPlugin as Plugin);
223+
options.plugins.push(CACHES.tailwindPlugin as Plugin);
219224
}
220225

221226
// ---
@@ -231,13 +236,6 @@ export interface SortTailwindClassesArgs {
231236
};
232237
}
233238

234-
async function loadTailwindSorter() {
235-
if (!CACHES.tailwindSorter) {
236-
CACHES.tailwindSorter = await import("prettier-plugin-tailwindcss/sorter");
237-
}
238-
return CACHES.tailwindSorter;
239-
}
240-
241239
/**
242240
* Process Tailwind CSS classes found in JS/TS files in batch.
243241
* @param args - Object containing classes and options (filepath is in options.filepath)
@@ -247,7 +245,11 @@ export async function sortTailwindClasses({
247245
classes,
248246
options,
249247
}: SortTailwindClassesArgs): Promise<string[]> {
250-
const { createSorter } = CACHES.tailwindSorter ?? (await loadTailwindSorter());
248+
CACHES.tailwindSorter ??= await loadCached(
249+
"tailwindSorter",
250+
() => import("prettier-plugin-tailwindcss/sorter"),
251+
);
252+
const { createSorter } = CACHES.tailwindSorter;
251253

252254
const sorter = await createSorter({
253255
filepath: options.filepath,
@@ -264,20 +266,14 @@ export async function sortTailwindClasses({
264266
// Oxfmt plugin support for (j|t)-in-xxx files
265267
// ---
266268

267-
async function loadOxfmtPlugin(): Promise<Plugin> {
268-
if (!CACHES.oxfmtPlugin) {
269-
CACHES.oxfmtPlugin = (await import("./prettier-plugin-oxfmt/index")) as Plugin;
270-
}
271-
return CACHES.oxfmtPlugin;
272-
}
273-
274-
// ---
275-
276269
/**
277270
* Load oxfmt plugin for js-in-xxx parsers.
278271
*/
279272
async function setupOxfmtPlugin(options: Options): Promise<void> {
280-
const oxcPlugin = CACHES.oxfmtPlugin ?? (await loadOxfmtPlugin());
273+
CACHES.oxfmtPlugin ??= await loadCached(
274+
"oxfmtPlugin",
275+
async () => (await import("./prettier-plugin-oxfmt/index")) as Plugin,
276+
);
281277
options.plugins ??= [];
282-
options.plugins.push(oxcPlugin);
278+
options.plugins.push(CACHES.oxfmtPlugin);
283279
}

0 commit comments

Comments
 (0)