Git Product home page Git Product logo

vite-plugins's Introduction

vite-plugins's People

Contributors

alessandrojcm avatar berlysia avatar calebkish avatar emirotin avatar github-actions[bot] avatar jxom avatar kaispencer avatar marbemac avatar naporin0624 avatar ninebolt6 avatar rutan avatar ryuapp avatar sor4chi avatar theonlytails avatar tseijp avatar yusukebe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vite-plugins's Issues

[@hono/vite-dev-server] Proposal for Specialized Plugin: Cloudflare Workers/Wrangler Integration

Related issue: #24

@hono/vite-dev-server currently supports development servers for most edge environments. However, as we attempt to address issues specific to platforms like Cloudflare Workers/Wrangler, such concerns become more prominent. Similarly, when it comes to features tailored for other edge environments, this can lead to a situation where, for those who want to utilize the Wrangler environment, this plugin becomes overly complex.

Therefore, I have created this issue with the idea that it would be beneficial to first extract specific functionality for Cloudflare Workers/Wrangler as a dedicated plugin. I would appreciate your input on this matter.

What's the correct way to import css?

While using vite plugin I found out that css import from client side script were blocked by hono (or the plugin not sure really)

CleanShot 2024-01-04 at 7โ€ฏ 40 02@2x

My workaround was to exclude css files from the plugin options, like so:

exclude: [
 ...defaultOptions.exclude,
 /(.*\.css$|.*\.css\?t=[\d]+$)/
//                      ^ also considering updates
],

Not sure if this is the best way to handle this, if so wouldn't be better to add it into the default options?

[@hono/vite-dev-server] Hostname/IP does not match certificate's altnames: Host: localhost. is not in the cert's altnames: DNS:httpbin.org, DNS:*.httpbin.org

related: #24

Reproduce code:

import { Hono } from 'hono'

const app = new Hono()

app.get('/httpbin/*', async (c) => {
  const url = new URL(c.req.url);
  return await fetch(
    `https://httpbin.org${url.pathname.replace('/httpbin', '')}`,
    c.req.raw,
  );
});

export default app

Started-up vite server as 8787 and executed npx local-ssl-proxy --key localhost-key.pem --cert localhost.pem --source 8788 --target 8787, Request to https://localhost:8788/httpbin/get via browser. I used mkcert to make localhost certification.

It works on Cloudflare Workers and wrangler dev, but when passing through vite-dev-server, it produces the following error and stops working.

cause: Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: localhost. is not in the cert's altnames: DNS:httpbin.org, DNS:*.httpbin.org
      at new NodeError (node:internal/errors:405:5)
      at Object.checkServerIdentity (node:tls:337:12)
      at TLSSocket.onConnectSecure (node:_tls_wrap:1637:27)
      at TLSSocket.emit (node:events:514:28)
      at TLSSocket.emit (node:domain:489:12)
      at TLSSocket._finishInit (node:_tls_wrap:1038:8)
      at ssl.onhandshakedone (node:_tls_wrap:824:12)
      at TLSWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    reason: "Host: localhost. is not in the cert's altnames: DNS:httpbin.org, DNS:*.httpbin.org",
    host: 'localhost',
    cert: {
      subject: [Object: null prototype],
      issuer: [Object: null prototype],
      subjectaltname: 'DNS:httpbin.org, DNS:*.httpbin.org',
...

Workaround

By rewriting the header's host as follows, it starts working. It seems there is a difference in the behavior of fetch between vite-dev-server and wrangler dev.

app.get('/httpbin/*', async (c) => {
  const url = new URL(c.req.url);
  return await fetch(
    `https://httpbin.org${url.pathname.replace('/httpbin', '')}`,
    {
      headers: {
        ...c.req.raw.headers,
        host: 'httpbin.org', // add this
      },
    },
  );
});

`c.env.ASSETS` is `undefined` in dev server

I'm migrating one of my projects from Workers Site to Pages with Functions, and having trouble with env.ASSETS.fetch. With the following setup (I'll publish a reproduction repo later), GET / returns a 500 error saying TypeError: Cannot read properties of undefined (reading 'fetch') during dev server (i.e., wrangler pages dev -- vite).

// src/index.ts
import { Hono } from "hono";

const app = new Hono().get("/", async (c) => {
  const env = c.env as { ASSETS: { fetch: typeof fetch } };
  const asset = await env.ASSETS.fetch(
    new URL("/assets/static.json", c.req.url)
  ).then((r) => r.json());
  return c.json({ asset });
});

export default app;
// public/assets/static.json
{
  "foo": "Hello world",
  "bar": 42
}
// public/_routes.json
{
  "version": 1,
  "include": ["/*"],
  "exclude": ["/assets/*"]
}
// vite.config.ts
import { type UserConfig } from "vite";
import pages from "@hono/vite-cloudflare-pages";
import devServer, { defaultOptions } from "@hono/vite-dev-server";

export default {
  plugins: [
    pages(),
    devServer({
      exclude: [...defaultOptions.exclude, /^\/assets\/.+/],
    }),
  ],
} satisfies UserConfig;

After building with vite build, however, GET / returns the expected {"asset":{"foo":"Hello world","bar":42}} during preview server with wrangler pages dev dist. So how can I bind env.ASSETS.fetch to Hono's context in dev mode? If it's already possible, a small documentation would be much appreciated (I tried to find relevant options in the two plugins but wasn't successful unfortunately)

[@hono/vite-cloudflare-pages] Importing Node.js Modules Throw Runtime Errors

I'm trying to integrate Supabase into my Hono app built with the Cloudflare Pages template with npm create hono@latest.

However, when trying to do wrangler preview with it, it throws an error like so:

My Errors

โŽ” Starting local server...
[wrangler:inf] Ready on http://127.0.0.1:8787
[wrangler:inf] GET / 200 OK (11ms)
[wrangler:inf] GET /static/style.css 200 OK (13ms)
X [ERROR] TypeError: Cannot read properties of undefined (reading 'from')
at null.
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:27784)
at o
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:9830)
at null.
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:9838)
at null.
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:27452)
at o
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:9830)
at null.
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:9574)
at null.
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:17948)
at _e.dispatch
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:18124)
at Object.fetch
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/dist/_worker.js:1:15426)
at facade_modules_fetch
(file:///C:/Users/LENOVO/Desktop/Programming/work/hono-pages-supabase/.wrangler/tmp/bundle-u0JqXt/middleware-loader.entry.ts:45:16)

[wrangler:inf] GET /tasks 500 Internal Server Error (12ms)

I tried implementing it using the Cloudflare Workers template and it seems to work perfectly fine, so I'm guessing the issue lies in the Vite plugin that bundles the code for Cloudflare Pages in the _worker.js file.

Minimal Reproductions

Here are my minimal repros for this:
Hono Workers Template + Supabase | Deployed Worker Template /tasks Route
Hono Pages Template + Supabase | Deployed Pages Template /tasks Route

[@hono/vite-dev-server] simple bun usage fails

When I do a simple vite configuration to use with hono, like this:

import { defineConfig } from "vite";
import hono from "@hono/vite-dev-server";

export default defineConfig({
  plugins: [hono({ entry: "./server.ts" })],
});

My server.ts:

import { Hono } from "hono";

const application = new Hono();

application.get("*", async (c) => {
  console.log("HERE");
  return c.text("Hello world!");
});

export default application;

Running with bun --bun vite

I got bun default feedback:

image

But my console.log("HERE") is executed. Reproduction: https://codesandbox.io/p/devbox/bun-vite-hono-repro-dwzcnv

Ignore `.wrangler` directory when watching

If you use Vite with Wrangler's getPlatformProxy(), you have to ignore .wrangler from the watch, otherwise it will restart every time the D1 database is updated.

export default defineConfig(() => {
  const proxy = await getPlatformProxy()
  return {
    server: {
      watch: {
        ignored: [/\.wrangler/]
      }
    },
    plugins: [
      honox({
        devServer: {
          plugins: [
            {
              env: proxy.env,
              onServerClose: proxy.dispose
            }
          ]
        }
      }),
      pages()
    ]
  }
})

It is better to ignore it by default in dev-server.

bug(dev-server): with multiple configuration methods, env is overwritten

Whilst looking at making a PR from honojs/honox#83, I have noticed that the value for env used by the dev-server plugin is overwritten depending on the configuration used.

See:

              let env: Env = {}
              console.log('OPTIONS', options)

              if (options?.env) {
                if (typeof options.env === 'function') {
                  env = await options.env()
                } else {
                  env = options.env
                }
              } else if (options?.cf) {
                env = await cloudflarePagesGetEnv(options.cf)()
              }

              if (options?.plugins) {
                for (const plugin of options.plugins) {
                  if (plugin.env) {
                    env = typeof plugin.env === 'function' ? await plugin.env() : plugin.env
                  }
                }
              }

if you supply via root env, and then also cf (albeit deprecated), and then multiple plugins, only the values in the last plugin will be passed through.

Is this intended behaviour? Or should each configuration option extend env

I found this by adding a second plugin in the e2e tests, see below.

export default defineConfig(async () => {
  const { env, dispose } = await getPlatformProxy({ configPath: './wrangler.toml' })

  return {
    plugins: [
      devServer({
        entry: './mock/worker.ts',
        exclude: [...defaultOptions.exclude, '/app/**'],
        plugins: [
          { onServerClose: dispose, env },
          pages({
            bindings: {
              NAME: 'Hono',
            },
          }),
        ],
      }),
    ],
  }
})

This results in only the NAME binding passed through, and those set in wrangler.toml picked up by getPlatformProxy being ignored.

This can be worked around by extending the bindings property of the cloudflare-pages package like so

pages({
            bindings: {
              NAME: 'Hono',
              ...env,
            },
          }),

Is it intended to be able to supply multiple methods of configuration? If so, this code can be updated to extend rather than assign.

Vite dev server crashes if error is introduced in the Hono Server.

If you run vite dev then introduce a syntax error in index.ts and any of the files that are running the Hono server, the dev server crashes and fails to restart, and the process crashes.

Somewhat same motivations as in Rich's words from this issue: vitejs/vite#12375

Ideally the process would stay alive, and gracefully recover once the error is fixed. Even better would be if the server survived, if only to report the error, though that's probably somewhat trickier.

Steps to reproduce:

  1. Clone and run this repo: https://github.com/Blankeos/spend-snap/tree/029cb1bbe64b17c05290b8399772ab60a94ec56b
  2. Introduce a syntax error anywhere in src/server/index.ts or _app.ts
  3. To run the server bun run dev:
    • Currently running it in node: vite
    • Can also run it in Bun bunx --bun vite
  4. Either way, try introducing an error AND both would still crash the dev server without restarts.

System

System Info
System:
    OS: macOS 14.4.1
  Binaries:
    Bun: 1.1.6

Error vite

View Error
9:03:50 PM [vite] page reload src/server/_app.ts
[vite] program reload

/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:1651
  let error = new Error(text);
              ^
Error: Transform failed with 1 error:
/Users/carlo/Desktop/Projects/spend-snap/src/server/_app.ts:13:35: ERROR: Expected ")" but found ";"
    at failureErrorWithLog (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:1651:15)
    at /Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:849:29
    at responseCallbacks.<computed> (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:704:9)
    at handleIncomingPacket (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:764:9)
    at Socket.readFromStdout (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:680:7)
    at Socket.emit (node:events:518:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Socket.Readable.push (node:internal/streams/readable:390:5)
    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)
    at Pipe.callbackTrampoline (node:internal/async_hooks:130:17)
error: script "dev" exited with code 1

Error bunx --bun vite

View Error
9:16:57 PM [vite] page reload src/server/modules/collations/collations.controller.ts
[vite] program reload
1646 |     let { file, line, column } = e.location;
1647 |     let pluginText = e.pluginName ? `[plugin: ${e.pluginName}] ` : "";
1648 |     return `
1649 | ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
1650 |   }).join("");
1651 |   let error = new Error(text);
                     ^
error: Transform failed with 1 error:
/Users/carlo/Desktop/Projects/spend-snap/src/server/modules/collations/collations.controller.ts:4:30: ERROR: Expected ";" but found "("
 errors: [
  {
    "id": "",
    "location": {
      "column": 30,
      "file": "/Users/carlo/Desktop/Projects/spend-snap/src/server/modules/collations/collations.controller.ts",
      "length": 1,
      "line": 4,
      "lineText": "export const collationsControl().basePath(\"/collations\");",
      "namespace": "",
      "suggestion": ";"
    },
    "notes": [],
    "pluginName": "",
    "text": "Expected \";\" but found \"(\""
  }
]

      at failureErrorWithLog (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:1651:15)
      at /Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:849:29
      at /Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:704:9
      at handleIncomingPacket (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:764:9)
      at readFromStdout (/Users/carlo/Desktop/Projects/spend-snap/node_modules/vite/node_modules/esbuild/lib/main.js:680:7)
      at addChunk (node:stream:1953:43)
      at readableAddChunk (node:stream:1907:59)
      at node:stream:32:101
      at node:stream:125:103
error: script "dev" exited with code 1

The errors aren't really important. It's the fact that it closes when there's an error.

Support reading env from `wrangler.toml` in dev server

Currently I have a rudimentary function called getWranglerEnv that reads the env from the wrangler.toml and adds it to the env of the honox dev server. This is a proposal to add this as a plugin.

import pagesBuild from '@hono/vite-cloudflare-pages'
import pagesPlugin from '@hono/vite-dev-server/cloudflare-pages'
import { Env } from 'hono/types'
import honox from 'honox/vite'
import clientBuild from 'honox/vite/client'
import { defineConfig } from 'vite'

export default defineConfig(async ({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [clientBuild()]
    }
  } else {
    return {
      ssr: {
        external: ['react', 'react-dom', 'prop-types', 'react-is', 'hoist-non-react-statics', '@babel/runtime']
      },
      plugins: [
        honox({
          islands: true,
          devServer: {
            env: await getWranglerEnv(),
            plugins: [
              pagesPlugin({
                d1Databases: ['DB'],
                d1Persist: true
              })
            ]
          }
        }),
        pagesBuild()
      ]
    }
  }
})
async function getWranglerEnv(): Promise<Env> {
  const fs = await import('fs/promises')
  const toml = await import('toml')

  const wranglerToml = await fs.readFile('wrangler.toml', 'utf-8')
  const config = toml.parse(wranglerToml)

  console.log("Environment variables loaded from wrangler.toml")
  return config.vars[0]
}

Can't get devServer to work with Qwik & vite-cloudflare-pages

Hello guys,
I'm trying to get a devServer to work with Qwik & Cloudflare pages to render both my Qwik app & my api endpoints under a /functions folder.

Hopefully I'm doing something wrong and there is no bug :)
Thanks in advance for the help and thank you @yusukebe for your awesome contributions! ๐Ÿ™

dev/vite.config.ts:

import { extendConfig } from "@builder.io/qwik-city/vite";
import pages from '@hono/vite-cloudflare-pages'
import baseConfig from "../../vite.config";
import devServer from '@hono/vite-dev-server'
import { getPlatformProxy } from 'wrangler'
import build from '@hono/vite-cloudflare-pages'

export default extendConfig(baseConfig, async ({mode}) => {
    const {env, dispose} = await getPlatformProxy()
    return {
      plugins: [
        devServer({
          adapter:cloudflarePagesAdapter,
          entry: 'src/entry.hono.tsx',
          plugins: [
            { onServerClose: dispose, env },
            pages({ bindings: { NAME: 'Hono', } }),
          ],
        })
      ]
    }
});

vite.config.ts:

 * This is the base config for vite.
 * When building, the adapter config is used which loads this file and extends it.
 */
import { defineConfig, type UserConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
import tsconfigPaths from "vite-tsconfig-paths";
import pkg from "./package.json";

const { dependencies = {}, devDependencies = {} } = pkg as any as {
  dependencies: Record<string, string>;
  devDependencies: Record<string, string>;
  [key: string]: unknown;
};

/**
 * Note that Vite normally starts from `index.html` but the qwikCity plugin makes start at `src/entry.ssr.tsx` instead.
 */
export default defineConfig(({ command, mode }): UserConfig => {
  return {
    plugins: [qwikCity(), qwikVite(), tsconfigPaths()],
    // This tells Vite which dependencies to pre-build in dev mode.
    optimizeDeps: {
      // Put problematic deps that break bundling here, mostly those with binaries.
      // For example ['better-sqlite3'] if you use that in server functions.
      exclude: [],
    },
    // This tells Vite how to bundle the server code.
    ssr:
      command === "build" && mode === "production"
        ? {
            // All dev dependencies should be bundled in the server build
            noExternal: Object.keys(devDependencies),
            // Anything marked as a dependency will not be bundled
            // These should only be production binary deps (including deps of deps), CLI deps, and their module graph
            // If a dep-of-dep needs to be external, add it here
            // For example, if something uses `bcrypt` but you don't have it as a dep, you can write
            // external: [...Object.keys(dependencies), 'bcrypt']
            external: Object.keys(dependencies),
          }
        : undefined,
    server: {
      headers: {
        // Don't cache the server response in dev mode
        "Cache-Control": "public, max-age=0",
      },
    },
    preview: {
      headers: {
        // Do cache the server response in preview (non-adapter production build)
        "Cache-Control": "public, max-age=600",
      },
    },
  };
});

src/entry.hono.tsx:

import { manifest } from "@qwik-client-manifest";
import render from "./entry.ssr";

import { qwikMiddleware } from '@hono/qwik-city'
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { showRoutes } from 'hono/dev'
const app = new Hono()
app.get('*', logger())

app.use('*', qwikMiddleware({ render, qwikCityPlan, manifest}))
app.get('/bar', () => {
  return new Response("Hello, world from hono!");
})

showRoutes(app)

export default app
export const { fetch } = app

here is the error I'm seeing starting the server:

   at shim (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs:165:34)
   at AsyncFunction.RouterOutlet_component_e0ssiDXoeAM (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs:185:24)
   at AsyncFunction.invokeApply (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:3627:22)
   at AsyncFunction.invoke (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:3620:22)
   at eval (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:7206:25)
   at maybeThen (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:388:54)
   at eval (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:7192:14)
   at eval (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:1019:25)
   at safeCall (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:377:21)
   at executeComponent (/Users/greg/src/github.com/homelifedata/qwik/node_modules/@builder.io/qwik/core.mjs:1019:10) {
 hostElement: <ref *1> MockElement {
   nodeType: 111,
   _qc_: {
     '$flags$': 4,
     '$id$': '',
     '$element$': [Circular *1],
     '$refMap$': [],
     li: [],
     '$tasks$': null,
     '$seq$': null,
     '$slots$': [],
     '$scopeIds$': null,
     '$appendStyles$': null,
     '$props$': {},
     '$vdom$': null,
     '$componentQrl$': [AsyncFunction],
     '$contexts$': null,
     '$dynamicSlots$': null,
     '$parentCtx$': [Object],
     '$realParentCtx$': [Object]
   }
 }
}

[@hono/vite-dev-server] Best way to develop locally?

I'm using a basic vite-dev-server setup (see below). abc gets caught within the vite process and vite displays the error and watches the file system and restarts the server. But outside doesn't get caught the same way, and the vite process crashes. What is the recommended way to run a local dev server (via nodemon?)

export default defineConfig({
  plugins: [
    devServer({
      entry: 'src/index.ts', // The file path of your application.
    }),
  ],
});
import { Hono } from 'hono';
const app = new Hono();
outside;
app.get('/', (c) => {
  abc;  
  return c.text('Hello Vitess!');
});
export default app;

Support caches api

My app is using caches with cloudflare but it seems like not supported in hono vite plugin, it shows undefined when I call it

Tried below code but it doesn't work

const { env, dispose, caches } = await getPlatformProxy()
Object.defineProperties(globalThis, {
    caches: { value: caches, writable: true, configurable: true },
    scheduler: { // To use scheduler.wait API
      value: {
        wait: () => {
        },
      },
      writable: true,
      configurable: true,
    },
  })

Got TypeError: 'get' on proxy: property 'default' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Cache2>' but got '#<Cache2>')

Any plan to support this api?

Hono ViteDevServer takes 2s to serve index html

Hiho,
First of all, I like Hono (played around with it last month), especially the feature that it can run in a service worker...!

If Hono has such great speed, this also needs to apply in the development environment: There is a bottleneck in the current dev-server implementation, it always takes around two seconds on Windows (Node v21.7) to return the index HTML.

Is on-demand TypeScript compilation taking too much time? Should I use Bun for faster server responses?

Reproduction:
0. Run npm create hono@latest - choose x-basic & npm & Y to install

  1. npm run dev
  2. open localhost:5173 with dev tools network tab open
  3. (trigger a) refresh: /-document takes about 2000ms load

grafik

Yesterday, I've tried to make Vite a middleware for Hono instead:
(based on https://github.com/bluwy/create-vite-extra/blob/master/template-ssr-vanilla/server.js#L23)

  const { createServer } = await import("vite")
  vite = await createServer({
    server: { middlewareMode: true },
    appType: "custom",
    base
  })
  const vmw = (c, body) => new Promise(resolve => vite.middlewares({
    headers: c.req.raw.headers,
    url: c.req.url,
    body,
  }, {
    ...c.res, 
    setHeader: c.header,
  }, resolve))
  // inject into nodemon/tsx reloaded server
  app.use(async (c, next) => {
    await next()
    return vmw(c, await c.req.parseBody())
  })

It does not serve the client files yet, probably req.url handling being different...?

Here is a related discussion:
https://github.com/orgs/honojs/discussions/1520

I think it would be nice to have two utilities:

  • convertHonoToConnectMiddleware (use hono nested into an express server)
  • convertConnectToHonoMiddleware (use express e.g. vite dev server middleware nested into hono server)

These come in very handy when trying to migrate projects. Or when adapting existing Connect middleware until it is rewritten for performance reasons (in this case, hono-vite-dev-server has matured).

Static assets from '/public/' dir does not handled

Static assets from '/public/' dir does not handled well.
i.e. having file in '/public/robots.txt' does not work as expected,
it produces 404 error as it 's intercepted by this dev. server plugin but not vite.

temp workaround atm. was using option:

exclude: ['.*.ts', '.*.tsx', '/@.+', '/node_modules/.*', '/inc/.*', '.*.txt', '.*.ico' ], - added exlude paths.

[@hono/vite-cloudflare-pages] Support to serve static files on root directory

Ref: honojs/starter#31,

I want to use a public directory with file-based routing on HonoX.
But @hono/vite-cloudflare-pages only supports favicon.ico in the root directory, other files must be placed under static directory.
https://github.com/honojs/vite-plugins/blob/60d79860626d67622a38da138c0f12fcc33424ae/packages/cloudflare-pages/src/entry.ts#L39C1-L40C39

This makes it difficult to use robots.txt and sitemap.xml.
It's possible to serve them manually, but it is troublesome to set them one by one.

It's better if a public directory can be freely routed.
In addition, it would be even better if it was realized that like #110.

[@hono/vite-dev-server] feature request: Support wrangler.toml

Thank you for developing such an incredible toolset and web framework!

I am considering switching from Wrangler to Vite + dev-Server. However, since my wrangler.toml file already contains numerous environment variables and bindings, I thought it would be beneficial if these could be automatically reflected in @hono/vite-dev-server.

Items I would like to be automatically loaded:

  • kv_namespaces
  • vars
  • durable_objects.bindings
  • queues.producers
  • queues.consumers
  • d1_databases

Btw, Wrangler seems to be using @iarna/toml to read toml file.

[@hono/vite-cloudflare-pages] Serve static assets using `_routes.json`

It is currently using serveStatic() ( env.ASSETS.fetch() ) to serve static assets in Cloudflare Pages, but there are some issues with this.

  1. Consume function requests number of times.

The number of function calls is consumed because the function is executed every time there is a request for an asset.
However, access to static assets is unlimited.

image

The Free plan combines requests for Workers and Pages Functions. Requests to static assets on Pages will continue to be free and unlimited.

  1. Asset access is slow.

Cloudflare Page Functions are fast enough, but there is some overhead compared to direct asset access.

Therefore, I think it needs to serve assets using _routes.json.
https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file

{
  "version": 1,
  "include": ["/*"],
  "exclude": [
    "/static/*",
    "/favicon.ico"
  ]
}

When using @hono/vite-dev-server in Cloudflare Workers development, there is a misjudgment in hono/adapter's env().

When using @hono/vite-dev-server for live reloading settings during local development with Cloudflare Workers, environment variables defined in wrangler.toml are not recognized.

Specifically, if wrangler.toml contains settings like the following:

[vars]
NAME="test"

The following code will recognize the variable:

app.get("/", async (c) => {
    return c.text(c.env.NAME) // => test
}

However, it is not recognized in the env() function of the Adapter Helper.

import { env } from 'hono/adapter'

app.get('/', (c) => {
  const { NAME } = env<{ NAME: string }>(c)
  return c.text(NAME) // => `undefined`(empty response)
})

The cause is that global?.WebSocketPair is undefined for getRuntimeKey() in env() to determine workerd via @hono/vite-dev-server's devServer(), and getRuntimeKey() returns node.
cf. https://github.com/honojs/hono/blob/v4.0.8/src/helper/adapter/index.ts#L33-L57

I have made a fix that works locally as a workaround, but since I have no knowledge of Vite, I am not sure if this is the correct approach. Here is my workaround commit: natsumesou@717b19a

Please advise if you have any suggestions :)
Thank you!

[@hono/vite-dev-server] add bun websocket support

dev server does not run websocket:

import { Hono } from "hono";
import { createBunWebSocket } from "hono/bun";

const { upgradeWebSocket, websocket } = createBunWebSocket();

const app = new Hono();

const ws = app.get(
    "/ws",
    upgradeWebSocket((c) => {
        console.log("WebSocket connected");
        let intervalId: Timer;
        return {
            onOpen(_event, ws) {
                intervalId = setInterval(() => {
                    ws.send(new Date().toString());
                }, 200);
            },
            onClose() {
                clearInterval(intervalId);
            },
        };
    }),
);

export default {
    fetch: app.fetch,
    websocket,
};

desired behaviour: should connect to websocket server when new WebSocket("ws://localhost:5173/ws") is called
current behaviour: fetch requests work fine, websocket request hangs

Error running dev server

I've setup my-app using the Hono CLI and then changed it following the instructions here. When I run npm exec vite I get this error:

failed to load config from D:\my\temp\hono\my-app\vite.config.ts
error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module D:\my\temp\hono\my-app\node_modules\@hono\vite-dev-server\dist\dev-server.js from D:\my\temp\hono\my-app\node_modules\@hono\vite-dev-server\dist\index.cjs not supported.

My vite.config.ts is:

import { defineConfig } from "vite";
import devServer from "@hono/vite-dev-server";

export default defineConfig({
  plugins: [
    devServer({
      entry: "src/index.ts", // The file path of your application.
    }),
  ],
});

package.json is:

{
  "scripts": {
    "dev": "vite"
  },
  "dependencies": {
    "@hono/node-server": "^1.4.1",
    "hono": "^3.12.6"
  },
  "devDependencies": {
    "@hono/vite-dev-server": "^0.4.0",
    "tsx": "^3.12.2",
    "vite": "^5.0.12"
  }
}

and src/index.ts is:

import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => {
  return c.text("Hello Hono!");
});

export default app;

I'm using Windows 10, node 20.1.0, and npm 9.6.4.

Any ideas on how I can fix the error? TIA

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.