feat(core): use src/api as api dir; don't render if event path is public asset

This commit is contained in:
Ayo Ayco 2025-01-08 23:26:27 +01:00
parent 15bbb38123
commit b526da063f
5 changed files with 44 additions and 13 deletions

View file

@ -17,6 +17,7 @@
I often wonder what it would look like to build sites & apps knowing just the basics.
I thought:
- What if I knew how to write HTML and I can have a dynamic web page from that?
- What if I knew how to build custom elements and that's all the component system I needed?
- What if I can write HTML fragments and assemble them easily in a page?
@ -25,10 +26,13 @@ I thought:
**McFly** is my reimagination of web development: Back to the basics. Into the future.
## Project Status
We are currently in a Proof of Concept phase. All parts are subject to breaking changes in minor releases.
## Try it today
Run the following to generate a McFly starter project.
```
npm create mcfly@latest
```
@ -42,36 +46,43 @@ npm create mcfly@latest
✅ Deploy anywhere, even the Edge<br>
## Special directories
**1. `./src/pages/`**
- file-based routing for `.html` files
- directly use custom elements & static fragments (no imports or registry maintenance needed)
- use `<script server:setup>` to define logic that runs on the server, which then gets stripped away
**2. `./src/components/`**
- custom element constructor files (only `.js` files for now)
- all components are automatically registered using their file names; a `hello-world.js` component can be used as `<hello-world>`
- static `.html` fragments; a `my-header.html` fragment can be directly used as `<my-header>`
**3. `./routes/api/`**
**3. `./src/api/`**
- file-based routing for REST API endpoints
- e.g., `./routes/api/users.ts` can be accessed via `http://<domain>/api/users`
- TypeScript or JavaScript welcome!
## Packages
The following are the project packages published on the NPM registry:
| Package | Description | Version |
| --- | --- | --- |
| [`@mcflyjs/cli`](https://ayco.io/n/@mcflyjs/cli) | The McFly CLI tooling | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fcli) |
| [`@mcflyjs/config`](https://ayco.io/n/@mcflyjs/config) | Nitro server config for McFly projects | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fconfig) |
| [`@mcflyjs/core`](https://ayco.io/n/@mcflyjs/core) | Route event and config handlers | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fcore) |
| [`create-mcfly`](https://ayco.io/n/create-mcfly) | Script for scaffolding a new McFly workspace | ![npm version](https://img.shields.io/npm/v/create-mcfly) |
| Package | Description | Version |
| ------------------------------------------------------ | -------------------------------------------- | ---------------------------------------------------------------- |
| [`@mcflyjs/cli`](https://ayco.io/n/@mcflyjs/cli) | The McFly CLI tooling | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fcli) |
| [`@mcflyjs/config`](https://ayco.io/n/@mcflyjs/config) | Nitro server config for McFly projects | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fconfig) |
| [`@mcflyjs/core`](https://ayco.io/n/@mcflyjs/core) | Route event and config handlers | ![npm version](https://img.shields.io/npm/v/%40mcflyjs%2Fcore) |
| [`create-mcfly`](https://ayco.io/n/create-mcfly) | Script for scaffolding a new McFly workspace | ![npm version](https://img.shields.io/npm/v/create-mcfly) |
## More info
This framework is a result of [an exploration](https://social.ayco.io/@ayo/111195315785886977) for using [Nitro](https://nitro.build) and custom elements using a minimal [Web Component Base](https://WebComponent.io) class.
**Nitro** is the same production-grade web server powering [Nuxt](https://nuxt.com/)
---
*Just keep building*<br />
*A project by [Ayo Ayco](https://ayco.io)*
_Just keep building_<br />
_A project by [Ayo Ayco](https://ayco.io)_

View file

@ -12,6 +12,7 @@ import {
prerender,
} from 'nitropack'
import { fileURLToPath } from 'node:url'
import { nitroConfig as mcflyNitroConfig } from '@mcflyjs/config/nitro-config.js'
async function _build(args) {
consola.start('Building project...')
@ -21,7 +22,6 @@ async function _build(args) {
const { config: nitroConfig } = await loadConfig({ name: 'nitro' })
const nitro = await createNitro({
extends: '@mcflyjs/config',
rootDir,
dev: false,
minify: args.minify,
@ -29,6 +29,7 @@ async function _build(args) {
// spread mcfly.nitro config
...(mcflyConfig.nitro ?? {}),
...(nitroConfig ?? {}),
...mcflyNitroConfig,
})
nitro.options.runtimeConfig.mcfly = mcflyConfig

View file

@ -15,6 +15,7 @@ import { resolve } from 'pathe'
import { loadConfig } from 'c12'
import { fileURLToPath } from 'node:url'
import { dirname } from 'pathe'
import { nitroConfig as mcflyNitroConfig } from '@mcflyjs/config/nitro-config.js'
const hmrKeyRe = /^runtimeConfig\.|routeRules\./
const __filename = fileURLToPath(import.meta.url)
@ -62,7 +63,6 @@ async function serve(args) {
// create new nitro
nitro = await createNitro(
{
extends: '@mcflyjs/config',
rootDir,
dev: true,
preset: 'nitro-dev',
@ -70,6 +70,7 @@ async function serve(args) {
// spread mcfly.nitro config
...(mcflyConfig.nitro ?? {}),
...(nitroConfig ?? {}),
...mcflyNitroConfig,
},
{
watch: true,

View file

@ -1,6 +1,6 @@
{
"name": "@mcflyjs/core",
"version": "0.7.2",
"version": "0.8.0",
"description": "McFly core package",
"type": "module",
"main": "index.js",
@ -32,7 +32,8 @@
"h3": "^1.13.0",
"nitropack": "latest",
"pathe": "^1.1.2",
"ultrahtml": "^1.5.3"
"ultrahtml": "^1.5.3",
"@mcflyjs/config": "workspace:*"
},
"devDependencies": {
"@vitest/coverage-istanbul": "2.1.8",

View file

@ -22,12 +22,22 @@ import {
* McFly middleware event handler
*/
export default eventHandler(async (event) => {
const timeStart = performance.now()
const hooks = createHooks()
Object.keys(mcflyHooks).forEach((hookName) => hooks.addHooks(hookName))
const { path } = event
let { mcfly: config } = useRuntimeConfig()
const storage = useStorage()
const publicAssets = (await storage.getKeys('root:public')).map(
(key) => `/${key.replace('root:public:', '')}`
)
// if not page, don't render
if (event.path.startsWith('/api') || publicAssets.includes(event.path)) {
return
}
if (!config || Object.keys(config).length === 0) {
config = defaultMcflyConfig
consola.warn(`[WARN]: McFly configuration not loaded, using defaults...`)
@ -85,6 +95,13 @@ export default eventHandler(async (event) => {
hooks.callHook(mcflyHooks.pageRendered)
}
const timeEnd = performance.now()
consola.info(
'Page rendered in',
Math.round(timeEnd - timeStart),
'ms:',
event.path
)
return (
html ??
new Response(