Extensibility

Quokka.js is easily extensible via user defined plugins.

Once your plugin is ready, you may use it by specifying the name of the plugin file or the plugin node module via the plugins setting right in your Quokka file, or in your project’s package.json file, or in the Quokka global config file.

API

Quokka plugin is a CommonJS module that should expose an object with a couple of functions:

module.exports = {
  
  before: config => {
    
  },
  
  beforeEach: config => {
      
  }
  
};

When possible, Quokka.js re-uses the same node.js process for running your code. The before function code is executed once per process, and is the best place to initialize things once per process. For example, Quokka uses the function to set up Babel and ts-node register hooks.

The beforeEach function gets executed before every run, potentially every key stroke. This is the best place to run some cleanup code, or some initialization code required every run (ideally it needs to be fast).

The config argument object passed to the both of the functions is the final configuration object (the result of merging Quokka settings from various locations).

If your plugin requires some configuration options from a user, you may allow users to specify the options under your plugin’s setting name in the configuration:

{
    "myPlugin": {
        "mySetting": "myValue"
    }
}

and then access it in your plugin:

// myPlugin
module.exports = {
  
  before: config => {
    console.log(config.myPlugin.mySetting); // myValue
  }
  
};

You may also change the config object, for example, you could write a plugin that adds an alternative babel support and prevent Quokka from running the built-in one, it is possible to write:

module.exports = {
  
  before: config => {
    delete config.babel; 
  }
  
};

Plugin ideas and recommendations

If you think that your plugin may be useful to others, you may create and publish a node module with it. The suggested module naming convention is quokka-plugin-purpose, where purpose is the one-two words description of what the module is adding to the quokka’s default workflow.

Some examples of the plugins that may be useful for everyone are environment setups for popular frameworks and libraries, such as Angular, React, Express, etc.

If you find yourself adding some code to run before every new Quokka file that you create, it’s probably a good candidate for a plugin as well.

If you would like to expose some API from your plugin, the recommended way to do it is via a namespace in the global object. While globals are not great in real apps, in a playground they allow users to experiment with less ceremony involve. So for example a simple benchmarking plugin named time may look like:

 module.exports = {
   
   before: config => {
     global.time = func => {
       console.time('Execution time');
       func();
       console.timeEnd('Execution time');
     };
     global.time.repeat = (times, func) => {
       ...
     };
   }; 
 };

so a user may write a Quokka file like:

time(() => {
  // code to measure the execution time for 
});

time.repeat(10, () => {
  // ...
});

If you wrote a Quokka plugin and would like to let others know about it, please feel free to share it in our repo.

Development hints