创建插件
创建你自己的插件来扩展 Lume 的指南
Lume 可以通过添加更多 loaders, engines, processors 等来轻松扩展。插件提供了一个简单的接口,用于扩展 Lume,而无需在 _config.ts
文件中编写太多代码。
插件只是一个函数,它在第一个参数中接收一个 lume 实例,以便配置和注册新的元素。
简单的插件示例
假设我们在 _config.ts
文件中有以下代码,用于向所有 CSS 页面添加版权横幅:
// _config.ts
import lume from "lume/mod.ts";
const site = lume();
function addBanner(content: string): string {
const banner = "/* © This code belongs to ACME inc. */";
return banner + "\n" + content;
}
site.process([".css"], (pages) => {
for (const page of pages) {
page.content = addBanner(page.content as string);
}
});
export default site;
我们可以将这段代码封装在一个插件中,甚至可以包含一些配置:
// my-plugins/css_banner.ts
interface Options {
message: string;
}
export default function (options: Options) {
function addBanner(content: string): string {
const banner = `/* ${options.message} */`;
return banner + "\n" + content;
}
return (site: Site) => {
site.process([".css"], (pages) => {
for (const page of pages) {
page.content = addBanner(page.content as string);
}
});
};
}
现在,我们可以通过这种方式在 _config.ts
文件中使用它:
import lume from "lume/mod.ts";
import cssBanner from "./my-plugins/css_banner.ts";
const site = lume();
site.use(cssBanner({
message: "© This code belongs to ACME inc.",
}));
export default site;
插件不能做任何你在 _config.ts
文件中做不到的事情,但它们提供了一个更好的接口来组织和重用你的代码。更好的是:与他人分享它。
查看 Lume 插件仓库 获取更高级的示例。
Hooks
一些插件公开 hooks,这些 hooks 可以被其他插件或在 _config.ts
文件中调用。Hook 只是一个函数,它可以做任何事情,例如更改插件的配置。Hooks 存储在 site.hooks
中。让我们在 css_banner
插件中创建一个 hook 来更改消息:
// my-plugins/css_banner.ts
interface Options {
message: string;
}
export default function (options: Options) {
function addBanner(content: string): string {
const banner = `/* ${options.message} */`;
return banner + "\n" + content;
}
return (site: Site) => {
// 添加一个 hook 来更改消息
site.hooks.changeCssBanner = (message: string) => {
options.message = message;
};
site.process([".css"], (page) => {
page.content = addBanner(page.content as string);
});
};
}
现在可以在插件安装后更改消息:
import lume from "lume/mod.ts";
import cssBanner from "./my-plugins/css_banner.ts";
const site = lume();
site.use(cssBanner({
message: "© This code belongs to ACME inc.",
}));
site.hooks.changeCssBanner("This code is open source");
export default site;
或者我们可以从其他插件调用这个 hook:
// my-plugins/open_source.ts
export default function () {
return (site: Site) => {
if (!site.hooks.changeCssBanner) {
throw new Error("This plugin requires css_banner to be installed before");
// 此插件需要先安装 css_banner
}
site.hooks.changeCssBanner("This code is open source");
};
}
import lume from "lume/mod.ts";
import cssBanner from "./my-plugins/css_banner.ts";
import openSource from "./my-plugins/open_source.ts";
const site = lume();
site.use(cssBanner({
message: "© This code belongs to ACME inc.",
}));
site.use(openSource());
export default site;
发布插件
如果你创建了一个插件并想让其他人使用它,由于 HTTP 导入和 Deno 原生的 TypeScript 支持,这非常简单。你只需要通过 HTTP URL 使你的代码可访问。
这是一些建议列表:
- 使用
lume/
标识符从 Lume 导入模块。例如,假设你的插件使用merge
工具函数。而不是像这样导入完整的 URL:
import { merge } from "https://deno.land/x/lume@v2.2.0/core/utils/object.ts";
最好使用 lume/
标识符:
import { merge } from "lume/core/utils/object.ts";
这避免了项目中加载的 Lume 版本重复,因为 lume/
标识符在 import maps 中配置(记住在你的 import maps 中包含此条目)。
使用 HTTP 包注册表,例如
deno.land/x
。或者,你可以使用 jsDelivr 从 GitHub 仓库提供文件并确保可靠性(即使 GitHub 仓库被删除,它们也会被永久缓存 even if the GitHub repository is deleted)。不推荐使用 JSR,因为它不支持 HTTP 导入(无法导入 Lume 类型),有 bug 的 import maps 行为,以及平台自动进行的代码更改,这些更改可能会导致意外的 bug。
一旦你的插件发布,请告诉我们!!你可以创建一个 PR 到 awesome-lume 仓库。