From bdc818bb140e4559de3e7af4afd24f38d0739033 Mon Sep 17 00:00:00 2001 From: daishi Date: Sat, 13 Jan 2024 11:25:01 +0900 Subject: [PATCH 1/4] feat: waku/config --- packages/waku/package.json | 7 ++-- packages/waku/src/config.ts | 63 +++++++++++++++++++++++++++++++++ packages/waku/src/lib/config.ts | 60 +------------------------------ 3 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 packages/waku/src/config.ts diff --git a/packages/waku/package.json b/packages/waku/package.json index 62e29ff8a..05e8cd39a 100644 --- a/packages/waku/package.json +++ b/packages/waku/package.json @@ -18,6 +18,10 @@ "types": "./dist/main.d.ts", "default": "./dist/main.js" }, + "./config": { + "types": "./dist/config.d.ts", + "default": "./dist/config.js" + }, "./prd": { "types": "./dist/prd.d.ts", "default": "./dist/prd.js" @@ -52,8 +56,7 @@ }, "files": [ "src", - "dist", - "patches" + "dist" ], "scripts": { "dev": "swc src -d dist -w", diff --git a/packages/waku/src/config.ts b/packages/waku/src/config.ts new file mode 100644 index 000000000..8440149bc --- /dev/null +++ b/packages/waku/src/config.ts @@ -0,0 +1,63 @@ +export interface Config { + /** + * The base path for serve HTTP. + * Defaults to "/". + */ + basePath?: string; + /** + * The source directory relative to root. + * This will be the actual root in the development mode. + * Defaults to "src". + */ + srcDir?: string; + /** + * The dist directory relative to root. + * This will be the actual root in the production mode. + * Defaults to "dist". + */ + distDir?: string; + /** + * The public directory relative to distDir. + * It's different from Vite's build.publicDir config. + * Defaults to "public". + */ + publicDir?: string; + /** + * The assets directory relative to distDir and publicDir. + * Defaults to "assets". + */ + assetsDir?: string; + /** + * The index.html file for any directories. + * Defaults to "index.html". + */ + indexHtml?: string; + /** + * The client main file relative to srcDir. + * Defaults to "main.tsx". + */ + mainJs?: string; + /** + * The entries.js file relative to srcDir or distDir. + * The extension should be `.js`, + * but resolved with `.ts`, `.tsx` and `.jsx` in the development mode. + * Defaults to "entries.js". + */ + entriesJs?: string; + /** + * Prefix for HTTP requests to indicate RSC requests. + * Defaults to "RSC". + */ + rscPath?: string; + /** + * HTML headers to inject. + * Defaults to: + * + * + */ + htmlHead?: string; +} + +export function defineConfig(config: Config) { + return config; +} diff --git a/packages/waku/src/lib/config.ts b/packages/waku/src/lib/config.ts index bb78aa6c8..044f257bd 100644 --- a/packages/waku/src/lib/config.ts +++ b/packages/waku/src/lib/config.ts @@ -1,62 +1,4 @@ -export interface Config { - /** - * The base path for serve HTTP. - * Defaults to "/". - */ - basePath?: string; - /** - * The source directory relative to root. - * This will be the actual root in the development mode. - * Defaults to "src". - */ - srcDir?: string; - /** - * The dist directory relative to root. - * This will be the actual root in the production mode. - * Defaults to "dist". - */ - distDir?: string; - /** - * The public directory relative to distDir. - * It's different from Vite's build.publicDir config. - * Defaults to "public". - */ - publicDir?: string; - /** - * The assets directory relative to distDir and publicDir. - * Defaults to "assets". - */ - assetsDir?: string; - /** - * The index.html file for any directories. - * Defaults to "index.html". - */ - indexHtml?: string; - /** - * The client main file relative to srcDir. - * Defaults to "main.tsx". - */ - mainJs?: string; - /** - * The entries.js file relative to srcDir or distDir. - * The extension should be `.js`, - * but resolved with `.ts`, `.tsx` and `.jsx` in the development mode. - * Defaults to "entries.js". - */ - entriesJs?: string; - /** - * Prefix for HTTP requests to indicate RSC requests. - * Defaults to "RSC". - */ - rscPath?: string; - /** - * HTML headers to inject. - * Defaults to: - * - * - */ - htmlHead?: string; -} +import type { Config } from '../config.js'; type DeepRequired = T extends (...args: any[]) => any ? T From d2cc1c4d395a30faf1a913195519313ffd96305f Mon Sep 17 00:00:00 2001 From: daishi Date: Sat, 13 Jan 2024 11:32:30 +0900 Subject: [PATCH 2/4] fix imports --- packages/waku/src/lib/builder/build.ts | 3 ++- packages/waku/src/lib/handlers/handler-dev.ts | 2 +- packages/waku/src/lib/handlers/handler-prd.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/waku/src/lib/builder/build.ts b/packages/waku/src/lib/builder/build.ts index 9ccaf4d7e..0adf70af4 100644 --- a/packages/waku/src/lib/builder/build.ts +++ b/packages/waku/src/lib/builder/build.ts @@ -6,8 +6,9 @@ import { build as buildVite, resolveConfig as resolveViteConfig } from 'vite'; import viteReact from '@vitejs/plugin-react'; import type { RollupLog, LoggingFunction } from 'rollup'; +import type { Config } from '../../config.js'; import { resolveConfig } from '../config.js'; -import type { Config, ResolvedConfig } from '../config.js'; +import type { ResolvedConfig } from '../config.js'; import { joinPath, extname, diff --git a/packages/waku/src/lib/handlers/handler-dev.ts b/packages/waku/src/lib/handlers/handler-dev.ts index fea85a8bb..94894beb2 100644 --- a/packages/waku/src/lib/handlers/handler-dev.ts +++ b/packages/waku/src/lib/handlers/handler-dev.ts @@ -2,8 +2,8 @@ import { Readable, Writable } from 'node:stream'; import { createServer as createViteServer } from 'vite'; import { default as viteReact } from '@vitejs/plugin-react'; +import type { Config } from '../../config.js'; import { resolveConfig } from '../config.js'; -import type { Config } from '../config.js'; import { joinPath, decodeFilePathFromAbsolute } from '../utils/path.js'; import { endStream } from '../utils/stream.js'; import { renderHtml } from '../renderers/html-renderer.js'; diff --git a/packages/waku/src/lib/handlers/handler-prd.ts b/packages/waku/src/lib/handlers/handler-prd.ts index 2ecfdd521..34a23dda1 100644 --- a/packages/waku/src/lib/handlers/handler-prd.ts +++ b/packages/waku/src/lib/handlers/handler-prd.ts @@ -1,6 +1,6 @@ import type { EntriesPrd } from '../../server.js'; +import type { Config } from '../../config.js'; import { resolveConfig } from '../config.js'; -import type { Config } from '../config.js'; import { endStream } from '../utils/stream.js'; import { renderHtml } from '../renderers/html-renderer.js'; import { decodeInput, hasStatusCode, deepFreeze } from '../renderers/utils.js'; From cd4ab414e540f7fdd98efd29d85e38e48203fa62 Mon Sep 17 00:00:00 2001 From: daishi Date: Sat, 13 Jan 2024 22:50:25 +0900 Subject: [PATCH 3/4] loadConfig --- packages/waku/src/cli.ts | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/waku/src/cli.ts b/packages/waku/src/cli.ts index 8054177c1..b978e295a 100755 --- a/packages/waku/src/cli.ts +++ b/packages/waku/src/cli.ts @@ -8,7 +8,9 @@ import { createRequire } from 'node:module'; import { Hono } from 'hono'; import { serve } from '@hono/node-server'; import { serveStatic } from '@hono/node-server/serve-static'; +import * as swc from '@swc/core'; +import type { Config } from './config.js'; import { resolveConfig } from './lib/config.js'; import { honoMiddleware as honoDevMiddleware } from './lib/middleware/hono-dev.js'; import { honoMiddleware as honoPrdMiddleware } from './lib/middleware/hono-prd.js'; @@ -47,6 +49,7 @@ const { values, positionals } = parseArgs({ }); loadEnv(); +const config = await loadConfig(); const cmd = positionals[0]; @@ -80,7 +83,10 @@ if (values.version) { async function runDev(options: { ssr: boolean }) { const app = new Hono(); - app.use('*', honoDevMiddleware({ ...options, env: process.env as any })); + app.use( + '*', + honoDevMiddleware({ ...options, config, env: process.env as any }), + ); const port = parseInt(process.env.PORT || '3000', 10); startServer(app, port); } @@ -88,6 +94,7 @@ async function runDev(options: { ssr: boolean }) { async function runBuild(options: { ssr: boolean }) { await build({ ...options, + config, env: process.env as any, vercel: values['with-vercel'] ?? !!process.env.VERCEL @@ -101,14 +108,14 @@ async function runBuild(options: { ssr: boolean }) { } async function runStart(options: { ssr: boolean }) { - const { distDir, publicDir, entriesJs } = await resolveConfig({}); + const { distDir, publicDir, entriesJs } = await resolveConfig(config); const entries = import( pathToFileURL(path.resolve(distDir, entriesJs)).toString() ); const app = new Hono(); app.use( '*', - honoPrdMiddleware({ ...options, entries, env: process.env as any }), + honoPrdMiddleware({ ...options, config, entries, env: process.env as any }), ); app.use('*', serveStatic({ root: path.join(distDir, publicDir) })); const port = parseInt(process.env.PORT || '8080', 10); @@ -165,3 +172,18 @@ function loadEnv() { } } } + +// TODO is this a good idea? +async function loadConfig(): Promise { + if (!existsSync('waku.config.ts')) { + return {}; + } + const { code } = swc.transformFileSync('waku.config.ts', { + swcrc: false, + jsc: { + parser: { syntax: 'typescript' }, + target: 'es2022', + }, + }); + return (await import(`data:text/javascript,${code}`)).default; +} From 34635c1e506472d6058f84b1154c563fa0e9a998 Mon Sep 17 00:00:00 2001 From: daishi Date: Sat, 13 Jan 2024 23:19:57 +0900 Subject: [PATCH 4/4] use temp file --- packages/waku/src/cli.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/waku/src/cli.ts b/packages/waku/src/cli.ts index b978e295a..e3be7304a 100755 --- a/packages/waku/src/cli.ts +++ b/packages/waku/src/cli.ts @@ -1,10 +1,11 @@ #!/usr/bin/env node import path from 'node:path'; -import { existsSync, readFileSync } from 'node:fs'; +import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs'; import { pathToFileURL } from 'node:url'; import { parseArgs } from 'node:util'; import { createRequire } from 'node:module'; +import { randomBytes } from 'node:crypto'; import { Hono } from 'hono'; import { serve } from '@hono/node-server'; import { serveStatic } from '@hono/node-server/serve-static'; @@ -185,5 +186,11 @@ async function loadConfig(): Promise { target: 'es2022', }, }); - return (await import(`data:text/javascript,${code}`)).default; + const temp = path.resolve(`.temp-${randomBytes(8).toString('hex')}.js`); + try { + writeFileSync(temp, code); + return (await import(pathToFileURL(temp).toString())).default; + } finally { + unlinkSync(temp); + } }