nksaraf / vinxi

The Full Stack JavaScript SDK
https://vinxi.vercel.app
MIT License
1.85k stars 74 forks source link

No way to add plugins that run before internal plugins #383

Open samualtnorman opened 2 days ago

samualtnorman commented 2 days ago

This means Vinxi projects cannot properly integrate other languages like Civet or plugins that need to run on the original source code like babel-plugin-here.

I did some digging into the source code and found 2 places where the order of the plugins is hardcoded. For vinxi build it's here:

https://github.com/nksaraf/vinxi/blob/93d236ae005185143adab17b59fa7013ad240a48/packages/vinxi/lib/build.js#L477-L491

For vinxi dev it's here:

https://github.com/nksaraf/vinxi/blob/93d236ae005185143adab17b59fa7013ad240a48/packages/vinxi/lib/dev-server.js#L53-L59

I found I could hook into vinxi build thanks to:

https://github.com/nksaraf/vinxi/blob/93d236ae005185143adab17b59fa7013ad240a48/packages/vinxi/lib/build.js#L500-L504

Like so:

// app.config.js
const app = createApp({ /* ... */ })

app.hooks.hook("app:build:router:vite:start", async ({ vite }) => {
    vite.plugins.unshift(/* plugins here */)
})

export default app

This requires inside knowledge however and I assume this is not stable.

I could not find anything similar for vinxi dev.

samualtnorman commented 2 days ago

my current workaround is this patch

diff --git a/lib/build.js b/lib/build.js
index 812f346df2651bb4bab4ef54ac71b8142f15531a..e04fe63ea8219f2cdfc684a48a95a4818a34e1cd 100644
--- a/lib/build.js
+++ b/lib/build.js
@@ -503,6 +503,7 @@ async function createRouterBuild(app, router) {
        app,
    });

+   await app.hooks.callHook("3m6vP6KyC27N6foZgWisB", viteBuildConfig.plugins);
    await createViteBuild(viteBuildConfig);

    await app.hooks.callHook("app:build:router:vite:end", {
diff --git a/lib/dev-server.js b/lib/dev-server.js
index 381b6326958e55feb0e611d94c29c2b5e6fc8038..0bfb65120d48b5b76bb6881edfd82cee6f5cf17a 100644
--- a/lib/dev-server.js
+++ b/lib/dev-server.js
@@ -58,6 +58,8 @@ export async function createViteHandler(router, app, serveConfig) {
        ...(((await router.plugins?.(router)) ?? []).filter(Boolean) || []),
    ].filter(Boolean);

+   await app.hooks.callHook("3m6vP6KyC27N6foZgWisB", plugins);
+
    let base = join(app.config.server.baseURL ?? "/", router.base);

    const viteDevServer = await createViteDevServer({

and this in my app.config.ts

const app = createApp({ /* ... */ })

app.hooks.hook("3m6vP6KyC27N6foZgWisB", plugins => {
    plugins.unshift(/* plugins here */)
})

export default app