Skip to content

Commit

Permalink
ESLint Plugin: Image rules (#23402)
Browse files Browse the repository at this point in the history
Adds a new image rule to `eslint-plugin-next`:

```
Do not use `<img>`. Use Image from `next/image` instead
```
  • Loading branch information
housseindjirdeh authored May 17, 2021
1 parent d746db6 commit 7426ebc
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
32 changes: 32 additions & 0 deletions errors/no-img-element.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# No Img Element

### Why This Error Occurred

An HTML `<img>` element was used to display an image. For better performance and automatic image optimization, use Next.js' built-in image component instead.

### Possible Ways to Fix It

Import and use the `<Image />` component:

```jsx
import { Image } from 'next/image'

function Home() {
return (
<>
<Image
src="https://example.com/test"
alt="Landscape picture"
width={500}
height={500}
/>
</>
)
}

export default Home
```

### Useful Links

- [Image Component and Image Optimization](https://nextjs.org/docs/basic-features/image-optimization)
2 changes: 2 additions & 0 deletions packages/eslint-plugin-next/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
'no-css-tags': require('./rules/no-css-tags'),
'no-sync-scripts': require('./rules/no-sync-scripts'),
'no-html-link-for-pages': require('./rules/no-html-link-for-pages'),
'no-img-element': require('./rules/no-img-element'),
'no-unwanted-polyfillio': require('./rules/no-unwanted-polyfillio'),
'no-page-custom-font': require('./rules/no-page-custom-font'),
'no-title-in-document-head': require('./rules/no-title-in-document-head'),
Expand All @@ -19,6 +20,7 @@ module.exports = {
'@next/next/no-css-tags': 1,
'@next/next/no-sync-scripts': 1,
'@next/next/no-html-link-for-pages': 1,
'@next/next/no-img-element': 1,
'@next/next/no-unwanted-polyfillio': 1,
'@next/next/no-page-custom-font': 1,
'@next/next/no-title-in-document-head': 1,
Expand Down
29 changes: 29 additions & 0 deletions packages/eslint-plugin-next/lib/rules/no-img-element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module.exports = {
meta: {
docs: {
description: 'Prohibit usage of HTML <img> element',
category: 'HTML',
recommended: true,
},
fixable: 'code',
},

create: function (context) {
return {
JSXOpeningElement(node) {
if (node.name.name !== 'img') {
return
}

if (node.attributes.length === 0) {
return
}

context.report({
node,
message: `Do not use <img>. Use Image from 'next/image' instead. See https://nextjs.org/docs/messages/no-img-element.`,
})
},
}
},
}
62 changes: 62 additions & 0 deletions test/eslint-plugin-next/no-img-element.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-img-element')

const RuleTester = require('eslint').RuleTester

RuleTester.setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
modules: true,
jsx: true,
},
},
})

var ruleTester = new RuleTester()
ruleTester.run('no-img-element', rule, {
valid: [
`import { Image } from 'next/image';
export class MyComponent {
render() {
return (
<div>
<Image
src="/test.png"
alt="Test picture"
width={500}
height={500}
/>
</div>
);
}
}`,
],
invalid: [
{
code: `
export class MyComponent {
render() {
return (
<div>
<img
src="/test.png"
alt="Test picture"
width={500}
height={500}
/>
</div>
);
}
}`,
errors: [
{
message:
"Do not use <img>. Use Image from 'next/image' instead. See https://nextjs.org/docs/messages/no-img-element.",
type: 'JSXOpeningElement',
},
],
},
],
})

0 comments on commit 7426ebc

Please sign in to comment.