Skip to content

Commit

Permalink
feat: add new prefer-nothing rule (#140)
Browse files Browse the repository at this point in the history
add new prefer-nothing rule
  • Loading branch information
43081j authored Nov 27, 2022
1 parent d591052 commit d8c7d27
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ If you want more fine-grained configuration, you can instead add a snippet like
- [lit/no-template-map](docs/rules/no-template-map.md)
- [lit/no-useless-template-literals](docs/rules/no-useless-template-literals.md)
- [lit/no-value-attribute](docs/rules/no-value-attribute.md)
- [lit/prefer-nothing](docs/rules/prefer-nothing.md)
- [lit/quoted-expressions](docs/rules/quoted-expressions.md)


Expand Down
43 changes: 43 additions & 0 deletions docs/rules/prefer-nothing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Enforces use of `nothing` constant over empty templates (prefer-nothing)

`nothing` is a constant provided by lit which may be used to render
nothing. This is far more efficient than creating an empty template.

This means you can do something like:

```ts
_render() {
if (!condition) {
return nothing;
}

return html`Hello there`;
}
```

## Rule Details

This rule enforces the use of `nothing` rather than empty templates.

The following patterns are considered warnings:

```ts
html``;
const tpl = html``;

function render() {
return html``;
}
```

The following patterns are not warnings:

```ts
html`foo`;
html` `; // whitespace
```

## When Not To Use It

If you prefer using empty templates or don't yet have lit 2.x (which provides
the `nothing` constant), you should not use this rule.
52 changes: 52 additions & 0 deletions src/rules/prefer-nothing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @fileoverview Enforces use of `nothing` constant over empty templates
* @author James Garbutt <https://github.com/43081j>
*/

import {Rule} from 'eslint';
import * as ESTree from 'estree';

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

const rule: Rule.RuleModule = {
meta: {
docs: {
description: 'Enforces use of `nothing` constant over empty templates',
category: 'Best Practices',
url: 'https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/prefer-nothing.md'
},
schema: [],
messages: {
preferNothing:
'`nothing` is preferred over empty templates when you want to render' +
' nothing'
}
},

create(context): Rule.RuleListener {
return {
TaggedTemplateExpression: (node: ESTree.Node): void => {
if (
node.type === 'TaggedTemplateExpression' &&
node.tag.type === 'Identifier' &&
node.tag.name === 'html'
) {
if (
node.quasi.expressions.length === 0 &&
node.quasi.quasis.length === 1 &&
node.quasi.quasis[0].value.raw === ''
) {
context.report({
node,
messageId: 'preferNothing'
});
}
}
}
};
}
};

export = rule;
59 changes: 59 additions & 0 deletions src/test/rules/prefer-nothing_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @fileoverview Enforces use of `nothing` constant over empty templates
* @author James Garbutt <https://github.com/43081j>
*/

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

import rule = require('../../rules/prefer-nothing');
import {RuleTester} from 'eslint';

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
parserOptions: {
sourceType: 'module',
ecmaVersion: 2015
}
});

ruleTester.run('prefer-nothing', rule, {
valid: ['html`foo`', 'css``', 'nonsense``', 'html`${x}`', 'html` `'],

invalid: [
{
code: 'html``',
errors: [
{
messageId: 'preferNothing',
line: 1,
column: 1
}
]
},
{
code: 'const x = html``;',
errors: [
{
messageId: 'preferNothing',
line: 1,
column: 11
}
]
},
{
code: 'function render() { return html``; }',
errors: [
{
messageId: 'preferNothing',
line: 1,
column: 28
}
]
}
]
});

0 comments on commit d8c7d27

Please sign in to comment.