Skip to content

Commit d89091e

Browse files
authored
Merge pull request #675 from 2chanhaeng/init-nuxt
Add Nuxt as a web framework option in `fedify init`
2 parents f00a94e + d825e08 commit d89091e

8 files changed

Lines changed: 105 additions & 7 deletions

File tree

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,13 @@ To be released.
9797
`TypeError: Cannot read properties of undefined` from `mysql2`.
9898
[[#649], [#656] by ChanHaeng Lee]
9999

100+
- Supported [Nuxt] as a web framework option in `fedify init`, with
101+
templates for federation setup, logging, and Nitro middleware.
102+
[[#149], [#675] by ChanHaeng Lee]
103+
100104
[#649]: https://github.com/fedify-dev/fedify/issues/649
101105
[#656]: https://github.com/fedify-dev/fedify/pull/656
106+
[#675]: https://github.com/fedify-dev/fedify/pull/675
102107

103108

104109
Version 2.1.5

packages/init/src/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const WEB_FRAMEWORK = [
1313
"elysia",
1414
"astro",
1515
"express",
16+
"nuxt",
1617
"solidstart",
1718
] as const;
1819
/** All supported message queue backend identifiers. */

packages/init/src/json/deps.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"npm:@dotenvx/dotenvx": "^1.59.1",
1010
"npm:@elysiajs/node": "^1.4.5",
1111
"npm:@hono/node-server": "^1.19.12",
12+
"npm:@nuxt/kit": "^4.4.2",
1213
"npm:@sinclair/typebox": "^0.34.49",
1314
"npm:@solidjs/router": "^0.16.1",
1415
"npm:@solidjs/start": "^1.3.2",
@@ -21,7 +22,10 @@
2122
"npm:elysia": "^1.4.28",
2223
"npm:eslint": "^9.0.0",
2324
"npm:express": "^5.2.1",
25+
"npm:h3": "^1.15.0",
2426
"npm:hono": "^4.12.9",
27+
"npm:nuxi": "^3.34.0",
28+
"npm:nuxt": "^4.4.2",
2529
"npm:openapi-types": "^12.1.3",
2630
"npm:solid-js": "^1.9.12",
2731
"npm:tsx": "^4.21.0",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// https://nuxt.com/docs/api/configuration/nuxt-config
2+
export default defineNuxtConfig({
3+
modules: ["@fedify/nuxt"],
4+
fedify: { federationModule: "#server/federation" },
5+
ssr: true,
6+
});

packages/init/src/test/lookup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const BANNED_LOOKUP_REASONS: Record<string, string> = {
3131
"next,*,*,*": "Next.js doesn't support remote packages",
3232
"solidstart,deno,*,*": "Error occurred while loading submodules in Deno",
3333
"astro,deno,*,*": "Astro doesn't support remote packages in Deno",
34+
"nuxt,deno,*,*": "Nuxt doesn't support remote packages in Deno",
3435
};
3536
const BANNED_LOOKUP_CASES: LookupCasePattern[] = Object.keys(
3637
BANNED_LOOKUP_REASONS,

packages/init/src/test/port.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { execFile } from "node:child_process";
2-
import { appendFile, readFile, writeFile } from "node:fs/promises";
2+
import { readFile, writeFile } from "node:fs/promises";
33
import { createConnection, createServer } from "node:net";
44
import { join } from "node:path";
55
import process from "node:process";
@@ -100,6 +100,12 @@ const ENTRY_FILES: Partial<Record<WebFramework, string>> = {
100100
elysia: "src/index.ts",
101101
};
102102

103+
const WF_READ_PORT_FROM_ENV: Set<WebFramework> = new Set([
104+
"nuxt",
105+
"nitro",
106+
"solidstart",
107+
]);
108+
103109
/**
104110
* Replace the hardcoded default port with `newPort` in the generated test
105111
* app's source files. Strategy varies by framework.
@@ -110,6 +116,7 @@ export async function replacePortInApp(
110116
defaultPort: number,
111117
newPort: number,
112118
): Promise<void> {
119+
if (WF_READ_PORT_FROM_ENV.has(wf)) return;
113120
if (defaultPort === newPort) return;
114121

115122
const entryFile = ENTRY_FILES[wf];
@@ -125,12 +132,6 @@ export async function replacePortInApp(
125132
return;
126133
}
127134

128-
if (wf === "nitro") {
129-
// Nitro reads PORT from .env
130-
await appendFile(join(dir, ".env"), `\nPORT=${newPort}\n`);
131-
return;
132-
}
133-
134135
if (wf === "astro") {
135136
// Insert server.port into the Astro config
136137
const configPath = join(dir, "astro.config.ts");

packages/init/src/webframeworks/mod.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import express from "./express.ts";
66
import hono from "./hono.ts";
77
import next from "./next.ts";
88
import nitro from "./nitro.ts";
9+
import nuxt from "./nuxt.ts";
910
import solidstart from "./solidstart.ts";
1011

1112
/**
@@ -23,6 +24,7 @@ const webFrameworks: WebFrameworks = {
2324
hono,
2425
next,
2526
nitro,
27+
nuxt,
2628
solidstart,
2729
} as const;
2830

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { PACKAGE_MANAGER } from "../const.ts";
2+
import deps from "../json/deps.json" with { type: "json" };
3+
import { PACKAGE_VERSION, readTemplate } from "../lib.ts";
4+
import type { PackageManager, WebFrameworkDescription } from "../types.ts";
5+
import { defaultDenoDependencies, defaultDevDependencies } from "./const.ts";
6+
import { getInstruction } from "./utils.ts";
7+
8+
const nuxtDescription: WebFrameworkDescription = {
9+
label: "Nuxt",
10+
packageManagers: PACKAGE_MANAGER,
11+
defaultPort: 3000,
12+
init: async ({ packageManager: pm, testMode }) => ({
13+
command: Array.from(getInitCommand(pm)),
14+
dependencies: getDeps(pm),
15+
devDependencies: {
16+
...defaultDevDependencies,
17+
"typescript": deps["npm:typescript"],
18+
"@types/node": deps["npm:@types/node@25"],
19+
},
20+
federationFile: "server/federation.ts",
21+
loggingFile: "server/logging.ts",
22+
env: testMode ? { HOST: "127.0.0.1" } : {} as Record<string, string>,
23+
files: {
24+
"nuxt.config.ts": await readTemplate("nuxt/nuxt.config.ts"),
25+
...(pm !== "deno" && {
26+
"eslint.config.ts": await readTemplate("defaults/eslint.config.ts"),
27+
}),
28+
},
29+
tasks: pm !== "deno"
30+
? { "lint": "eslint ." }
31+
: {} as Record<string, string>,
32+
instruction: getInstruction(pm, 3000),
33+
}),
34+
};
35+
36+
export default nuxtDescription;
37+
38+
function* getInitCommand(pm: PackageManager) {
39+
yield* getNuxtInitCommand(pm);
40+
yield* [
41+
"init",
42+
".",
43+
"--template",
44+
"minimal",
45+
"--no-install",
46+
"--force",
47+
"--packageManager",
48+
pm,
49+
"--no-gitInit",
50+
"--no-modules",
51+
"&&",
52+
"rm",
53+
"nuxt.config.ts",
54+
];
55+
}
56+
57+
/**
58+
* Returns the shell command array to scaffold a new Nuxt project
59+
* in the current directory using the given package manager.
60+
*/
61+
const getNuxtInitCommand = (pm: PackageManager): string[] =>
62+
pm === "bun"
63+
? ["bunx", "nuxi"]
64+
: pm === "deno"
65+
? ["deno", "-A", "npm:nuxi@latest"]
66+
: pm === "npm"
67+
? ["npx", "nuxi"]
68+
: [pm, "dlx", "nuxi"];
69+
70+
const getDeps = (pm: PackageManager): Record<string, string> =>
71+
pm !== "deno"
72+
? {
73+
"@fedify/nuxt": PACKAGE_VERSION,
74+
}
75+
: {
76+
...defaultDenoDependencies,
77+
"@fedify/nuxt": PACKAGE_VERSION,
78+
};

0 commit comments

Comments
 (0)