-
Notifications
You must be signed in to change notification settings - Fork 3
Cookbook: Creating a Rupert Plugin
In Progress
Rupert Plugins allow third-party developers a convenient way to expose their library to Rupert. Rupert plugins usually perform by adding configuration information to Rupert, but can also reach in and modify behaviors of Rupert and Stassets in an aspect-oriented way (sometimes called "monkey patching").
Rupert finds plugins by looking for npm dependencies with rupert-plugin-
as a module name prefix, and also by looking at the plugins
key of the config
object. Rupert will require
the main file in the package, and expects a function returned. That function will get called with the config
object.
This pattern will cover most third party integrations. Add the local dependencies folder (node_modules) to the vendors prefix. Add each file as needed in the vendors arrays.
module.exports = function(config){
// Use `config.find` to set or update properties
// Use `config.prepend` and `config.append` to extend lookup arrays
// Add the local relative node_modules to [stassets.vendors.prefix](https://github.com/RupertJS/rupert/wiki/Cookbook:-Add-Vendor-Libraries)
config.append('stassets.vendors.prefix', [
Path.resolve(__dirname, '../node_modules')
]);
// Load jquery before other dependencies
config.prepend('stassets.vendors.js', [
'jquery/dist/jquery.js'
])
// Load bootstrap after dependencies
config.append('stassets.vendors.js', [
'bootstrap/dist/js/bootstrap.js'
])
// Load Bootstrap css after other vendors.
config.append('stassets.vendors.css', [
'bootstrap/dist/css/bootstrap.css',
'bootstrap/dist/css/bootstrap-theme.css'
]);
};
When additional configuration settings are needed for the Testing environment, a Rupert plugin can additionally export a Gruntfile
function. It will get passed the Grunt configuration (with grunt-recurse
available, so assign to grunt.Config), as well as the rupert-grunt configuration to override and augment any Rupert Grunt details.
module.exports.Gruntfile = function(grunt, config){
};
plugins.dependencies
If plugins
is unavailable in the server.json
configuration, package.json
will get loaded. Either way, the dependencies
hash will be consulted. The keys of the dependencies hash can either be rupert-grunt-
module names (which must be installed via npm) or file paths (which have at least one /
character). The module or file will be included, and executed as above.
Place [file-path]: true
in the plugin dependencies hash. true
is sufficient as a key.
Prefix with rupert-plugin-
, publish to NPM, and please be a good citizen :) If this is a one-off module you don't intend to maintain, please notify a RupertJS team member and add at least one as a collaborator on the project. Consider asking the RupertJS team to move the plugin into the Rupert organization. If you intend to continue to maintain the package, consider adding davidsoutherci
as an owner on the NPM registry, so that if you are unavailable to fix a critical issue the RupertJS CI server can push hotfixes when you're just getting on a plane for your honeymoon (this has actually happened).
Follow the steps here to include the custom plugin, making sure step #3 is satisfied. If the plugin is published, you can npm install --save rupert-plugin-custom-plugin
. If the plugin is not published but is an NPM module, you can npm install --save /path/to/rupert-plugin-custom-plugin
.
Rupert and Stassets can be extended by adding additional file types for js, css, and html transpilation. Stassets' constructor types for Script
, Template
, and Style
have static renderers
objects. Any key on the renderers
will be used as a file extension, and when files of that type update Stassets will pass the raw file content (in utf-8) and the relative file path to the renderer function. The return value of the function should resolve (either a promise that resolve, or be the value) of an object with properties content
, sourceMap
, and path
. content
should be the utf-8 transpiled JS, CSS, or HTML; sourceMap
should be a Javascript Source Map object (version 3), and path
should be the passed path
value as a nonce.
ScriptWatcher = require('rupert').Stassets.constructors.Script;
Script.renderers['es6'] = function(code, path){
// Do something to render `code` into `content`, while generating `sourceMap`.
return Q.when({content, sourceMap, path});
};