From 7a6607cfa1f9229a14cd5460623d387b4fc94271 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 28 Oct 2021 12:48:58 +0800 Subject: [PATCH] refactor: remove a few Lodash usages & ESLint enforcement (#5807) * refactor: remove some lodash usage Signed-off-by: Josh-Cena * Enforce ESLint Signed-off-by: Josh-Cena * More forbids * Fixup * Fix * Fix website --- .eslintrc.js | 27 ++++++++++++++++++- .../src/collectRedirects.ts | 6 ++--- .../src/extensionRedirects.ts | 5 ++-- .../src/blogUtils.ts | 8 +++--- .../src/index.ts | 9 +++---- .../src/index.ts | 6 ++--- .../src/index.ts | 7 ++--- .../src/translations.ts | 16 +++++------ packages/docusaurus/src/server/brokenLinks.ts | 7 +++-- .../translations/translationsExtractor.ts | 11 +++----- packages/docusaurus/src/server/utils.ts | 6 ++--- website/tsconfig.json | 1 + 12 files changed, 60 insertions(+), 49 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 66d72dd28313..d3c900637a9e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -129,11 +129,36 @@ module.exports = { 'no-redeclare': OFF, '@typescript-eslint/no-redeclare': ERROR, '@typescript-eslint/no-empty-interface': [ - 'error', + ERROR, { allowSingleExtends: true, }, ], + 'no-restricted-imports': [ + ERROR, + { + paths: [ + { + name: 'lodash', + importNames: [ + // 'compact', // TODO: TS doesn't make Boolean a narrowing function yet, so filter(Boolean) is problematic type-wise + 'filter', + 'flatten', + 'flatMap', + 'map', + 'reduce', + 'take', + 'takeRight', + 'head', + 'tail', + 'initial', + 'last', + ], + message: 'These APIs have their ES counterparts.', + }, + ], + }, + ], }, overrides: [ { diff --git a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts index ab78bff3109a..55415dfa44a0 100644 --- a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts +++ b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {flatten, uniqBy, difference, groupBy} from 'lodash'; +import {uniqBy, difference, groupBy} from 'lodash'; import { PluginContext, RedirectMetadata, @@ -165,7 +165,7 @@ function createRedirectsOptionRedirects( })); } - return flatten(redirectsOption.map(optionToRedirects)); + return redirectsOption.flatMap(optionToRedirects); } // Create redirects from the "createRedirects" fn provided by the user @@ -189,5 +189,5 @@ function createCreateRedirectsOptionRedirects( }); } - return flatten(paths.map(createPathRedirects)); + return paths.flatMap(createPathRedirects); } diff --git a/packages/docusaurus-plugin-client-redirects/src/extensionRedirects.ts b/packages/docusaurus-plugin-client-redirects/src/extensionRedirects.ts index 3f18f848abc5..89ce0450543f 100644 --- a/packages/docusaurus-plugin-client-redirects/src/extensionRedirects.ts +++ b/packages/docusaurus-plugin-client-redirects/src/extensionRedirects.ts @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import {flatten} from 'lodash'; import { addTrailingSlash, removeSuffix, @@ -62,7 +61,7 @@ export function createToExtensionsRedirects( return []; }; - return flatten(paths.map(createPathRedirects)); + return paths.flatMap(createPathRedirects); } // Create new /path.html/index.html that redirects to existing an /path @@ -99,5 +98,5 @@ export function createFromExtensionsRedirects( })); }; - return flatten(paths.map(createPathRedirects)); + return paths.flatMap(createPathRedirects); } diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index e50e4cadfcce..39c98ecea3cb 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -9,7 +9,7 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import path from 'path'; import readingTime from 'reading-time'; -import {compact, keyBy, mapValues} from 'lodash'; +import {keyBy, mapValues} from 'lodash'; import { PluginOptions, BlogPost, @@ -267,7 +267,7 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); - const blogPosts: BlogPost[] = compact( + const blogPosts = ( await Promise.all( blogSourceFiles.map(async (blogSourceFile: string) => { try { @@ -287,8 +287,8 @@ export async function generateBlogPosts( throw e; } }), - ), - ); + ) + ).filter(Boolean) as BlogPost[]; blogPosts.sort( (a, b) => b.metadata.date.getTime() - a.metadata.date.getTime(), diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index b7f2cf7ebd68..463e35022fd6 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -22,7 +22,6 @@ import { DEFAULT_PLUGIN_ID, } from '@docusaurus/core/lib/constants'; import {translateContent, getTranslationFiles} from './translations'; -import {flatten, take} from 'lodash'; import { PluginOptions, @@ -98,10 +97,8 @@ export default function pluginContentBlog( getPathsToWatch() { const {include, authorsMapPath} = options; - const contentMarkdownGlobs = flatten( - getContentPathList(contentPaths).map((contentPath) => { - return include.map((pattern) => `${contentPath}/${pattern}`); - }), + const contentMarkdownGlobs = getContentPathList(contentPaths).flatMap( + (contentPath) => include.map((pattern) => `${contentPath}/${pattern}`), ); // TODO: we should read this path in plugin! but plugins do not support async init for now :'( @@ -244,7 +241,7 @@ export default function pluginContentBlog( const sidebarBlogPosts = options.blogSidebarCount === 'ALL' ? blogPosts - : take(blogPosts, options.blogSidebarCount); + : blogPosts.slice(0, options.blogSidebarCount); const archiveUrl = normalizeUrl([ baseUrl, diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 4c2f5220466e..74970360ecad 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -42,7 +42,7 @@ import { import {RuleSetRule} from 'webpack'; import {cliDocsVersionCommand} from './cli'; import {VERSIONS_JSON_FILE} from './constants'; -import {keyBy, compact, mapValues} from 'lodash'; +import {keyBy, mapValues} from 'lodash'; import {toGlobalDataVersion} from './globalData'; import {toTagDocListProp, toVersionMetadataProp} from './props'; import { @@ -388,7 +388,7 @@ export default function pluginContentDocs( include: contentDirs // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970 .map(addTrailingPathSeparator), - use: compact([ + use: [ getJSLoader({isServer}), { loader: require.resolve('@docusaurus/mdx-loader'), @@ -414,7 +414,7 @@ export default function pluginContentDocs( loader: path.resolve(__dirname, './markdown/index.js'), options: docsMarkdownOptions, }, - ]), + ].filter(Boolean), }; } diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 82c95d08f76b..c26208d1c140 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -40,7 +40,6 @@ import { Metadata, PagesContentPaths, } from './types'; -import {flatten} from 'lodash'; export function getContentPathList(contentPaths: PagesContentPaths): string[] { return [contentPaths.contentPathLocalized, contentPaths.contentPath]; @@ -86,10 +85,8 @@ export default function pluginContentPages( getPathsToWatch() { const {include = []} = options; - return flatten( - getContentPathList(contentPaths).map((contentPath) => { - return include.map((pattern) => `${contentPath}/${pattern}`); - }), + return getContentPathList(contentPaths).flatMap((contentPath) => + include.map((pattern) => `${contentPath}/${pattern}`), ); }, diff --git a/packages/docusaurus-theme-classic/src/translations.ts b/packages/docusaurus-theme-classic/src/translations.ts index 191c3a429774..2b7a3ab6ab82 100644 --- a/packages/docusaurus-theme-classic/src/translations.ts +++ b/packages/docusaurus-theme-classic/src/translations.ts @@ -13,18 +13,16 @@ import { Footer, } from '@docusaurus/theme-common'; -import {keyBy, chain, flatten} from 'lodash'; +import {keyBy, chain} from 'lodash'; import {mergeTranslations} from '@docusaurus/utils'; function getNavbarTranslationFile(navbar: Navbar): TranslationFileContent { // TODO handle properly all the navbar item types here! function flattenNavbarItems(items: NavbarItem[]): NavbarItem[] { - const subItems = flatten( - items.map((item) => { - const allSubItems = flatten([item.items ?? []]); - return flattenNavbarItems(allSubItems); - }), - ); + const subItems = items.flatMap((item) => { + const allSubItems = [item.items ?? []].flat(); + return flattenNavbarItems(allSubItems); + }); return [...items, ...subItems]; } @@ -84,9 +82,7 @@ function getFooterTranslationFile(footer: Footer): TranslationFileContent { .value(); const footerLinkLabels: TranslationFileContent = chain( - flatten(footer.links.map((link) => link.items)).filter( - (link) => !!link.label, - ), + footer.links.flatMap((link) => link.items).filter((link) => !!link.label), ) .keyBy((linkItem) => `link.item.label.${linkItem.label}`) .mapValues((linkItem) => ({ diff --git a/packages/docusaurus/src/server/brokenLinks.ts b/packages/docusaurus/src/server/brokenLinks.ts index ab385b571b27..62a7557c811e 100644 --- a/packages/docusaurus/src/server/brokenLinks.ts +++ b/packages/docusaurus/src/server/brokenLinks.ts @@ -8,7 +8,7 @@ import {matchRoutes, RouteConfig as RRRouteConfig} from 'react-router-config'; import resolvePathname from 'resolve-pathname'; import fs from 'fs-extra'; -import {mapValues, pickBy, flatten, countBy} from 'lodash'; +import {mapValues, pickBy, countBy} from 'lodash'; import {RouteConfig, ReportingSeverity} from '@docusaurus/types'; import {removePrefix, removeSuffix, reportMessage} from '@docusaurus/utils'; import {getAllFinalRoutes} from './utils'; @@ -110,10 +110,9 @@ export function getBrokenLinksErrorMessage( // Add an additional message in such case to help user figure this out. // see https://github.com/facebook/docusaurus/issues/3567#issuecomment-706973805 function getLayoutBrokenLinksHelpMessage() { - const flatList = flatten( - Object.entries(allBrokenLinks).map(([pagePage, brokenLinks]) => + const flatList = Object.entries(allBrokenLinks).flatMap( + ([pagePage, brokenLinks]) => brokenLinks.map((brokenLink) => ({pagePage, brokenLink})), - ), ); const countedBrokenLinks = countBy( diff --git a/packages/docusaurus/src/server/translations/translationsExtractor.ts b/packages/docusaurus/src/server/translations/translationsExtractor.ts index 31d0fcaf3474..97681daa34d2 100644 --- a/packages/docusaurus/src/server/translations/translationsExtractor.ts +++ b/packages/docusaurus/src/server/translations/translationsExtractor.ts @@ -9,7 +9,6 @@ import traverse, {Node} from '@babel/traverse'; import generate from '@babel/generator'; import chalk from 'chalk'; import {parse, types as t, NodePath, TransformOptions} from '@babel/core'; -import {flatten} from 'lodash'; import { InitializedPlugin, TranslationFileContent, @@ -69,7 +68,7 @@ async function getSourceCodeFilePaths( // The getPathsToWatch() generally returns the js/jsx/ts/tsx/md/mdx file paths // We can use this method as well to know which folders we should try to extract translations from // Hacky/implicit, but do we want to introduce a new lifecycle method for that??? - const pluginsPaths = flatten(plugins.map(getPluginSourceCodeFilePaths)); + const pluginsPaths = plugins.flatMap(getPluginSourceCodeFilePaths); const allPaths = [...sitePaths, ...pluginsPaths]; @@ -133,11 +132,9 @@ export async function extractAllSourceCodeFileTranslations( sourceCodeFilePaths: string[], babelOptions: TransformOptions, ): Promise { - return flatten( - await Promise.all( - sourceCodeFilePaths.map((sourceFilePath) => - extractSourceCodeFileTranslations(sourceFilePath, babelOptions), - ), + return Promise.all( + sourceCodeFilePaths.flatMap((sourceFilePath) => + extractSourceCodeFileTranslations(sourceFilePath, babelOptions), ), ); } diff --git a/packages/docusaurus/src/server/utils.ts b/packages/docusaurus/src/server/utils.ts index 4e154d24597f..e6c4384e38f8 100644 --- a/packages/docusaurus/src/server/utils.ts +++ b/packages/docusaurus/src/server/utils.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -import {flatMap} from 'lodash'; + import {RouteConfig} from '@docusaurus/types'; import nodePath from 'path'; import {posixPath, Globby} from '@docusaurus/utils'; @@ -12,9 +12,9 @@ import {posixPath, Globby} from '@docusaurus/utils'; // Recursively get the final routes (routes with no subroutes) export function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[] { function getFinalRoutes(route: RouteConfig): RouteConfig[] { - return route.routes ? flatMap(route.routes, getFinalRoutes) : [route]; + return route.routes ? route.routes.flatMap(getFinalRoutes) : [route]; } - return flatMap(routeConfig, getFinalRoutes); + return routeConfig.flatMap(getFinalRoutes); } // Globby that fix Windows path patterns diff --git a/website/tsconfig.json b/website/tsconfig.json index 183db790ab5a..600abaf584d0 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -2,6 +2,7 @@ // This file is not used in compilation. It is here just for a nice editor experience. "extends": "@tsconfig/docusaurus/tsconfig.json", "compilerOptions": { + "lib": ["DOM", "ESNext"], "baseUrl": ".", "resolveJsonModule": true },