eslint rule for script strategy should work properly in app/
(#46609)
fixes https://github.com/vercel/next.js/issues/46549 The docs are wrong for now, this limitation is just in `pages/`, you can use it anywhere in `app/`. Since `app/` is still not stable we will emit that warning in all files outside of `app/`.
This commit is contained in:
parent
bfc3849b1f
commit
8b50b80cde
2 changed files with 110 additions and 2 deletions
|
@ -4,6 +4,11 @@ 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))
|
||||
)
|
||||
|
||||
export = defineRule({
|
||||
meta: {
|
||||
docs: {
|
||||
|
@ -25,6 +30,17 @@ export = defineRule({
|
|||
scriptImportName = node.local.name
|
||||
},
|
||||
JSXOpeningElement(node) {
|
||||
let pathname = context.getFilename()
|
||||
|
||||
if (startsWithUsingCorrectSeparators(pathname, 'src/')) {
|
||||
pathname = pathname.slice(4)
|
||||
}
|
||||
|
||||
// This rule shouldn't fire in `app/`
|
||||
if (startsWithUsingCorrectSeparators(pathname, 'app/')) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!scriptImportName) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -103,7 +103,72 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
`,
|
||||
filename: 'pages/_document.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/root/layout.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/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',
|
||||
},
|
||||
].map((obj, idx) => ({
|
||||
...obj,
|
||||
code: `// valid-${idx}
|
||||
${obj.code}
|
||||
`,
|
||||
})),
|
||||
|
||||
invalid: [
|
||||
{
|
||||
|
@ -128,5 +193,32 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
|
|||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
{
|
||||
code: `
|
||||
import Head from "next/head";
|
||||
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: 'components/outside-known-dirs.js',
|
||||
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}
|
||||
${obj.code}
|
||||
`,
|
||||
})),
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue