Skip to content

Extend Deno with plugins #28126

Description

@CyanChanges

A way to extend Deno with plugins.

Like Bun Plugins

Deno plugins is able to modify the import(require) logic, like:

  • Handle import module load (for example, matching /\.(yaml|yml)$/ to implement a custom yaml file loader)
  • Handle import resolutions
  • Register virtual modules (like register #db and export database connection)
  • Purge Module Cache (allowing customized hmr)

deno plugins might be under a permission flag to prevent abuse.

Example Use cases

interface ResolvedModule {
  href: URL, // module url, like `npm:zod`, `file:///home/user/loader/tree.ts`
}

interface Module {
  exports: any, // module exports
  type: "module" | "commonjs" // module type
}

interface OnLoadOptions {
  specifier: string, // import specifier, like "`./tree.ts`"
  attributes: object, // import attributes, like `{ with: { type: "yaml" }}`
  origin: URL, // which module tries import this like `file:///home/user/loader/mod.ts`
  next(resolved: ResolvedModule): Promise<Module> // 
}

For example, implementing YAML loader:

// function
Deno.plugin(async (loader) => {
    const { load } = await import("js-yaml");

    loader.onLoad({ match: /\.(yaml|yml)$/ }, async (path, _options: OnLoadOptions) {
      return {
        exports: load(await Deno.readTextFile(path)),
        type: "module"
      }
    })
})

// object 
Deno.plugin({
  name: 'yaml-loader',
  async setup(loader) {
    const { load } = await import("js-yaml");

    loader.onLoad({ match: /\.(yaml|yml)$/ }, async (module: ResolvedModule, _options: OnLoadOptions) {
      const { path } = module
      return {
        exports: load(await Deno.readTextFile(path)),
        type: "module"
      }
    })
  }
})

And virtual module (override could existing module):

Deno.plugin(async (loader) => {
  const db = drizzle(...)
  const mod = await loader.module('#db', (attributes: object, next: (attributes: object) => Promise<Module>) => { // next for default resolution
    return {
      exports: db,
      type: "module"
    }
  })
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions