-
Notifications
You must be signed in to change notification settings - Fork 26.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add eslint rule to prevent importing next/server outside of _middlewa…
…re (#30973) * Add eslint rule to prevent importing next/server outside of _middleware * add error to manifest.json Co-authored-by: Javi Velasco <javier.velasco86@gmail.com>
- Loading branch information
1 parent
4a22059
commit d1adf1d
Showing
4 changed files
with
190 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,23 @@ | ||
# No Server Import In Page | ||
|
||
### Why This Error Occurred | ||
|
||
`next/server` was imported in a page outside of `pages/_middleware.js` (or `pages/_middleware.tsx` if you are using TypeScript) | ||
|
||
### Possible Ways to Fix It | ||
|
||
Only import and use `next/server` within `pages/_middleware.js` (or `pages/_middleware.tsx`) to add middlewares. | ||
|
||
```jsx | ||
// pages/_middleware.ts | ||
|
||
import type { NextFetchEvent, NextRequest } from 'next/server' | ||
|
||
export function middleware(req: NextRequest, ev: NextFetchEvent) { | ||
return new Response('Hello, world!') | ||
} | ||
``` | ||
|
||
### Useful Links | ||
|
||
- [Middleware](https://nextjs.org/docs/middleware) |
37 changes: 37 additions & 0 deletions
37
packages/eslint-plugin-next/lib/rules/no-server-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,37 @@ | ||
const path = require('path') | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: | ||
'Disallow importing next/server outside of pages/_middleware.js', | ||
recommended: true, | ||
url: 'https://nextjs.org/docs/messages/no-server-import-in-page', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
ImportDeclaration(node) { | ||
if (node.source.value !== 'next/server') { | ||
return | ||
} | ||
|
||
const paths = context.getFilename().split('pages') | ||
const page = paths[paths.length - 1] | ||
|
||
if ( | ||
!page || | ||
page.startsWith(`${path.sep}_middleware`) || | ||
page.startsWith(`${path.posix.sep}_middleware`) | ||
) { | ||
return | ||
} | ||
|
||
context.report({ | ||
node, | ||
message: `next/server should not be imported outside of pages/_middleware.js. See https://nextjs.org/docs/messages/no-server-import-in-page.`, | ||
}) | ||
}, | ||
} | ||
}, | ||
} |
126 changes: 126 additions & 0 deletions
126
test/unit/eslint-plugin-next/no-server-import-in-page.test.ts
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,126 @@ | ||
import { RuleTester } from 'eslint' | ||
import path from 'path' | ||
import rule from '@next/eslint-plugin-next/lib/rules/no-server-import-in-page' | ||
;(RuleTester as any).setDefaultConfig({ | ||
parserOptions: { | ||
ecmaVersion: 2018, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
modules: true, | ||
jsx: true, | ||
}, | ||
}, | ||
}) | ||
const ruleTester = new RuleTester() | ||
|
||
ruleTester.run('no-server-import-in-page', rule, { | ||
valid: [ | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: 'pages/_middleware.js', | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: `pages${path.sep}_middleware.js`, | ||
}, | ||
{ | ||
code: `import NextDocument from "next/document" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: `pages${path.posix.sep}_middleware.tsx`, | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: 'pages/_middleware.page.tsx', | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: 'pages/_middleware/index.js', | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: 'pages/_middleware/index.tsx', | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export function middleware(req, ev) { | ||
return new Response('Hello, world!') | ||
} | ||
`, | ||
filename: 'pagesapp/src/pages/_middleware.js', | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export const Test = () => <p>Test</p> | ||
`, | ||
filename: 'components/test.js', | ||
errors: [ | ||
{ | ||
message: | ||
'next/server should not be imported outside of pages/_middleware.js. See https://nextjs.org/docs/messages/no-server-import-in-page.', | ||
type: 'ImportDeclaration', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export const Test = () => <p>Test</p> | ||
`, | ||
filename: 'pages/test.js', | ||
errors: [ | ||
{ | ||
message: | ||
'next/server should not be imported outside of pages/_middleware.js. See https://nextjs.org/docs/messages/no-server-import-in-page.', | ||
type: 'ImportDeclaration', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { NextFetchEvent, NextRequest } from "next/server" | ||
export const Test = () => <p>Test</p> | ||
`, | ||
filename: `pages${path.sep}test.js`, | ||
errors: [ | ||
{ | ||
message: | ||
'next/server should not be imported outside of pages/_middleware.js. See https://nextjs.org/docs/messages/no-server-import-in-page.', | ||
type: 'ImportDeclaration', | ||
}, | ||
], | ||
}, | ||
], | ||
}) |