From 9023b7740c820b2d61d2870d61182e8432f9ae10 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Mon, 30 May 2022 14:49:51 +0800 Subject: [PATCH] refactor: remove sub-eslintrc, fix more lint errors (#7530) --- .eslintrc.js | 54 ++++++++++++++----- packages/create-docusaurus/bin/index.js | 10 ++-- packages/docusaurus-logger/src/index.ts | 10 ++-- .../no-heading-with-toc-export.md | 9 ++++ .../__snapshots__/index.test.ts.snap | 13 +++++ .../src/remark/toc/__tests__/index.test.ts | 8 +++ .../src/remark/toc/index.ts | 8 +-- packages/docusaurus-migrate/src/index.ts | 26 +++++---- .../src/index.ts | 6 +-- .../src/renderReloadPopup.tsx | 2 +- .../src/__tests__/createSitemap.test.ts | 6 +++ .../src/theme/MDXComponents/Code.tsx | 7 ++- .../src/theme/MDXComponents/Details.tsx | 3 +- .../src/theme/MDXComponents/Head.tsx | 8 ++- .../src/theme/MDXComponents/Pre.tsx | 3 +- .../src/utils/historyUtils.ts | 6 +-- packages/docusaurus/src/client/.eslintrc.js | 27 ---------- .../src/client/exports/ErrorBoundary.tsx | 1 + .../__tests__/translations.test.ts | 4 +- packages/eslint-plugin/.eslintrc.js | 10 ---- 20 files changed, 129 insertions(+), 92 deletions(-) create mode 100644 packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/no-heading-with-toc-export.md delete mode 100644 packages/docusaurus/src/client/.eslintrc.js delete mode 100644 packages/eslint-plugin/.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index 0513662017..c24b8215bd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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'], + }, ], }; diff --git a/packages/create-docusaurus/bin/index.js b/packages/create-docusaurus/bin/index.js index 35e135ebc6..be5e14f689 100755 --- a/packages/create-docusaurus/bin/index.js +++ b/packages/create-docusaurus/bin/index.js @@ -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); diff --git a/packages/docusaurus-logger/src/index.ts b/packages/docusaurus-logger/src/index.ts index 768cb8f9a0..f430555b0e 100644 --- a/packages/docusaurus-logger/src/index.ts +++ b/packages/docusaurus-logger/src/index.ts @@ -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, diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/no-heading-with-toc-export.md b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/no-heading-with-toc-export.md new file mode 100644 index 0000000000..900b8900c1 --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/no-heading-with-toc-export.md @@ -0,0 +1,9 @@ +foo + +`bar` + +```js +baz +``` + +export const toc = 1; diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap index e7811b9e9f..ba71805a2a 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap @@ -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 = [ { diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts index acd2a37615..6df3e94e67 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts @@ -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(); diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/index.ts b/packages/docusaurus-mdx-loader/src/remark/toc/index.ts index 9fe619e325..5e6c694dc3 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/toc/index.ts @@ -89,8 +89,10 @@ export default function plugin(): Transformer { const {children} = root as Parent; const targetIndex = getOrCreateExistingTargetIndex(children); - children[targetIndex]!.value = `export const ${name} = ${stringifyObject( - headings, - )};`; + if (headings.length) { + children[targetIndex]!.value = `export const ${name} = ${stringifyObject( + headings, + )};`; + } }; } diff --git a/packages/docusaurus-migrate/src/index.ts b/packages/docusaurus-migrate/src/index.ts index f5bf38134b..bab7fd6882 100644 --- a/packages/docusaurus-migrate/src/index.ts +++ b/packages/docusaurus-migrate/src/index.ts @@ -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 { const results: string[] = []; const list = await fs.readdir(dir); @@ -82,7 +79,8 @@ export async function migrateDocusaurusProject( shouldMigratePages: boolean = false, ): Promise { async function createMigrationContext(): Promise { - 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; diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index afbb809fb7..a855754243 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -100,9 +100,9 @@ export default async function pluginContentDocs( .command(command) .arguments('') .description(commandDescription) - .action((version: unknown) => { - cliDocsVersionCommand(version, options, context); - }); + .action((version: unknown) => + cliDocsVersionCommand(version, options, context), + ); }, getTranslationFiles({content}) { diff --git a/packages/docusaurus-plugin-pwa/src/renderReloadPopup.tsx b/packages/docusaurus-plugin-pwa/src/renderReloadPopup.tsx index fe8e9eb2b0..2958a7dee8 100644 --- a/packages/docusaurus-plugin-pwa/src/renderReloadPopup.tsx +++ b/packages/docusaurus-plugin-pwa/src/renderReloadPopup.tsx @@ -21,7 +21,7 @@ const createContainer = () => { }; export default async function renderReloadPopup(props: Props): Promise { - const container = getContainer() || createContainer(); + const container = getContainer() ?? createContainer(); const ReloadPopup = (await import('@theme/PwaReloadPopup')).default; ReactDOM.render(, container); } diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts index bc34ee51d8..b033a0cc72 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts @@ -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/'); @@ -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', }, ); diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx index 4d5680ed0a..c1977000be 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx @@ -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 ? ( diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx index c99fdc2a6a..08ddaf1a1f 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx @@ -15,7 +15,8 @@ export default function MDXDetails(props: Props): JSX.Element { // Details theme component const summary = items.find( (item): item is ReactElement> => - 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)}; diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx index bf8867f409..3b8924c0ed 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx @@ -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 ( - )}>{unwrappedChildren} - ); + return {unwrappedChildren}; } diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx index 75e64c9971..cde1899da8 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx @@ -14,7 +14,8 @@ export default function MDXPre(props: Props): JSX.Element { diff --git a/packages/docusaurus-theme-common/src/utils/historyUtils.ts b/packages/docusaurus-theme-common/src/utils/historyUtils.ts index 129396b44e..921f945886 100644 --- a/packages/docusaurus-theme-common/src/utils/historyUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/historyUtils.ts @@ -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], ); } diff --git a/packages/docusaurus/src/client/.eslintrc.js b/packages/docusaurus/src/client/.eslintrc.js deleted file mode 100644 index cbef5af736..0000000000 --- a/packages/docusaurus/src/client/.eslintrc.js +++ /dev/null @@ -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/**', - ], - }, - ], - }, -}; diff --git a/packages/docusaurus/src/client/exports/ErrorBoundary.tsx b/packages/docusaurus/src/client/exports/ErrorBoundary.tsx index 0d188d4da4..c29a33a9ca 100644 --- a/packages/docusaurus/src/client/exports/ErrorBoundary.tsx +++ b/packages/docusaurus/src/client/exports/ErrorBoundary.tsx @@ -18,6 +18,7 @@ type State = { error: Error | null; }; +// eslint-disable-next-line react/function-component-definition const DefaultFallback: FallbackFunction = (params) => ( ); diff --git a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts index 70da33ffd3..1e1b59aad8 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts @@ -45,9 +45,7 @@ async function createTmpTranslationFile( return { siteDir, - readFile() { - return fs.readJSON(filePath); - }, + readFile: () => fs.readJSON(filePath), }; } diff --git a/packages/eslint-plugin/.eslintrc.js b/packages/eslint-plugin/.eslintrc.js deleted file mode 100644 index 81bfbca201..0000000000 --- a/packages/eslint-plugin/.eslintrc.js +++ /dev/null @@ -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'], -};