Skip to content

Commit

Permalink
Add support for async rules (stylelint#2351)
Browse files Browse the repository at this point in the history
* Add support for async rules

* Copy editing
  • Loading branch information
ramasilveyra authored and sergesemashko committed Mar 3, 2017
1 parent 01474a3 commit ded4db2
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
39 changes: 36 additions & 3 deletions docs/developer-guide/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,39 @@ In order for your plugin rule to work with the [standard configuration format](.

`ruleFunction` should return a function that is essentially a little [PostCSS plugin](https://github.com/postcss/postcss/blob/master/docs/writing-a-plugin.md): it takes 2 arguments: the PostCSS Root (the parsed AST), and the PostCSS LazyResult. You'll have to [learn about the PostCSS API](https://github.com/postcss/postcss/blob/master/docs/api.md).

### Asynchronous rules

Rules with asynchronous PostCSS plugins are also possible! All you need to do is return a Promise instance from your plugin function.

```js
// Abbreviated asynchronous example
var stylelint = require("stylelint")

var ruleName = "plugin/foo-bar-async"
var messages = stylelint.utils.ruleMessages(ruleName, {
expected: "Expected ...",
})

module.exports = stylelint.createPlugin(ruleName, function(primaryOption, secondaryOptionObject) {
return function(postcssRoot, postcssResult) {
var validOptions = stylelint.utils.validateOptions(postcssResult, ruleName, { .. })
if (!validOptions) { return }

return new Promise(function(resolve) {
// some async operation
setTimeout(function() {
// ... some logic ...
stylelint.utils.report({ .. })
resolve()
}, 1)
})
}
})

module.exports.ruleName = ruleName
module.exports.messages = messages
```

## `stylelint.utils`

stylelint exposes some utilities that are useful. *For details about the APIs of these functions, please look at comments in the source code and examples in the standard rules.*
Expand Down Expand Up @@ -82,9 +115,9 @@ function myPluginRule(primaryOption, secondaryOptions) {
root: root
}, (warning) => {
stylelint.utils.report({
message: myMessage,
ruleName: myRuleName,
result: result,
message: myMessage,
ruleName: myRuleName,
result: result,
node: warning.node,
line: warning.line,
column: warning.column,
Expand Down
30 changes: 30 additions & 0 deletions lib/__tests__/fixtures/plugin-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use strict"

const stylelint = require("../../")

const ruleName = "plugin/async"

const rule = enabled => (root, result) => {
const validOptions = stylelint.utils.validateOptions(result, ruleName, {
actual: enabled,
possible: [ true, false ],
})

if (!validOptions) {
return null
}

return new Promise((resolve) => {
setTimeout(() => {
stylelint.utils.report({
result,
ruleName,
message: "Async rule",
node: root,
})
resolve()
})
}, 1)
}

module.exports = stylelint.createPlugin(ruleName, rule)
12 changes: 12 additions & 0 deletions lib/__tests__/plugins.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ it("plugin with primary option array within options array", () => {
})
})

it("plugin with async rule", () => {
const config = {
plugins: [path.join(__dirname, "fixtures/plugin-async")],
rules: {
"plugin/async": true,
},
}
return postcss().use(stylelint(config)).process("a {}").then(result => {
expect(result.warnings().length).toBe(1)
})
})

describe("loading a plugin from process.cwd", () => {
let actualCwd
let result
Expand Down
2 changes: 1 addition & 1 deletion lib/lintSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function lintPostcssResult(
postcssResult.stylelint.customMessages[ruleName] = _.get(secondaryOptions, "message")

const performRule = Promise.resolve().then(() => {
ruleFunction(primaryOption, secondaryOptions)(postcssRoot, postcssResult)
return ruleFunction(primaryOption, secondaryOptions)(postcssRoot, postcssResult)
})
performRules.push(performRule)
})
Expand Down

0 comments on commit ded4db2

Please sign in to comment.