unjs / nitro

Next Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.
https://nitro.unjs.io
MIT License
5.89k stars 496 forks source link

Improve the module system #2688

Closed Barbapapazes closed 1 month ago

Barbapapazes commented 1 month ago

Describe the feature

This is an open discussion to track the module system's progress and centralize information.

Hello,

The current implementation of the module system is somewhat limited.

I propose a change (https://github.com/unjs/nitro/pull/2686) to make the module system more similar to Nuxt's, with auto-generated types based on the module options.

interface ModuleOptions {
  bar: string;
  foo: {
    baz: string;
  };
}

export default defineNitroModule<ModuleOptions>({
  name: "playground",
  configKey: "playground",
  setup: (nitro, moduleOptions) => {},
});

This will generate type augmentation for NitroConfig, enabling autocompletion in nitro.config.ts:

import { defineNitroConfig } from "nitropack/config";

export default defineNitroConfig({
  playground: {
    bar: "bar",
    foo: {
      baz: "baz",
    },
  },
});

In the previous snippet, an error will occur because foo must be an object.

However, the module system could also be reworked to resemble a Vite plugin (https://github.com/unjs/nitro/pull/2686#issuecomment-2305913286).

interface ModuleOptions {
  bar: string;
  foo: {
    baz: string;
  };
}

export default function moduleIndex(moduleOptions: ModuleOptions) {
  return {
    name: "playground",
    setup: (nitro) => {
      console.log("Hello from playground/modules/index.ts");

      const options = {
        ...{
          foo: "baz",
        },
        ...moduleOptions,
      } satisfies ModuleOptions;
    },
  };
}

And here's the corresponding nitro.config.ts:

import { defineNitroConfig } from "nitropack/config";
import moduleIndex from "./modules/index";

export default defineNitroConfig({
  modules: [
    moduleIndex({
      bar: "bar",
      foo: {
        baz: "baz",
      },
    }),
  ],
});

Additional information