BUN,HONO,VITE,TAILWINDCSS:刚刚揭示了一种惊人的组合!
#javascript #网络开发人员 #typescript #bunjs

Bun很棒,是的!,Lately每个人都惊讶,我今天能够玩耍,我发现与HonoViteTailwindCSSTailwindCSS一起使用它很棒。

不进一步的ADO,我在这里向您展示了我所做的事情。

首先,用bun创建一个项目,其方式比平常快。

bun create hono my-hono-app
cd my-hono-app
bun install

出于演示目的,我们将使用一些流行的液体,例如jose

bun add jose

tsconfig.json稍微更改为:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "strict": true,
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
    "types": [
      "bun-types"
    ],
  }
}

让我们放一些使用jose的代码,例如由我们自己创建一个JWT,我们将其放在src/core.ts

import * as jose from "jose";

const secret = "🔥🔥🔥🔥🔥🔥🔥🔥🔥";
const algo = "HS512";

const secretBytes = new TextEncoder().encode(secret);
export const secretB64 = btoa(
  Array.from(secretBytes, (x) => String.fromCodePoint(x)).join("")
);

export const createJWT = async () => {
  return await new jose.SignJWT({
    claims: {
      userId: "ridho",
    },
  })
    .setProtectedHeader({ alg: algo })
    .setAudience("urn:audience")
    .setIssuer("urn:issuer")
    .setSubject("urn:subject")
    .setIssuedAt()
    .setExpirationTime("5m")
    .sign(secretBytes);
};

从上面的代码中记下有关如何基于此MDN指南创建base64字符串的内容。稍后,我们可以通过将令牌和秘密粘贴到jwt.io中。

现在让我们修改src/index.ts中的服务器条目文件。

import { Hono } from "hono";
import { createJWT, secretB64 } from "./core";

const app = new Hono();

app.get("/", async (c) =>
  c.text(`Secret: ${secretB64} JWT: ${await createJWT()}`)
);

export default app;

是的,它已经准备好了。我们现在可以启动开发服务器:

bun run --hot src/index.ts

太好了,这是非常简单而简单的!只需很少的努力和下面的几个文件,我们就可以每秒提供约100K的请求。

tree -I node_modules 
.
├── bun.lockb
├── package.json
├── README.md
├── src
│   ├── core.ts
│   └── index.ts
└── tsconfig.json

2 directories, 6 files

好吧,让我们走得更远。我们希望提供HTML,而不是简单的文本响应。这是:

import { html } from "hono/html";

app.get("/hello", (c) =>
  c.html(html`<!DOCTYPE html>
    <html>
      <head>
        <title>Simple demo</title>
      </head>
      <body>
        <h1>Ok</h1>
      </body>
    </html>`)
);

我想和jsx一起编写内容。好的,也很容易。首先创建我们的jsx文件hello.tsx如下:

export function Hello() {
  return (
    <div>
      <h1>Hello there!</h1>
    </div>
  );
}

并像往常一样使用它,在这种简单的情况下,我们将JSX放入我们以前的HTML身体:

import { html } from "hono/html";
import { jsx } from "hono/jsx";
import { Hello } from "./hello";

app.get("/hello", (c) => {
  const content = jsx(Hello, {});  // <-- HERE IS our JSX content
  return c.html(html`<!DOCTYPE html>
    <html>
      <head>
        <title>Simple demo</title>
      </head>
      <body>
        ${content}
      </body>
    </html>`);
});

是的,这太棒了,还有更多!我们可以拥有伟大而著名的Vite及其所有东西,例如也可以工作。

有作者正在积极开发的koude5,并且可以肯定的是它的准备就绪。

在这段时间里,我探索了如何手动将VITE与到目前为止的所有内容一起整合。这只是简短的步骤,我相信您可以跟进。

添加必要的深度:

bun add --dev vite tailwindcss postcss autoprefixer

init tailwindcss config:

bunx tailwindcss init --esm --postcss

创建vite.config.ts

import { defineConfig } from "vite";

export default defineConfig({
  build: {
    manifest: true,
    rollupOptions: {
      input: "/src/client.tsx",
    },
  },
});

src/client.tsx中是我们的客户端代码由Vite居住和管理的地方。目前,它仅包含导入到partwind css条目文件。

tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./src/**/*.tsx"],
  theme: {
    extend: {},
  },
  plugins: [],
}

postcss.config.js

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

type=module添加到package.json

{
  "type": "module",
  "scripts": {
    "dev": "bun run --hot src/index.ts",
    "vite-dev": "vite",
    "build": "vite build",
    "serve": "NODE_ENV=production bun run src/index.ts"
  },
  "dependencies": {
    "hono": "^3.5.4",
    "jose": "latest"
  },
  "devDependencies": {
    "autoprefixer": "^10.4.15",
    "bun-types": "^0.6.2",
    "postcss": "^8.4.29",
    "tailwindcss": "^3.3.3",
    "vite": "^4.4.9"
  }
}

添加或修改targetmodulemoduleResolutiontsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true,
    "strict": true,
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
    "types": [
      "bun-types"
    ],
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
  }
}

src/style.css

@tailwind base;
@tailwind components;
@tailwind utilities;

src/client.tsx

import "./style.css"

src/hello.tsx

export function Hello() {
  return (
    <div class="text-2xl text-red-600 grid h-[100dvh] items-center justify-center text-center">
      <div>
        <h1 class="text-4xl font-bold">Hello there!</h1>
        <p class="font-mono">
          Bun, Hono, Vite, TailwindCSS <br />
          🔥🔥🔥🔥🔥🔥🔥🔥🔥
        </p>
      </div>
    </div>
  );
}

src/index.ts

import { Hono } from "hono";
import { serveStatic } from "hono/bun";
import { html, raw } from "hono/html";
import { jsx } from "hono/jsx";

import { createJWT, secretB64 } from "./core";
import { Hello } from "./hello";

const app = new Hono();

app.use("/assets/*", serveStatic({ root: "./dist" }));

app.get("/", async (c) =>
  c.text(`Secret: ${secretB64} JWT: ${await createJWT()}`)
);

const isProd = process.env.NODE_ENV === "production";

const manifestPath = "../dist/manifest.json";
const cssFile = isProd
  ? (await import(manifestPath)).default["src/client.tsx"]?.css?.at(0)
  : null;

app.get("/hello", (c) => {
  const content = jsx(Hello, {});
  return c.html(html`<!DOCTYPE html>
    <html>
      <head>
        <title>Simple demo</title>
        ${cssFile ? raw(`<link rel="stylesheet" href="${cssFile}">`) : null}
      </head>
      <body class="bg-green-200">
        ${content}
        ${isProd
          ? null
          : raw(`<script
                type="module"
                src="http://localhost:5173/@vite/client"
            ></script>
            <script
                type="module"
                src="http://localhost:5173/src/client.tsx"
            ></script>`)}
      </body>
    </html>`);
});

export default app;

开始开发,在单独的终端上启动bun和vite:

bun run vite-dev
bun run dev

用于生产,构建和运行:

bun run build
bun run serve

就是这样。

谢谢您的阅读,祝您周末愉快!