This repository has been archived by the owner on Jun 21, 2023. It is now read-only.
forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ESLint Plugin: Prevent bad imports of next/document and next/head (ve…
…rcel#24832) Adds lint rules to the Next.js ESLint plugin to: - Disallow importing `next/head` inside `pages/_document.js` - Disallow importing `next/document` outside of `pages/_document.js` Both rules will be surfaced as **errors** within the recommended config of the plugin. Fixes vercel#13712 vercel#13958
- Loading branch information
1 parent
8571510
commit c252fbc
Showing
8 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# No Document Import in Page | ||
|
||
### Why This Error Occurred | ||
|
||
`next/document` was imported in a page outside of `pages/_document.js`. This can cause unexpected issues in your application. | ||
|
||
### Possible Ways to Fix It | ||
|
||
Only import and use `next/document` within `pages/_document.js` to override the default `Document` component: | ||
|
||
```jsx | ||
// pages/_document.js | ||
import Document, { Html, Head, Main, NextScript } from 'next/document' | ||
|
||
class MyDocument extends Document { | ||
//... | ||
} | ||
|
||
export default MyDocument | ||
``` | ||
|
||
### Useful Links | ||
|
||
- [Custom Document](https://nextjs.org/docs/advanced-features/custom-document) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# No Head Import in Document | ||
|
||
### Why This Error Occurred | ||
|
||
`next/head` was imported in `pages/_document.js`. This can cause unexpected issues in your application. | ||
|
||
### Possible Ways to Fix It | ||
|
||
Only import and use `next/document` within `pages/_document.js` to override the default `Document` component. If you are importing `next/head` to use the `Head` component, import it from `next/document` instead in order to modify `<head>` code across all pages: | ||
|
||
```jsx | ||
// pages/_document.js | ||
import Document, { Html, Head, Main, NextScript } from 'next/document' | ||
|
||
class MyDocument extends Document { | ||
static async getInitialProps(ctx) { | ||
//... | ||
} | ||
|
||
render() { | ||
return ( | ||
<Html> | ||
<Head></Head> | ||
</Html> | ||
) | ||
} | ||
} | ||
|
||
export default MyDocument | ||
``` | ||
|
||
### Useful Links | ||
|
||
- [Custom Document](https://nextjs.org/docs/advanced-features/custom-document) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
packages/eslint-plugin-next/lib/rules/no-document-import-in-page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const path = require('path') | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: | ||
'Disallow importing next/document outside of pages/document.js', | ||
recommended: true, | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
ImportDeclaration(node) { | ||
if (node.source.value !== 'next/document') { | ||
return | ||
} | ||
|
||
const page = context.getFilename().split('pages')[1] | ||
if (!page || path.parse(page).name === '_document') { | ||
return | ||
} | ||
|
||
context.report({ | ||
node, | ||
message: `next/document should not be imported outside of pages/_document.js. See https://nextjs.org/docs/messages/no-document-import-in-page.`, | ||
}) | ||
}, | ||
} | ||
}, | ||
} |
29 changes: 29 additions & 0 deletions
29
packages/eslint-plugin-next/lib/rules/no-head-import-in-document.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const path = require('path') | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Disallow importing next/head in pages/document.js', | ||
recommended: true, | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
ImportDeclaration(node) { | ||
if (node.source.value !== 'next/head') { | ||
return | ||
} | ||
|
||
const document = context.getFilename().split('pages')[1] | ||
if (!document || path.parse(document).name !== '_document') { | ||
return | ||
} | ||
|
||
context.report({ | ||
node, | ||
message: `next/head should not be imported in pages${document}. Import Head from next/document instead. See https://nextjs.org/docs/messages/no-head-import-in-document.`, | ||
}) | ||
}, | ||
} | ||
}, | ||
} |
66 changes: 66 additions & 0 deletions
66
test/eslint-plugin-next/no-document-import-in-page.unit.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
const rule = require('@next/eslint-plugin-next/lib/rules/no-document-import-in-page') | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
|
||
RuleTester.setDefaultConfig({ | ||
parserOptions: { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
modules: true, | ||
jsx: true, | ||
}, | ||
}, | ||
}) | ||
|
||
var ruleTester = new RuleTester() | ||
ruleTester.run('no-document-import-in-page', rule, { | ||
valid: [ | ||
{ | ||
code: `import Document from "next/document" | ||
export default class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
</Html> | ||
); | ||
} | ||
} | ||
`, | ||
filename: 'pages/_document.js', | ||
}, | ||
{ | ||
code: `import Document from "next/document" | ||
export default class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
</Html> | ||
); | ||
} | ||
} | ||
`, | ||
filename: 'pages/_document.tsx', | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: `import Document from "next/document" | ||
export const Test = () => ( | ||
<p>Test</p> | ||
) | ||
`, | ||
filename: 'pages/test.js', | ||
errors: [ | ||
{ | ||
message: | ||
'next/document should not be imported outside of pages/_document.js. See https://nextjs.org/docs/messages/no-document-import-in-page.', | ||
type: 'ImportDeclaration', | ||
}, | ||
], | ||
}, | ||
], | ||
}) |
88 changes: 88 additions & 0 deletions
88
test/eslint-plugin-next/no-head-import-in-document.unit.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
const rule = require('@next/eslint-plugin-next/lib/rules/no-head-import-in-document') | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
|
||
RuleTester.setDefaultConfig({ | ||
parserOptions: { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
modules: true, | ||
jsx: true, | ||
}, | ||
}, | ||
}) | ||
|
||
var ruleTester = new RuleTester() | ||
ruleTester.run('no-head-import-in-document', rule, { | ||
valid: [ | ||
{ | ||
code: `import Document, { Html, Head, Main, NextScript } from 'next/document' | ||
class MyDocument extends Document { | ||
static async getInitialProps(ctx) { | ||
//... | ||
} | ||
render() { | ||
return ( | ||
<Html> | ||
<Head> | ||
</Head> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
`, | ||
filename: 'pages/_document.tsx', | ||
}, | ||
{ | ||
code: `import Head from "next/head"; | ||
export default function IndexPage() { | ||
return ( | ||
<Head> | ||
<title>My page title</title> | ||
<meta name="viewport" content="initial-scale=1.0, width=device-width" /> | ||
</Head> | ||
); | ||
} | ||
`, | ||
filename: 'pages/index.tsx', | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
import Document, { Html, Main, NextScript } from 'next/document' | ||
import Head from 'next/head' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<Head /> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
`, | ||
filename: 'pages/_document.js', | ||
errors: [ | ||
{ | ||
message: | ||
'next/head should not be imported in pages/_document.js. Import Head from next/document instead. See https://nextjs.org/docs/messages/no-head-import-in-document.', | ||
type: 'ImportDeclaration', | ||
}, | ||
], | ||
}, | ||
], | ||
}) |