skip to Main Content

I’m writing a plugin in the form of a default export like the code below. I want to be able to pass an object as default plugin options, this way:

// Normal call without options
Alpine.plugin(MyPlugin);

// Call with options
Alpine.plugin(MyPlugin.defaults({ foo: "bar" }));

I can easly solve adding let defaultOptions outside the scope of the plugin itself (that is, in the root of the module):

// src/myplugin.ts

let defaultOptions: MyPluginOptions;

const MyPlugin = (Alpine: Alpine) => {
  // Use defaultOptions here
};

// Expose a way to set default options
MyPlugin.defaults = (options: MyPluginOptions) => {
  defaultOptions = options;

  return MyPlugin;
};

export default MyPlugin;

Do I have any other option to move it inside the plugin itself?

2

Answers


  1. Calling MyPlugin.defaults, if used like this, should not globally set the defaultOptions for all usages of the plugin. Instead, it should create a new plugin that is configured with those defaults. You can use the factory pattern for this:

    type Plugin = {
      // basic call signature
      (_: Alpine): void;
      // extend options
      withDefaults(options: MyPluginOptions): Plugin;
    }
    
    function makeMyPlugin(defaultOptions: MyPluginOptions): Plugin {
      const MyPlugin = (Alpine: Alpine) => {
        // Use defaultOptions here
      };
    
      // Expose a way to create a new plugin with extended default options
      MyPlugin.withDefaults = (options: MyPluginOptions): Plugin => {
        return makeMyMyPlugin({...defaultOptions, ...options});
      };
    
      return MyPlugin;
    }
    
    export default makeMyPlugin({});
    

    This even lets you chain the plugin creation:

    const pluginA = MyPlugin.withDefault({foo: "bar"});
    const pluginB = pluginA.withDefaults({baz: "quux"});
    const pluginC = MyPlugin.withDefaults({foo: "quux"}).withDefaults({baz: "bar"});
    const pluginD = MyPlugin;
    
    Login or Signup to reply.
  2. you can move the defaultOptions variable inside the plugin itself by using a closure to encapsulate the variable within the scope of the MyPlugin function.

    const MyPlugin = (Alpine: Alpine) => {
      let defaultOptions: MyPluginOptions;
    
      // Use defaultOptions here
    
      // Expose a way to set default options
      MyPlugin.defaults = (options: MyPluginOptions) => {
        defaultOptions = options;
        return MyPlugin;
      };
    
      return MyPlugin;
    };
    
    export default MyPlugin;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search