aboutsummaryrefslogtreecommitdiff
path: root/docs/runtime/plugins.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/runtime/plugins.md')
-rw-r--r--docs/runtime/plugins.md104
1 files changed, 97 insertions, 7 deletions
diff --git a/docs/runtime/plugins.md b/docs/runtime/plugins.md
index 0286c7887..f2e0d7c77 100644
--- a/docs/runtime/plugins.md
+++ b/docs/runtime/plugins.md
@@ -17,7 +17,7 @@ const myPlugin: BunPlugin = {
};
```
-Plugins have to be registered before any other code runs! To achieve this, use the `preload` option in your [`bunfig.toml`](/docs/runtime/configuration). Bun automatically loads the files/modules specified in `preload` before running a file.
+Plugins have to be registered before any other code runs! To achieve this, use the `preload` option in your [`bunfig.toml`](/docs/runtime/bunfig). Bun automatically loads the files/modules specified in `preload` before running a file.
```toml
preload = ["./myPlugin.ts"]
@@ -45,7 +45,7 @@ plugin(
);
```
-Bun's plugin API is based on [esbuild](https://esbuild.github.io/plugins). Only [a subset](/docs/bundler/vs-esbuild#plugin-api) of the esbuild API is implemented, but some esbuild plugins "just work" in Bun, like the official [MDX loader](https://mdxjs.com/packages/esbuild/):
+Bun's plugin API is loosely based on [esbuild](https://esbuild.github.io/plugins). Only [a subset](/docs/bundler/vs-esbuild#plugin-api) of the esbuild API is implemented, but some esbuild plugins "just work" in Bun, like the official [MDX loader](https://mdxjs.com/packages/esbuild/):
```jsx
import { plugin } from "bun";
@@ -84,15 +84,20 @@ plugin({
});
```
-With this plugin, data can be directly imported from `.yaml` files.
+Register this file in `preload`:
+
+```toml#bunfig.toml
+preload = ["./yamlPlugin.ts"]
+```
+
+Once the plugin is registered, `.yaml` and `.yml` files can be directly imported.
{% codetabs %}
```ts#index.ts
-import "./yamlPlugin.ts"
-import {name, releaseYear} from "./data.yml"
+import data from "./data.yml"
-console.log(name, releaseYear);
+console.log(data);
```
```yaml#data.yml
@@ -127,7 +132,7 @@ In this case we're using `"object"`—a built-in loader (intended for use by plu
---
- `ts`
-- `.ts` `.mts` `cts`
+- `.ts` `.mts` `.cts`
- Transform TypeScript then transpile
---
@@ -212,6 +217,91 @@ import MySvelteComponent from "./component.svelte";
console.log(mySvelteComponent.render());
```
+## Virtual Modules
+
+{% note %}
+
+This feature is currently only available at runtime with `Bun.plugin` and not yet supported in the bundler, but you can mimick the behavior using `onResolve` and `onLoad`.
+
+{% /note %}
+
+To create virtual modules at runtime, use `builder.module(specifier, callback)` in the `setup` function of a `Bun.plugin`.
+
+For example:
+
+```js
+import { plugin } from "bun";
+
+plugin({
+ name: "my-virtual-module",
+
+ setup(build) {
+ build.module(
+ // The specifier, which can be any string
+ "my-transpiled-virtual-module",
+ // The callback to run when the module is imported or required for the first time
+ () => {
+ return {
+ contents: "console.log('hello world!')",
+ loader: "js",
+ };
+ },
+ );
+
+ build.module("my-object-virtual-module", () => {
+ return {
+ exports: {
+ foo: "bar",
+ },
+ loader: "object",
+ };
+ });
+ },
+});
+
+// Sometime later
+// All of these work
+import "my-transpiled-virtual-module";
+require("my-transpiled-virtual-module");
+await import("my-transpiled-virtual-module");
+require.resolve("my-transpiled-virtual-module");
+
+import { foo } from "my-object-virtual-module";
+const object = require("my-object-virtual-module");
+await import("my-object-virtual-module");
+require.resolve("my-object-virtual-module");
+```
+
+### Overriding existing modules
+
+You can also override existing modules with `build.module`.
+
+```js
+import { plugin } from "bun";
+build.module("my-object-virtual-module", () => {
+ return {
+ exports: {
+ foo: "bar",
+ },
+ loader: "object",
+ };
+});
+
+require("my-object-virtual-module"); // { foo: "bar" }
+await import("my-object-virtual-module"); // { foo: "bar" }
+
+build.module("my-object-virtual-module", () => {
+ return {
+ exports: {
+ baz: "quix",
+ },
+ loader: "object",
+ };
+});
+require("my-object-virtual-module"); // { baz: "quix" }
+await import("my-object-virtual-module"); // { baz: "quix" }
+```
+
## Reading the config
Plugins can read and write to the [build config](/docs/bundler#api) with `build.config`.