5.4 KiB
PostCSS Plugin Guidelines
PostCSS plugin is a function that receives and transforms a CSS AST from PostCSS parser. These rules are mandatory for all PostCSS plugins.
See also ClojureWerkz’s recommendations for open source projects.
1. API
1.1 Clear name with postcss- prefix
Plugin’s purpose should be clear just by its name.
If you wrote a polyfill for CSS 4 Custom Media, postcss-cuustom-media
is a good name. If you wrote a plugin to support mixin,
use postcss-mixins as name.
Prefix postcss- will show, that plugin is part of PostCSS ecosystem.
This rule is not mandatory for plugins promoted as separated tool, not like a part of PostCSS ecosystem. Like Autoprefixer or cssnext.
1.2. Do one thing, and do it well
Do not create multitool plugins. Few small one-purpose plugins with a plugins pack will be a better solution.
For example, cssnext contains many small plugins for each W3C specification. Or cssnano contains a plugin for each optimization.
1.3. Do not use mixins
Preprocessors libraries like Compass provide API by mixins.
PostCSS has a different way. Do not prodive mixins for postcss-mixins. Custom properties and at-rules are better way.
1.4. Create plugin by postcss.plugin
This method will create a wrap to provide common plugin API:
var plugin = postcss.plugin('plugin-name', function (opts) {
return function (css, result) {
// Plugin code
};
});
postcss([ plugin ]) // Bracket-less call
postcss([ plugin(opst) ]) // Brackets call to set options
2. Processing
2.1. Plugin must be tested
CI service like Travis is also recommended to test code on different environments (at least on node.js 0.12 and io.js).
2.2. Use asynchronous methods when it is possible
For example don’t use fs.writeFile instead of fs.writeFileSync:
postcss.plugin('plugin-sprite', function (opts) {
return function (css, result) {
return new Promise(function (resolve, reject) {
var sprite = makeSprite();
fs.writeFile(opts.file, function (err) {
if ( err ) return reject(err);
resolve();
})
});
};
});
2.3. Set node.source for new nodes
Every node must have relevant source to generate correct source map.
So if you add new declaration, because of different declaration, you should
clone it to save origin source.
if ( needPrefix(decl.prop) ) {
decl.cloneBefore({ prop: '-webkit-' + decl.prop });
}
If you will create different type of node, you can just set source
from source node:
if ( decl.prop === 'animation' ) {
var keyframe = createAnimationByName(decl.value);
keyframes.source = decl.source;
decl.root().append(keyframes);
}
2.4. Use only the public PostCSS API
PostCSS plugins must not rely on undocumented properties or methods, which may be subject to change in any minor release. The public API is described in API docs.
3. Errors
3.1. Use node.error on CSS relevant errors
If you have a error because of input CSS (like unknown name in mixin plugin)
you should use node.error to create a error with source position:
if ( typeof mixins[name] === 'undefined' ) {
throw decl.error('Unknown mixin ' + name, { plugin: 'postcss-mixins' });
}
You must set your plugin name in plugin options.
3.2. Use result.warn for warnings
Do not print warnings by console.warn, because some PostCSS runner may has
no console output.
if ( outdated(decl.prop) ) {
result.warn(decl.prop + ' is outdated', { node: decl });
}
If CSS input is a source of warning, plugin must set node option.
4. Documentation
4.1. Document your plugin in English
PostCSS plugins must have their README.md written in English. Do not be afraid
of your English skills, as the open source community will fix your errors.
Of course, you are welcome to write documentation in other languages;
just name them appropriately (e.g. README.ja.md).
4.2. Put input and output examples
README.md must contain input and output CSS. Example is a best way
to describe plugin work.
First section is a good place to put examples. See postcss-opacity for example.
4.3. Maintain a changelog
PostCSS plugins must describe changes of all releases in a separate file,
such as ChangeLog.md, History.md, or with GitHub Releases.
Visit Keep A Changelog for more information on how to write one of these.
4.4. postcssplugin keyword in package.json
PostCSS plugins written for npm must have the postcssplugin keyword
in their package.json. This special keyword will be useful for feedback about
the PostCSS ecosystem.
For packages not published to npm, this is not mandatory, but recommended if the package format is allowed to contain keywords.