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 often wonder what it would look like to build sites & apps knowing just the basics.
I thought: 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 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 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? - 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. **McFly** is my reimagination of web development: Back to the basics. Into the future.
## Project Status ## Project Status
We are currently in a Proof of Concept phase. All parts are subject to breaking changes in minor releases. We are currently in a Proof of Concept phase. All parts are subject to breaking changes in minor releases.
## Try it today ## Try it today
Run the following to generate a McFly starter project. Run the following to generate a McFly starter project.
``` ```
npm create mcfly@latest npm create mcfly@latest
``` ```
@ -42,36 +46,43 @@ npm create mcfly@latest
✅ Deploy anywhere, even the Edge<br> ✅ Deploy anywhere, even the Edge<br>
## Special directories ## Special directories
**1. `./src/pages/`** **1. `./src/pages/`**
- file-based routing for `.html` files - file-based routing for `.html` files
- directly use custom elements & static fragments (no imports or registry maintenance needed) - 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 - use `<script server:setup>` to define logic that runs on the server, which then gets stripped away
**2. `./src/components/`** **2. `./src/components/`**
- custom element constructor files (only `.js` files for now) - 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>` - 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>` - 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 - file-based routing for REST API endpoints
- e.g., `./routes/api/users.ts` can be accessed via `http://<domain>/api/users` - e.g., `./routes/api/users.ts` can be accessed via `http://<domain>/api/users`
- TypeScript or JavaScript welcome! - TypeScript or JavaScript welcome!
## Packages ## Packages
The following are the project packages published on the NPM registry: The following are the project packages published on the NPM registry:
| Package | Description | Version | | 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/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/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) | | [`@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) | | [`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 ## 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. 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/) **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, prerender,
} from 'nitropack' } from 'nitropack'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { nitroConfig as mcflyNitroConfig } from '@mcflyjs/config/nitro-config.js'
async function _build(args) { async function _build(args) {
consola.start('Building project...') consola.start('Building project...')
@ -21,7 +22,6 @@ async function _build(args) {
const { config: nitroConfig } = await loadConfig({ name: 'nitro' }) const { config: nitroConfig } = await loadConfig({ name: 'nitro' })
const nitro = await createNitro({ const nitro = await createNitro({
extends: '@mcflyjs/config',
rootDir, rootDir,
dev: false, dev: false,
minify: args.minify, minify: args.minify,
@ -29,6 +29,7 @@ async function _build(args) {
// spread mcfly.nitro config // spread mcfly.nitro config
...(mcflyConfig.nitro ?? {}), ...(mcflyConfig.nitro ?? {}),
...(nitroConfig ?? {}), ...(nitroConfig ?? {}),
...mcflyNitroConfig,
}) })
nitro.options.runtimeConfig.mcfly = mcflyConfig nitro.options.runtimeConfig.mcfly = mcflyConfig

View file

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

View file

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

View file

@ -22,12 +22,22 @@ import {
* McFly middleware event handler * McFly middleware event handler
*/ */
export default eventHandler(async (event) => { export default eventHandler(async (event) => {
const timeStart = performance.now()
const hooks = createHooks() const hooks = createHooks()
Object.keys(mcflyHooks).forEach((hookName) => hooks.addHooks(hookName)) Object.keys(mcflyHooks).forEach((hookName) => hooks.addHooks(hookName))
const { path } = event const { path } = event
let { mcfly: config } = useRuntimeConfig() let { mcfly: config } = useRuntimeConfig()
const storage = useStorage() 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) { if (!config || Object.keys(config).length === 0) {
config = defaultMcflyConfig config = defaultMcflyConfig
consola.warn(`[WARN]: McFly configuration not loaded, using defaults...`) consola.warn(`[WARN]: McFly configuration not loaded, using defaults...`)
@ -85,6 +95,13 @@ export default eventHandler(async (event) => {
hooks.callHook(mcflyHooks.pageRendered) hooks.callHook(mcflyHooks.pageRendered)
} }
const timeEnd = performance.now()
consola.info(
'Page rendered in',
Math.round(timeEnd - timeStart),
'ms:',
event.path
)
return ( return (
html ?? html ??
new Response( new Response(