honox
Advanced tools
Comparing version 0.0.1 to 0.0.2
declare const COMPONENT_NAME = "component-name"; | ||
declare const DATA_SERIALIZED_PROPS = "data-serialized-props"; | ||
declare const IMPORTING_ISLANDS_ID: "__importing_islands"; | ||
export { COMPONENT_NAME, DATA_SERIALIZED_PROPS }; | ||
export { COMPONENT_NAME, DATA_SERIALIZED_PROPS, IMPORTING_ISLANDS_ID }; |
const COMPONENT_NAME = "component-name"; | ||
const DATA_SERIALIZED_PROPS = "data-serialized-props"; | ||
const IMPORTING_ISLANDS_ID = "__importing_islands"; | ||
export { | ||
COMPONENT_NAME, | ||
DATA_SERIALIZED_PROPS | ||
DATA_SERIALIZED_PROPS, | ||
IMPORTING_ISLANDS_ID | ||
}; |
export { ServerOptions, createApp } from './server.js'; | ||
export { HasIslands } from './components.js'; | ||
import 'hono/types'; | ||
import 'hono'; | ||
import '../constants.js'; | ||
import 'hono/jsx'; |
import { createApp } from "./server.js"; | ||
import { HasIslands } from "./components.js"; | ||
export { | ||
HasIslands, | ||
createApp | ||
}; |
import * as hono_types from 'hono/types'; | ||
import { H } from 'hono/types'; | ||
import { Env, Hono, MiddlewareHandler, NotFoundHandler, ErrorHandler } from 'hono'; | ||
import { IMPORTING_ISLANDS_ID } from '../constants.js'; | ||
declare const METHODS: readonly ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"]; | ||
type InnerMeta = { | ||
[key in typeof IMPORTING_ISLANDS_ID]?: boolean; | ||
}; | ||
type RouteFile = { | ||
@@ -10,3 +14,3 @@ default?: Function; | ||
[M in (typeof METHODS)[number]]?: H[]; | ||
}; | ||
} & InnerMeta; | ||
type RendererFile = { | ||
@@ -13,0 +17,0 @@ default: MiddlewareHandler; |
import { Hono } from "hono"; | ||
import { createMiddleware } from "hono/factory"; | ||
import { IMPORTING_ISLANDS_ID } from "../constants.js"; | ||
import { | ||
@@ -6,3 +8,2 @@ filePathToPath, | ||
listByDirectory, | ||
pathToDirectoryPath, | ||
sortDirectoriesByDepth | ||
@@ -32,6 +33,8 @@ } from "../utils/file.js"; | ||
const rendererList = listByDirectory(RENDERER_FILE); | ||
const applyRenderer = (rendererFile) => { | ||
const applyRenderer = (app2, rendererFile) => { | ||
const renderer = RENDERER_FILE[rendererFile]; | ||
const path = pathToDirectoryPath(rendererFile).replace(rootRegExp, ""); | ||
app.all(`${filePathToPath(path)}*`, renderer.default); | ||
const rendererDefault = renderer["default"]; | ||
if (rendererDefault) { | ||
app2.all("*", rendererDefault); | ||
} | ||
}; | ||
@@ -45,26 +48,27 @@ const ROUTES_FILE = options?.ROUTES ?? import.meta.glob("/app/routes/**/[!_]*.(ts|tsx|mdx)", { | ||
const subApp = new Hono(); | ||
let rendererFiles = rendererList[dir]; | ||
if (rendererFiles) { | ||
applyRenderer(rendererFiles[0]); | ||
} | ||
if (!rendererFiles) { | ||
const dirPaths = dir.split("/"); | ||
const getRendererPaths = (paths) => { | ||
rendererFiles = rendererList[paths.join("/")]; | ||
if (!rendererFiles) { | ||
paths.pop(); | ||
if (paths.length) { | ||
getRendererPaths(paths); | ||
} | ||
let rendererPaths = rendererList[dir] ?? []; | ||
const getRendererPaths = (paths) => { | ||
rendererPaths = rendererList[paths.join("/")]; | ||
if (!rendererPaths) { | ||
paths.pop(); | ||
if (paths.length) { | ||
getRendererPaths(paths); | ||
} | ||
return rendererFiles; | ||
}; | ||
rendererFiles = getRendererPaths(dirPaths); | ||
if (rendererFiles) { | ||
applyRenderer(rendererFiles[0]); | ||
} | ||
} | ||
return rendererPaths ?? []; | ||
}; | ||
const dirPaths = dir.split("/"); | ||
rendererPaths = getRendererPaths(dirPaths); | ||
rendererPaths.sort((a, b) => a.split("/").length - b.split("/").length); | ||
rendererPaths.map((path) => { | ||
applyRenderer(subApp, path); | ||
}); | ||
let rootPath = dir.replace(rootRegExp, ""); | ||
rootPath = filePathToPath(rootPath); | ||
for (const [filename, route] of Object.entries(content)) { | ||
const importingIslands = route[IMPORTING_ISLANDS_ID]; | ||
const setInnerMeta = createMiddleware(async function innerMeta(c, next) { | ||
c.set(IMPORTING_ISLANDS_ID, importingIslands); | ||
await next(); | ||
}); | ||
const routeDefault = route.default; | ||
@@ -78,2 +82,3 @@ const path = filePathToPath(filename); | ||
if (handlers) { | ||
subApp.on(m, path, setInnerMeta); | ||
subApp.on(m, path, ...handlers); | ||
@@ -83,5 +88,7 @@ } | ||
if (routeDefault && Array.isArray(routeDefault)) { | ||
subApp.get(path, setInnerMeta); | ||
subApp.get(path, ...routeDefault); | ||
} | ||
if (typeof routeDefault === "function") { | ||
subApp.get(path, setInnerMeta); | ||
subApp.get(path, (c) => { | ||
@@ -88,0 +95,0 @@ return c.render(routeDefault(), route); |
import path from "path"; | ||
import devServer, { defaultOptions as devServerDefaultOptions } from "@hono/vite-dev-server"; | ||
import { injectImportingIslands } from "./inject-importing-islands.js"; | ||
import { islandComponents } from "./island-components.js"; | ||
@@ -26,2 +27,3 @@ const defaultOptions = { | ||
} | ||
plugins.push(injectImportingIslands()); | ||
return [ | ||
@@ -28,0 +30,0 @@ { |
@@ -78,4 +78,5 @@ import fs from "fs/promises"; | ||
const functionId = path.node.declaration.id; | ||
if (!functionId) | ||
if (!functionId) { | ||
return; | ||
} | ||
const isAsync = path.node.declaration.async; | ||
@@ -82,0 +83,0 @@ const originalFunctionId = identifier(functionId.name + "Original"); |
{ | ||
"name": "honox", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"main": "dist/index.js", | ||
@@ -11,2 +11,3 @@ "type": "module", | ||
"test:integration:hono-jsx": "vitest run -c ./test/hono-jsx/vitest.config.ts ./test/hono-jsx/integration.test.ts", | ||
"test:integration:hono-jsx:watch": "vitest -c ./test/hono-jsx/vitest.config.ts ./test/hono-jsx/integration.test.ts", | ||
"test:integration:api": "vitest run -c ./test/api/vitest.config.ts ./test/api/integration.test.ts", | ||
@@ -17,6 +18,8 @@ "test:e2e": "playwright test -c ./test/hono-jsx/playwright.config.ts ./test/hono-jsx/e2e.test.ts", | ||
"watch": "tsup --watch", | ||
"lint": "eslint src/**.ts", | ||
"lint:fix": "eslint src/**.ts --fix", | ||
"prerelease": "yarn test && yarn build", | ||
"release": "np --no-yarn" | ||
"lint": "eslint --ext js,ts src test", | ||
"lint:fix": "eslint --ext js,ts src test --fix", | ||
"format": "prettier --check \"src/**/*.{js,ts}\" \"test/**/*.{js,ts}\"", | ||
"format:fix": "prettier --write \"src/**/*.{js,ts}\" \"test/**/*.{js,ts}\"", | ||
"prerelease": "bun run test && bun run build", | ||
"release": "np" | ||
}, | ||
@@ -94,6 +97,6 @@ "files": [ | ||
"@babel/types": "^7.23.6", | ||
"@hono/vite-dev-server": "^0.4.1" | ||
"@hono/vite-dev-server": "^0.5.0" | ||
}, | ||
"devDependencies": { | ||
"@hono/eslint-config": "^0.0.3", | ||
"@hono/eslint-config": "^0.0.4", | ||
"@mdx-js/rollup": "^3.0.0", | ||
@@ -106,4 +109,4 @@ "@playwright/test": "^1.41.0", | ||
"glob": "^10.3.10", | ||
"hono": "4.0.0-rc.2", | ||
"np": "^9.2.0", | ||
"hono": "4.0.0-rc.4", | ||
"np": "7.7.0", | ||
"prettier": "^3.1.1", | ||
@@ -116,6 +119,8 @@ "publint": "^0.2.7", | ||
}, | ||
"packageManager": "yarn@4.0.2", | ||
"engines": { | ||
"node": ">=18.14.1" | ||
}, | ||
"optionalDependencies": { | ||
"@rollup/rollup-linux-x64-gnu": "^4.9.6" | ||
} | ||
} |
# HonoX | ||
**HonoX** is a simple and fast meta framework for creating websites and Web APIs with Server-Side Rendering - (formerly _[Sonik](https://github.com/sonikjs/sonik)_). It stands on the shoulders of giants; built on [Hono](https://hono.dev/), [Vite](https://hono.dev/), and UI libraries. | ||
**HonoX** is a simple and fast - _supersonic_ - meta framework for creating full-stack websites or Web APIs - (formerly _[Sonik](https://github.com/sonikjs/sonik)_). It stands on the shoulders of giants; built on [Hono](https://hono.dev/), [Vite](https://hono.dev/), and UI libraries. | ||
**Note**: _HonoX is currently in a "beta stage". There will be breaking changes without any announcement. Don't use it in production. However, feel free to try it in your hobby project and give us your feedback!_ | ||
**Note**: _HonoX is currently in a "beta stage". Breaking changes are introduced without following semantic versioning._ | ||
## Features | ||
- **File-based routing** - You can create a large app by separating concerns. | ||
- **File-based routing** - You can create a large application like Next.js. | ||
- **Fast SSR** - Rendering is ultra-fast thanks to Hono. | ||
- **BYOR** - You can bring your own renderer, not only one using hono/jsx. | ||
- **Island hydration** - If you want interactions, create an island. JavaScript is hydrated only for it. | ||
- **Islands hydration** - If you want interactions, create an island. JavaScript is hydrated only for it. | ||
- **Middleware** - It works as Hono, so you can use a lot of Hono's middleware. | ||
@@ -157,3 +157,3 @@ | ||
// app/global.d.ts | ||
import 'hono' | ||
import type {} from 'hono' | ||
@@ -183,3 +183,3 @@ type Head = { | ||
<meta name='viewport' content='width=device-width, initial-scale=1.0' /> | ||
{title ? <title>{title}</title> : ''} | ||
{title ? <title>{title}</title> : <></>} | ||
</head> | ||
@@ -250,3 +250,3 @@ <body>{children}</body> | ||
This is a `_renderer.tsx` which will load the `/app/client.ts` entry file for the client. It can also load the JavaScript file for the production according to the variable `import.meta.env.PROD`. | ||
This is a `_renderer.tsx`, which will load the `/app/client.ts` entry file for the client. It will load the JavaScript file for the production according to the variable `import.meta.env.PROD`. And renders the inside of `HasIslands` if there are islands on that page. | ||
@@ -264,3 +264,5 @@ ```tsx | ||
{import.meta.env.PROD ? ( | ||
<script type='module' src='/static/client.js'></script> | ||
<HasIslands> | ||
<script type='module' src='/static/client.js'></script> | ||
</HasIslands> | ||
) : ( | ||
@@ -327,3 +329,3 @@ <script type='module' src='/app/client.ts'></script> | ||
**Note**: We cannot provide technical support for the renderer you bring. | ||
**Note**: We may not provide supports for the renderer you bring. | ||
@@ -397,2 +399,21 @@ ### React case | ||
### Nested Layouts | ||
If you are using the JSX Renderer middleware, you can nest layouts using ` <Layout />`. | ||
```tsx | ||
// app/routes/posts/_renderer.tsx | ||
import { jsxRenderer } from 'hono/jsx-renderer' | ||
export default jsxRenderer(({ children, Layout }) => { | ||
return ( | ||
<Layout> | ||
<nav>Posts Menu</nav> | ||
<div>{children}</div> | ||
</Layout> | ||
) | ||
}) | ||
``` | ||
### Using Middleware | ||
@@ -399,0 +420,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
50496
35
748
651
0
6
+ Added@hono/vite-dev-server@0.5.1(transitive)
+ Added@rollup/rollup-linux-x64-gnu@4.18.0(transitive)
- Removed@hono/vite-dev-server@0.4.1(transitive)
Updated@hono/vite-dev-server@^0.5.0