Skip to content

Commit

Permalink
Merge pull request #215 from nksaraf/config-esbuold
Browse files Browse the repository at this point in the history
feat: bundle config file with esbuild before loading, adds support for ts, jsx, etc in config files
  • Loading branch information
nksaraf authored Feb 27, 2024
2 parents df99efc + 345ed49 commit 44faf8d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 22 deletions.
6 changes: 6 additions & 0 deletions .changeset/cuddly-balloons-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"vinxi": patch
"react-ssr-basic": patch
---

feat: bundle config file with esbuild before loading, adds support for ts, jsx, etc in config files
96 changes: 75 additions & 21 deletions packages/vinxi/lib/load-app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/// <reference types="bun-types" />
import { loadConfig } from "c12";
import { existsSync } from "fs";
import { rm } from "fs/promises";
import { isBuiltin } from "module";
import { fileURLToPath, pathToFileURL } from "url";

import { createApp } from "./app.js";
import { log } from "./logger.js";
import { join } from "./path.js";
import { isAbsolute, join } from "./path.js";

function isBun() {
return !!process.versions.bun;
Expand All @@ -15,44 +16,97 @@ async function fileExists(path) {
return isBun() ? Bun.file(path).exists() : existsSync(path);
}

const bundleConfigFile = async (configFile, out) => {
const esbuild = await import("esbuild");

// const out = `app.config.timestamp_${Date.now()}.js`;
await esbuild.build({
entryPoints: [configFile],
bundle: true,
outfile: out,
platform: "node",
format: "esm",
resolveExtensions: [".js", ".mjs", ".ts", ".jsx", ".tsx"],
plugins: [
{
name: "externalize-deps",
setup(build) {
build.onResolve(
{ filter: /^[^.].*/ },
async ({ path: id, importer, kind }) => {
if (
kind === "entry-point" ||
isAbsolute(id) ||
id.match(/node:.*/)
) {
return;
}

// With the `isNodeBuiltin` check above, this check captures if the builtin is a
// non-node built-in, which esbuild doesn't know how to handle. In that case, we
// externalize it so the non-node runtime handles it instead.
if (isBuiltin(id)) {
return { external: true };
}

return { external: true };
},
);
},
},
],
loader: {
".js": "jsx",
".ts": "tsx",
".jsx": "jsx",
".tsx": "tsx",
".mjs": "jsx",
},
});
};

async function loadFile({ ...options }) {
if (options.name) {
for (const ext of ["js", "mjs", "ts"]) {
if (ext === "ts" && !isBun()) continue;

for (const ext of ["js", "mjs", "ts", "tsx", "jsx"]) {
const filepath = join(process.cwd(), `${options.name}.config.${ext}`);

if (await fileExists(filepath)) {
return import(
pathToFileURL(filepath).href + `?time=${Date.now()}`
).then((m) => ({
let out = `${options.name}.config.timestamp_${Date.now()}.${ext}`;
await bundleConfigFile(`${options.name}.config.${ext}`, out);
const importedApp = import(pathToFileURL(out).href).then((m) => ({
config: m.default,
}));

await rm(out);
return importedApp;
}
}

throw new Error(`Config file not found: ${options.name}`);
} else if (options.configFile) {
const ext = options.configFile.slice(
options.configFile.lastIndexOf(".") + 1,
);
if (["js", "mjs", "ts"].includes(ext) && (ext !== "ts" || isBun())) {
const filepath = join(process.cwd(), options.configFile);
const configFileName = options.configFile.slice(
0,
options.configFile.lastIndexOf("."),
);

if (["js", "mjs", "ts", "tsx", "jsx"].includes(ext)) {
const filepath = join(process.cwd(), `${configFileName}.${ext}`);
if (await fileExists(filepath)) {
return import(
pathToFileURL(filepath).href + `?time=${Date.now()}`
).then((m) => ({
let out = `${configFileName}.timestamp_${Date.now()}.${ext}`;
await bundleConfigFile(options.configFile, out);
const importedApp = import(pathToFileURL(out).href).then((m) => ({
config: m.default,
}));
await rm(out);
return importedApp;
}
}
}

return loadConfig({
jitiOptions: {
esmResolve: true,
nativeModules: ["acorn"],
},
...options,
});
throw new Error(`Config file not found: ${options.configFile}`);
}
}

/**
Expand Down
1 change: 0 additions & 1 deletion packages/vinxi/lib/nitro-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ export async function createDevServer(nitro) {

// Dev-only handlers
for (const handler of nitro.options.devHandlers) {
console.log(handler);
app.use(
joinURL(nitro.options.runtimeConfig.app.baseURL, handler.route ?? "/"),
handler.handler,
Expand Down

0 comments on commit 44faf8d

Please sign in to comment.