fix(eslint): next/script
beforeInteractive
gives warning on appDir (#51148)
## Issue The `context.getFilename()` gets the absolute path of the files, and the if statement to filter `/src` and `/app` was not working since #46609. ## Expected Do not show a lint warning if use `beforeInteractive` inside `appDir`. Fixes #46609 #50261
This commit is contained in:
parent
a794e1f32e
commit
022cb25640
2 changed files with 121 additions and 61 deletions
|
@ -4,10 +4,8 @@ import * as path from 'path'
|
|||
const url =
|
||||
'https://nextjs.org/docs/messages/no-before-interactive-script-outside-document'
|
||||
|
||||
const startsWithUsingCorrectSeparators = (str: string, start: string) =>
|
||||
[path.sep, path.posix.sep].some((sep) =>
|
||||
str.startsWith(start.replace(/\//g, sep))
|
||||
)
|
||||
const convertToCorrectSeparator = (str: string) =>
|
||||
str.replace(/[\\/]/g, path.sep)
|
||||
|
||||
export = defineRule({
|
||||
meta: {
|
||||
|
@ -25,24 +23,17 @@ export = defineRule({
|
|||
|
||||
return {
|
||||
'ImportDeclaration[source.value="next/script"] > ImportDefaultSpecifier'(
|
||||
node
|
||||
node: any
|
||||
) {
|
||||
scriptImportName = node.local.name
|
||||
},
|
||||
JSXOpeningElement(node) {
|
||||
let pathname = context.getFilename()
|
||||
const pathname = convertToCorrectSeparator(context.getFilename())
|
||||
|
||||
if (startsWithUsingCorrectSeparators(pathname, 'src/')) {
|
||||
pathname = pathname.slice(4)
|
||||
} else if (startsWithUsingCorrectSeparators(pathname, '/src/')) {
|
||||
pathname = pathname.slice(5)
|
||||
}
|
||||
const isInAppDir = pathname.includes(`${path.sep}app${path.sep}`)
|
||||
|
||||
// This rule shouldn't fire in `app/`
|
||||
if (
|
||||
startsWithUsingCorrectSeparators(pathname, 'app/') ||
|
||||
startsWithUsingCorrectSeparators(pathname, '/app/')
|
||||
) {
|
||||
if (isInAppDir) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -109,59 +109,33 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
|
||||
export default function Index() {
|
||||
return (
|
||||
<Script
|
||||
id="scriptBeforeInteractive"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy="beforeInteractive"
|
||||
></Script>
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: 'app/deep/root/layout.tsx',
|
||||
filename: '/Users/user_name/projects/project-name/app/layout.tsx',
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
export default function test() {
|
||||
return (
|
||||
<Script
|
||||
id="scriptBeforeInteractive"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy="beforeInteractive"
|
||||
></Script>
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: 'app/deep/page.tsx',
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<Script
|
||||
id="scriptBeforeInteractive"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy="beforeInteractive"
|
||||
></Script>
|
||||
);
|
||||
}`,
|
||||
filename: 'app/deep/randomFile.tsx',
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<Script
|
||||
id="scriptBeforeInteractive"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy="beforeInteractive"
|
||||
></Script>
|
||||
);
|
||||
}`,
|
||||
filename: 'src/app/deep/randomFile.tsx',
|
||||
filename: 'C:\\Users\\username\\projects\\project-name\\app\\layout.tsx',
|
||||
},
|
||||
{
|
||||
code: `
|
||||
|
@ -178,13 +152,13 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: '/src/app/layout.tsx',
|
||||
filename: '/Users/user_name/projects/project-name/src/app/layout.tsx',
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
export default function test() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
|
@ -195,7 +169,8 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: '/app/layout.tsx',
|
||||
filename:
|
||||
'C:\\Users\\username\\projects\\project-name\\src\\app\\layout.tsx',
|
||||
},
|
||||
].map((obj, idx) => ({
|
||||
...obj,
|
||||
|
@ -249,6 +224,100 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: '/Users/user_name/projects/project-name/pages/layout.tsx',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"`next/script`'s `beforeInteractive` strategy should not be used outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename:
|
||||
'C:\\Users\\username\\projects\\project-name\\pages\\layout.tsx',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"`next/script`'s `beforeInteractive` strategy should not be used outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename: '/Users/user_name/projects/project-name/src/pages/layout.tsx',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"`next/script`'s `beforeInteractive` strategy should not be used outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
import Script from "next/script";
|
||||
|
||||
export default function test() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<Script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive"
|
||||
strategy='beforeInteractive'
|
||||
/>
|
||||
</html>
|
||||
);
|
||||
}`,
|
||||
filename:
|
||||
'C:\\Users\\username\\projects\\project-name\\src\\pages\\layout.tsx',
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
"`next/script`'s `beforeInteractive` strategy should not be used outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document",
|
||||
},
|
||||
],
|
||||
},
|
||||
].map((obj, idx) => ({
|
||||
...obj,
|
||||
code: `// invalid-${idx}
|
||||
|
|
Loading…
Reference in a new issue