Skip to content

Commit

Permalink
fix(nextjs): remove temporary patch for next eslint rules (#20863)
Browse files Browse the repository at this point in the history
  • Loading branch information
meeroslav authored Dec 20, 2023
1 parent 9e25c91 commit 696d048
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 46 deletions.
16 changes: 10 additions & 6 deletions packages/eslint/src/generators/utils/eslint-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ function overrideNeedsCompat(
override: Linter.ConfigOverride<Linter.RulesRecord>
) {
return (
!override.env && !override.extends && !override.plugins && !override.parser
override.env || override.extends || override.plugins || override.parser
);
}

Expand All @@ -229,7 +229,12 @@ export function updateOverrideInLintConfig(
updateJson(tree, fileName, (json: Linter.Config) => {
const index = json.overrides.findIndex(lookup);
if (index !== -1) {
json.overrides[index] = update(json.overrides[index]);
const newOverride = update(json.overrides[index]);
if (newOverride) {
json.overrides[index] = newOverride;
} else {
json.overrides.splice(index, 1);
}
}
return json;
});
Expand Down Expand Up @@ -301,10 +306,9 @@ export function addExtendsToLintConfig(
if (useFlatConfig(tree)) {
const fileName = joinPathFragments(root, 'eslint.config.js');
const pluginExtends = generatePluginExtendsElement(plugins);
tree.write(
fileName,
addBlockToFlatConfigExport(tree.read(fileName, 'utf8'), pluginExtends)
);
let content = tree.read(fileName, 'utf8');
content = addCompatToFlatConfig(content);
tree.write(fileName, addBlockToFlatConfigExport(content, pluginExtends));
} else {
const fileName = joinPathFragments(root, '.eslintrc.json');
updateJson(tree, fileName, (json) => {
Expand Down
16 changes: 9 additions & 7 deletions packages/eslint/src/generators/utils/flat-config/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function replaceOverride(
content: string,
root: string,
lookup: (override: Linter.ConfigOverride<Linter.RulesRecord>) => boolean,
update: (
update?: (
override: Linter.ConfigOverride<Linter.RulesRecord>
) => Linter.ConfigOverride<Linter.RulesRecord>
): string {
Expand Down Expand Up @@ -167,12 +167,14 @@ export function replaceOverride(
length: end - start,
});
const updatedData = update(data);
mapFilePaths(updatedData);
changes.push({
type: ChangeType.Insert,
index: start,
text: JSON.stringify(updatedData, null, 2).slice(2, -2), // remove curly braces and start/end line breaks since we are injecting just properties
});
if (updatedData) {
mapFilePaths(updatedData);
changes.push({
type: ChangeType.Insert,
index: start,
text: JSON.stringify(updatedData, null, 2).slice(2, -2), // remove curly braces and start/end line breaks since we are injecting just properties
});
}
}
}
});
Expand Down
6 changes: 6 additions & 0 deletions packages/next/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"version": "16.4.0-beta.3",
"description": "Update package.json moving @nx/next from dependency to devDependency",
"implementation": "./src/migrations/update-16-4-0/update-nx-next-dependency"
},
"update-17-2-7": {
"cli": "nx",
"version": "17.2.7",
"description": "Remove patched eslint rule for @next/next/no-html-link-for-pages",
"implementation": "./src/migrations/update-17-2-7/remove-eslint-rules-patch"
}
},
"packageJsonUpdates": {
Expand Down
8 changes: 0 additions & 8 deletions packages/next/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,14 +626,6 @@ describe('app', () => {
".next/**/*",
],
"overrides": [
{
"files": [
"*.*",
],
"rules": {
"@next/next/no-html-link-for-pages": "off",
},
},
{
"files": [
"*.ts",
Expand Down
12 changes: 0 additions & 12 deletions packages/next/src/generators/application/lib/add-linting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ describe('updateEslint', () => {
".next/**/*",
],
"overrides": [
{
"files": [
"*.*",
],
"rules": {
"@next/next/no-html-link-for-pages": "off",
},
},
{
"files": [
"*.ts",
Expand Down Expand Up @@ -132,10 +124,6 @@ describe('updateEslint', () => {
module.exports = [
{
files: ["**/*.*"],
rules: { "@next/next/no-html-link-for-pages": "off" }
},
...baseConfig,
{
"files": [
Expand Down
13 changes: 0 additions & 13 deletions packages/next/src/generators/application/lib/add-linting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,6 @@ export async function addLinting(
'next/core-web-vitals',
]);

// Turn off @next/next/no-html-link-for-pages since there is an issue with nextjs throwing linting errors
// TODO(nicholas): remove after Vercel updates nextjs linter to only lint ["*.ts", "*.tsx", "*.js", "*.jsx"]
addOverrideToLintConfig(
host,
options.appProjectRoot,
{
files: ['*.*'],
rules: {
'@next/next/no-html-link-for-pages': 'off',
},
},
{ insertAtTheEnd: false }
);
updateOverrideInLintConfig(
host,
options.appProjectRoot,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { Tree, addProjectConfiguration, writeJson } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';

import update from './remove-eslint-rules-patch';
import { readJson } from '@nx/devkit';

describe('update-nx-next-dependency', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

it('should remove @next/next/no-html-link-for-pages in json configs', async () => {
tree.write('.eslintrc.json', '{}');

addProjectConfiguration(tree, 'my-pkg', {
root: 'packages/my-pkg',
});
writeJson(tree, `packages/my-pkg/.eslintrc.json`, {
root: true,
ignorePatterns: ['!**/*'],
plugins: ['@nx'],
overrides: [
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
rules: {
'@next/next/no-html-link-for-pages': ['error', 'apps/lint/pages'],
'no-console': 'error',
},
},
{
files: ['**/*.*'],
rules: { '@next/next/no-html-link-for-pages': 'off' },
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {},
},
{
files: ['**/*.js', '**/*.jsx'],
rules: {},
},
],
});

await update(tree);

expect(readJson(tree, `packages/my-pkg/.eslintrc.json`).overrides)
.toMatchInlineSnapshot(`
[
{
"files": [
"**/*.ts",
"**/*.tsx",
"**/*.js",
"**/*.jsx",
],
"rules": {
"@next/next/no-html-link-for-pages": [
"error",
"apps/lint/pages",
],
"no-console": "error",
},
},
{
"files": [
"**/*.ts",
"**/*.tsx",
],
"rules": {},
},
{
"files": [
"**/*.js",
"**/*.jsx",
],
"rules": {},
},
]
`);
});

it('should remove @next/next/no-html-link-for-pages in flat configs', async () => {
tree.write('eslint.config.js', 'module.exports = []');

addProjectConfiguration(tree, 'my-pkg', {
root: 'packages/my-pkg',
});
tree.write(
`packages/my-pkg/eslint.config.js`,
`const { FlatCompat } = require('@eslint/eslintrc');
const baseConfig = require('../../eslint.config.js');
const js = require('@eslint/js');
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
});
module.exports = [
...baseConfig,
...compat.extends(
'plugin:@nx/react-typescript',
'next',
'next/core-web-vitals'
),
{
files: ['**/*.*'],
rules: { '@next/next/no-html-link-for-pages': 'off' },
},
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
rules: {
'@next/next/no-html-link-for-pages': ['error', 'apps/lint/pages'],
'no-console': 'error',
},
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {},
},
{
files: ['**/*.js', '**/*.jsx'],
rules: {},
},
...compat.config({ env: { jest: true } }).map((config) => ({
...config,
files: ['**/*.spec.ts', '**/*.spec.tsx', '**/*.spec.js', '**/*.spec.jsx'],
})),
{ ignores: ['.next/**/*'] },
];`
);

await update(tree);

expect(
tree.read(`packages/my-pkg/eslint.config.js`, 'utf-8')
).not.toContain("'@next/next/no-html-link-for-pages': 'off'");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Tree, formatFiles, getProjects } from '@nx/devkit';
import { updateOverrideInLintConfig } from '@nx/eslint/src/generators/utils/eslint-file';

export default async function update(tree: Tree) {
const projects = getProjects(tree);
projects.forEach((project) => {
updateOverrideInLintConfig(
tree,
project.root,
(o) =>
o.rules?.['@next/next/no-html-link-for-pages'] &&
o.files?.includes('**/*.*'),
(o) => undefined
);
});

await formatFiles(tree);
}

0 comments on commit 696d048

Please sign in to comment.