refactor: remove sub-eslintrc, fix more lint errors (#7530)

This commit is contained in:
Joshua Chen 2022-05-30 14:49:51 +08:00 committed by GitHub
parent f443e992b9
commit 9023b7740c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 129 additions and 92 deletions

54
.eslintrc.js vendored
View file

@ -19,7 +19,8 @@ module.exports = {
},
parser: '@typescript-eslint/parser',
parserOptions: {
allowImportExportEverywhere: true,
// tsconfigRootDir: __dirname,
// project: ['./tsconfig.json', './website/tsconfig.json'],
},
globals: {
JSX: true,
@ -30,6 +31,8 @@ module.exports = {
'plugin:jest/recommended',
'airbnb',
'plugin:@typescript-eslint/recommended',
// 'plugin:@typescript-eslint/recommended-requiring-type-checking',
// 'plugin:@typescript-eslint/strict',
'plugin:regexp/recommended',
'prettier',
'plugin:@docusaurus/all',
@ -302,6 +305,9 @@ module.exports = {
'react/prop-types': OFF,
'react/require-default-props': [ERROR, {ignoreFunctionalComponents: true}],
'@typescript-eslint/consistent-type-definitions': OFF,
'@typescript-eslint/require-await': OFF,
'@typescript-eslint/ban-ts-comment': [
ERROR,
{'ts-expect-error': 'allow-with-description'},
@ -363,20 +369,39 @@ module.exports = {
overrides: [
{
files: [
'packages/docusaurus-*/src/theme/**/*.js',
'packages/docusaurus-*/src/theme/**/*.ts',
'packages/docusaurus-*/src/theme/**/*.tsx',
'packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}',
'packages/docusaurus/src/client/**/*.{js,ts,tsx}',
],
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
// Prevent importing lodash in client bundle for bundle size
'lodash',
'lodash.**',
'lodash/**',
// Prevent importing server code in client bundle
'**/../babel/**',
'**/../server/**',
'**/../commands/**',
'**/../webpack/**',
],
},
],
},
},
{
files: [
'packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}',
'packages/docusaurus/src/client/theme-fallback/**/*.{js,ts,tsx}',
],
rules: {
'import/no-named-export': ERROR,
},
},
{
files: [
'packages/create-docusaurus/templates/**/*.js',
'packages/create-docusaurus/templates/**/*.ts',
'packages/create-docusaurus/templates/**/*.tsx',
],
files: ['packages/create-docusaurus/templates/**/*.{js,ts,tsx}'],
rules: {
'header/header': OFF,
'global-require': OFF,
@ -391,14 +416,14 @@ module.exports = {
},
},
{
files: ['*.ts', '*.tsx'],
files: ['*.{ts,tsx}'],
rules: {
'no-undef': OFF,
'import/no-import-module-exports': OFF,
},
},
{
files: ['*.js', '*.mjs', '.cjs'],
files: ['*.{js,mjs,cjs}'],
rules: {
// Make JS code directly runnable in Node.
'@typescript-eslint/no-var-requires': OFF,
@ -419,8 +444,7 @@ module.exports = {
// Internal files where extraneous deps don't matter much at long as
// they run
files: [
'*.test.ts',
'*.test.tsx',
'*.test.{js,ts,tsx}',
'admin/**',
'jest/**',
'website/**',
@ -431,5 +455,9 @@ module.exports = {
'import/no-extraneous-dependencies': OFF,
},
},
{
files: ['packages/eslint-plugin/**/*.{js,ts}'],
extends: ['plugin:eslint-plugin/recommended'],
},
],
};

View file

@ -47,12 +47,12 @@ program
\`custom\`: enter your custom git clone command. We will prompt you for it.`,
)
.description('Initialize website.')
.action((siteName, template, rootDir, options) => {
.action((siteName, template, rootDir, options) =>
// See https://github.com/facebook/docusaurus/pull/6860
import('../lib/index.js').then(({default: init}) => {
init(path.resolve(rootDir ?? '.'), siteName, template, options);
});
});
import('../lib/index.js').then(({default: init}) =>
init(path.resolve(rootDir ?? '.'), siteName, template, options),
),
);
program.parse(process.argv);

View file

@ -128,11 +128,11 @@ function newLine(): void {
}
const logger = {
red: chalk.red,
yellow: chalk.yellow,
green: chalk.green,
bold: chalk.bold,
dim: chalk.dim,
red: (msg: string | number): string => chalk.red(msg),
yellow: (msg: string | number): string => chalk.yellow(msg),
green: (msg: string | number): string => chalk.green(msg),
bold: (msg: string | number): string => chalk.bold(msg),
dim: (msg: string | number): string => chalk.dim(msg),
path,
url,
name,

View file

@ -0,0 +1,9 @@
foo
`bar`
```js
baz
```
export const toc = 1;

View file

@ -1,5 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`toc remark plugin does not overwrite TOC var if no TOC 1`] = `
"foo
\`bar\`
\`\`\`js
baz
\`\`\`
export const toc = 1;
"
`;
exports[`toc remark plugin escapes inline code 1`] = `
"export const toc = [
{

View file

@ -30,6 +30,14 @@ describe('toc remark plugin', () => {
expect(result).toMatchSnapshot();
});
// A very implicit API: we allow users to hand-write the toc variable. It will
// get overwritten in most cases, but until we find a better way, better keep
// supporting this
it('does not overwrite TOC var if no TOC', async () => {
const result = await processFixture('no-heading-with-toc-export');
expect(result).toMatchSnapshot();
});
it('works on non text phrasing content', async () => {
const result = await processFixture('non-text-content');
expect(result).toMatchSnapshot();

View file

@ -89,8 +89,10 @@ export default function plugin(): Transformer {
const {children} = root as Parent<Literal>;
const targetIndex = getOrCreateExistingTargetIndex(children);
children[targetIndex]!.value = `export const ${name} = ${stringifyObject(
headings,
)};`;
if (headings.length) {
children[targetIndex]!.value = `export const ${name} = ${stringifyObject(
headings,
)};`;
}
};
}

View file

@ -8,7 +8,7 @@
import path from 'path';
import fs from 'fs-extra';
import logger from '@docusaurus/logger';
import {Globby} from '@docusaurus/utils';
import {Globby, DOCUSAURUS_VERSION} from '@docusaurus/utils';
import importFresh from 'import-fresh';
import Color from 'color';
@ -23,9 +23,6 @@ import type {
VersionTwoConfig,
} from './types';
const DOCUSAURUS_VERSION = (importFresh('../package.json') as {version: string})
.version;
async function walk(dir: string): Promise<string[]> {
const results: string[] = [];
const list = await fs.readdir(dir);
@ -82,7 +79,8 @@ export async function migrateDocusaurusProject(
shouldMigratePages: boolean = false,
): Promise<void> {
async function createMigrationContext(): Promise<MigrationContext> {
const v1Config = importFresh(`${siteDir}/siteConfig`) as VersionOneConfig;
const v1Config = (await import(`${siteDir}/siteConfig`))
.default as VersionOneConfig;
logger.info('Starting migration from v1 to v2...');
const deps = {
'@docusaurus/core': DOCUSAURUS_VERSION,
@ -444,9 +442,9 @@ async function migrateBlogFiles(context: MigrationContext) {
async function handleVersioning(context: MigrationContext) {
const {siteDir, newDir} = context;
if (await fs.pathExists(path.join(siteDir, 'versions.json'))) {
const loadedVersions: string[] = await fs.readJSON(
const loadedVersions = (await fs.readJSON(
path.join(siteDir, 'versions.json'),
);
)) as string[];
await fs.copyFile(
path.join(siteDir, 'versions.json'),
path.join(newDir, 'versions.json'),
@ -488,7 +486,11 @@ async function migrateVersionedDocs(
path.join(newDir, 'versioned_docs', `version-${version}`),
);
await fs.copy(
path.join(newDir, 'versioned_docs', `version-${versions[index - 1]}`),
path.join(
newDir,
'versioned_docs',
`version-${versions[index - 1]!}`,
),
path.join(newDir, 'versioned_docs', `version-${version}`),
);
await fs.copy(
@ -497,7 +499,11 @@ async function migrateVersionedDocs(
);
} catch {
await fs.copy(
path.join(newDir, 'versioned_docs', `version-${versions[index - 1]}`),
path.join(
newDir,
'versioned_docs',
`version-${versions[index - 1]!}`,
),
path.join(newDir, 'versioned_docs', `version-${version}`),
);
}
@ -543,7 +549,7 @@ async function migrateVersionedSidebar(
`version-${version}-sidebars.json`,
);
try {
sidebarEntries = await fs.readJSON(sidebarPath);
sidebarEntries = (await fs.readJSON(sidebarPath)) as SidebarEntries;
} catch {
sidebars.push({version, entries: sidebars[i - 1]!.entries});
return;

View file

@ -100,9 +100,9 @@ export default async function pluginContentDocs(
.command(command)
.arguments('<version>')
.description(commandDescription)
.action((version: unknown) => {
cliDocsVersionCommand(version, options, context);
});
.action((version: unknown) =>
cliDocsVersionCommand(version, options, context),
);
},
getTranslationFiles({content}) {

View file

@ -21,7 +21,7 @@ const createContainer = () => {
};
export default async function renderReloadPopup(props: Props): Promise<void> {
const container = getContainer() || createContainer();
const container = getContainer() ?? createContainer();
const ReloadPopup = (await import('@theme/PwaReloadPopup')).default;
ReactDOM.render(<ReloadPopup {...props} />, container);
}

View file

@ -23,6 +23,7 @@ describe('createSitemap', () => {
changefreq: EnumChangefreq.DAILY,
priority: 0.7,
ignorePatterns: [],
filename: 'sitemap.xml',
},
);
expect(sitemap).toContain(
@ -49,6 +50,7 @@ describe('createSitemap', () => {
changefreq: EnumChangefreq.DAILY,
priority: 0.7,
ignorePatterns: [],
filename: 'sitemap.xml',
},
);
expect(sitemap).not.toContain('404');
@ -70,6 +72,7 @@ describe('createSitemap', () => {
// Deep ignore
'/tags/**',
],
filename: 'sitemap.xml',
},
);
expect(sitemap).not.toContain('/search/</loc>');
@ -89,6 +92,7 @@ describe('createSitemap', () => {
changefreq: EnumChangefreq.DAILY,
priority: 0.7,
ignorePatterns: [],
filename: 'sitemap.xml',
},
);
@ -110,6 +114,7 @@ describe('createSitemap', () => {
changefreq: EnumChangefreq.DAILY,
priority: 0.7,
ignorePatterns: [],
filename: 'sitemap.xml',
},
);
@ -131,6 +136,7 @@ describe('createSitemap', () => {
changefreq: EnumChangefreq.DAILY,
priority: 0.7,
ignorePatterns: [],
filename: 'sitemap.xml',
},
);

View file

@ -11,7 +11,7 @@ import CodeBlock from '@theme/CodeBlock';
import type {Props} from '@theme/MDXComponents/Code';
export default function MDXCode(props: Props): JSX.Element {
const inlineElements = [
const inlineElements: (string | undefined)[] = [
'a',
'b',
'big',
@ -26,7 +26,10 @@ export default function MDXCode(props: Props): JSX.Element {
const shouldBeInline = React.Children.toArray(props.children).every(
(el) =>
(typeof el === 'string' && !el.includes('\n')) ||
(isValidElement(el) && inlineElements.includes(el.props.mdxType)),
(isValidElement(el) &&
inlineElements.includes(
(el.props as {mdxType: string} | null)?.mdxType,
)),
);
return shouldBeInline ? (

View file

@ -15,7 +15,8 @@ export default function MDXDetails(props: Props): JSX.Element {
// Details theme component
const summary = items.find(
(item): item is ReactElement<ComponentProps<'summary'>> =>
React.isValidElement(item) && item.props?.mdxType === 'summary',
React.isValidElement(item) &&
(item.props as {mdxType: string} | null)?.mdxType === 'summary',
);
const children = <>{items.filter((item) => item !== summary)}</>;

View file

@ -5,8 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {type ReactElement, type ComponentProps} from 'react';
import Head from '@docusaurus/Head';
import React, {type ReactElement} from 'react';
import Head, {type Props as HeadProps} from '@docusaurus/Head';
import type {Props} from '@theme/MDXComponents/Head';
// MDX elements are wrapped through the MDX pragma. In some cases (notably usage
@ -25,7 +25,5 @@ export default function MDXHead(props: Props): JSX.Element {
const unwrappedChildren = React.Children.map(props.children, (child) =>
React.isValidElement(child) ? unwrapMDXElement(child) : child,
);
return (
<Head {...(props as ComponentProps<typeof Head>)}>{unwrappedChildren}</Head>
);
return <Head {...(props as HeadProps)}>{unwrappedChildren}</Head>;
}

View file

@ -14,7 +14,8 @@ export default function MDXPre(props: Props): JSX.Element {
<CodeBlock
// If this pre is created by a ``` fenced codeblock, unwrap the children
{...(isValidElement(props.children) &&
props.children.props?.originalType === 'code'
(props.children.props as {originalType: string} | null)?.originalType ===
'code'
? props.children.props
: {...props})}
/>

View file

@ -18,12 +18,12 @@ type HistoryBlockHandler = (location: Location, action: Action) => void | false;
* will be blocked/cancelled.
*/
function useHistoryActionHandler(handler: HistoryBlockHandler): void {
const {block} = useHistory();
const history = useHistory();
const stableHandler = useDynamicCallback(handler);
useEffect(
// See https://github.com/remix-run/history/blob/main/docs/blocking-transitions.md
() => block((location, action) => stableHandler(location, action)),
[block, stableHandler],
() => history.block((location, action) => stableHandler(location, action)),
[history, stableHandler],
);
}

View file

@ -1,27 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = {
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
// Prevent importing lodash in client bundle for bundle size
'lodash',
'lodash.**',
'lodash/**',
// Prevent importing server code in client bundle
'**/../babel/**',
'**/../server/**',
'**/../commands/**',
'**/../webpack/**',
],
},
],
},
};

View file

@ -18,6 +18,7 @@ type State = {
error: Error | null;
};
// eslint-disable-next-line react/function-component-definition
const DefaultFallback: FallbackFunction = (params) => (
<ThemeError {...params} />
);

View file

@ -45,9 +45,7 @@ async function createTmpTranslationFile(
return {
siteDir,
readFile() {
return fs.readJSON(filePath);
},
readFile: () => fs.readJSON(filePath),
};
}

View file

@ -1,10 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = {
extends: ['../../.eslintrc.js', 'plugin:eslint-plugin/recommended'],
};