Experimental: New ESLint Plugin (#11986)

This commit is contained in:
Janicklas Ralph 2020-05-06 22:36:01 -07:00 committed by GitHub
parent a795e48be1
commit 5ad512b138
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 218 additions and 0 deletions

View file

@ -0,0 +1,14 @@
module.exports = {
rules: {
'no-css-tags': require('./rules/no-css-tags'),
'no-sync-scripts': require('./rules/no-sync-scripts'),
},
configs: {
recommended: {
rules: {
'@next/next/no-css-tags': 1,
'@next/next/no-sync-scripts': 1,
},
},
},
}

View file

@ -0,0 +1,29 @@
module.exports = function(context) {
return {
JSXOpeningElement(node) {
if (node.name.name !== 'link') {
return
}
if (node.attributes.length === 0) {
return
}
if (
node.attributes.find(
attr => attr.name.name === 'rel' && attr.value.value === 'stylesheet'
) &&
node.attributes.find(
attr => attr.name.name === 'href' && !/^https?/.test(attr.value.value)
)
) {
context.report({
node,
message:
'In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.',
})
}
},
}
}
module.exports.schema = []

View file

@ -0,0 +1,27 @@
module.exports = function(context) {
return {
JSXOpeningElement(node) {
if (node.name.name !== 'script') {
return
}
if (node.attributes.length === 0) {
return
}
if (
node.attributes.find(attr => attr.name.name === 'src') &&
!node.attributes.find(
attr => attr.name.name === 'async' || attr.name.name === 'defer'
)
) {
context.report({
node,
message:
"A synchronous script tag can impact your webpage's performance",
})
}
},
}
}
module.exports.schema = []

View file

@ -0,0 +1,11 @@
{
"name": "@next/eslint-plugin-next",
"version": "0.0.0",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
"repository": {
"url": "zeit/next.js",
"directory": "packages/eslint-plugin-next"
}
}

View file

@ -0,0 +1,80 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-css-tags')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
modules: true,
jsx: true,
},
},
})
var ruleTester = new RuleTester()
ruleTester.run('no-css-tags', rule, {
valid: [
`import {Head} from 'next/document';
export class Blah extends Head {
render() {
return (
<div>
<h1>Hello title</h1>
</div>
);
}
}`,
`import {Head} from 'next/document';
export class Blah extends Head {
render() {
return (
<div>
<h1>Hello title</h1>
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet" />
</div>
);
}
}`,
],
invalid: [
{
code: `
import {Head} from 'next/document';
export class Blah extends Head {
render() {
return (
<div>
<h1>Hello title</h1>
<link href="/_next/static/css/styles.css" rel="stylesheet" />
</div>
);
}
}`,
errors: [
{
message:
'In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.',
type: 'JSXOpeningElement',
},
],
},
{
code: `
<div>
<link href="/_next/static/css/styles.css" rel="stylesheet" />
</div>`,
errors: [
{
message:
'In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.',
type: 'JSXOpeningElement',
},
],
},
],
})

View file

@ -0,0 +1,57 @@
const rule = require('@next/eslint-plugin-next/lib/rules/no-sync-scripts')
const RuleTester = require('eslint').RuleTester
RuleTester.setDefaultConfig({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
modules: true,
jsx: true,
},
},
})
var ruleTester = new RuleTester()
ruleTester.run('sync-scripts', rule, {
valid: [
`import {Head} from 'next/document';
export class Blah extends Head {
render() {
return (
<div>
<h1>Hello title</h1>
<script src='https://blah.com' async></script>
</div>
);
}
}`,
],
invalid: [
{
code: `
import {Head} from 'next/document';
export class Blah extends Head {
render() {
return (
<div>
<h1>Hello title</h1>
<script src='https://blah.com'></script>
</div>
);
}
}`,
errors: [
{
message:
"A synchronous script tag can impact your webpage's performance",
type: 'JSXOpeningElement',
},
],
},
],
})