将EJ与Vite一起使用
#javascript #网络开发人员 #edge #vite

为什么要将EJ与Vite一起使用?

让我们考虑一个示例场景:您正在构建一个将使用 cdn 边缘位置运行的Web应用程序,使用 Cloudflare工人。在这种情况下,您可能有以下要求:

  • 您需要为某些第三方网站配置反向代理,例如 Framer Intercom intercom helpdesk 等。
  • 您应该能够注入自定义html/js摘要 进入这些网站的页面。
  • 代码片段应在不同的环境中正常运行,例如生产 test/qa
  • 要优化应用程序捆绑包,必须预编译这些模板而不是包括模板库。

在这种情况下,将EJ与Vite结合使用可能是一个有益的选择。

它是什么样子的?

使用html/js语法突出显示和代码完成(views/analytics.ejs),将HTML摘要方便地放入单独的文件中:

<script async src="https://www.googletagmanager.com/gtag/js?id=<%- env.GA_MEASUREMENT_ID %>"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag("js", new Date());
  gtag("config", "<%- env.GA_MEASUREMENT_ID %>");
</script>

当CloudFlare Worker脚本将其注入(HTML)登陆页面上的(

import { Hono } from "hono";
import analytics from "../views/analytics.ejs";

export const app = new Hono<Env>();

// Serve landing pages, inject Google Analytics
app.use("*", async ({ req, env }, next) => {
  const url = new URL(req.url);

  // Skip non-landing pages
  if (!["/", "/about", "/home"].includes(url.pathname)) {
    return next();
  }

  const res = await fetch("https://example.framer.app/", req.raw);

  return new HTMLRewriter()
    .on("body", {
      element(el) {
        el.onEndTag((tag) => {
          try {
            tag.before(analytics(env), { html: true });
          } catch (err) {
            console.error(err);
          }
        });
      },
    })
    .transform(res.clone());
});

如何使用VITE预编译EJS模板?

安装ejs@types/ejs npm模块作为开发依赖项(yarn add ejs @types/ejs -D)。

将以下插件添加到您的vite.config.ts文件:

import { compile } from "ejs";
import { readFile } from "node:fs/promises";
import { relative, resolve } from "node:path";
import { defineConfig } from "vite";

export default defineConfig({
  ...

  plugins: [
    {
      name: "ejs",
      async transform(_, id) {
        if (id.endsWith(".ejs")) {
          const src = await readFile(id, "utf-8");
          const code = compile(src, {
            client: true,
            strict: true,
            localsName: "env",
            views: [resolve(__dirname, "views")],
            filename: relative(__dirname, id),
          }).toString();
          return `export default ${code}`;
        }
      },
    },
  ],
});

如何使.ejs进口与打字稿一起使用?

  1. **/*.ejs添加到tsconfig.json文件中包含的文件的列表中。
  2. 向您添加以下类型声明global.d.ts文件:
declare module "*.ejs" {
  /**
   * Generates HTML markup from an EJS template.
   *
   * @param locals an object of data to be passed into the template.
   * @param escape callback used to escape variables
   * @param include callback used to include files at runtime with `include()`
   * @param rethrow callback used to handle and rethrow errors
   *
   * @return Return type depends on `Options.async`.
   */
  const fn: (
    locals?: Data,
    escape?: EscapeCallback,
    include?: IncludeCallback,
    rethrow?: RethrowCallback,
  ) => string;
  export default fn;
}

koude9是一个全面的全堆栈应用程序项目模板,与所有上述功能(位于/edge文件夹中)预先配置。

如果您需要在Web基础架构和DevOps方面有任何帮助,请随时在CodementorDiscord上与我联系。我在这里帮忙!愉快的编码!

参考