chore(v2): Fix a lot of eslint warnings (#2972)

This commit is contained in:
Sam Zhou 2020-06-20 00:30:18 -04:00 committed by GitHub
parent 4aa77651d3
commit 3611c96f90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 145 additions and 130 deletions

View file

@ -88,16 +88,11 @@ module.exports = {
// TODO re-enable some these as errors // TODO re-enable some these as errors
// context: https://github.com/facebook/docusaurus/pull/2949 // context: https://github.com/facebook/docusaurus/pull/2949
'@typescript-eslint/no-var-requires': WARNING,
'@typescript-eslint/ban-ts-comment': WARNING, '@typescript-eslint/ban-ts-comment': WARNING,
'@typescript-eslint/ban-types': WARNING, '@typescript-eslint/ban-types': WARNING,
'import/no-duplicates': WARNING,
'import/prefer-default-export': WARNING, 'import/prefer-default-export': WARNING,
'import/no-extraneous-dependencies': WARNING, 'import/no-extraneous-dependencies': WARNING,
'prefer-const': WARNING,
'no-useless-escape': WARNING, 'no-useless-escape': WARNING,
'prefer-object-spread': WARNING,
'no-return-await': WARNING,
'prefer-template': WARNING, 'prefer-template': WARNING,
'no-shadow': WARNING, 'no-shadow': WARNING,
'no-param-reassign': WARNING, 'no-param-reassign': WARNING,
@ -113,7 +108,6 @@ module.exports = {
'no-useless-return': WARNING, 'no-useless-return': WARNING,
'@typescript-eslint/no-empty-function': WARNING, '@typescript-eslint/no-empty-function': WARNING,
'global-require': WARNING, 'global-require': WARNING,
'import/newline-after-import': WARNING,
'prefer-destructuring': WARNING, 'prefer-destructuring': WARNING,
yoda: WARNING, yoda: WARNING,
'no-control-regex': WARNING, 'no-control-regex': WARNING,
@ -133,5 +127,13 @@ module.exports = {
'header/header': OFF, 'header/header': OFF,
}, },
}, },
{
files: ['*.js'],
rules: {
// Make JS code directly runnable in Node.
'@typescript-eslint/no-var-requires': OFF,
'@typescript-eslint/explicit-module-boundary-types': OFF,
},
},
], ],
}; };

View file

@ -17,7 +17,7 @@ function createTestPluginContext(
return { return {
outDir: '/tmp', outDir: '/tmp',
baseUrl: 'https://docusaurus.io', baseUrl: 'https://docusaurus.io',
routesPaths: routesPaths, routesPaths,
options: normalizePluginOptions(options), options: normalizePluginOptions(options),
}; };
} }
@ -192,7 +192,7 @@ describe('collectRedirects', () => {
`/def?queryString=toto`, `/def?queryString=toto`,
]; ];
} }
return; return undefined;
}, },
}, },
['/'], ['/'],
@ -210,7 +210,7 @@ describe('collectRedirects', () => {
if (routePath === '/') { if (routePath === '/') {
return [[`/fromPath`]] as any; return [[`/fromPath`]] as any;
} }
return; return undefined;
}, },
}, },
['/'], ['/'],

View file

@ -51,14 +51,14 @@ describe('validateRedirect', () => {
expect(() => expect(() =>
validateRedirect({ validateRedirect({
from: null as any, from: (null as unknown) as string,
to: '/toSomePath?queryString=xyz', to: '/toSomePath?queryString=xyz',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
expect(() => expect(() =>
validateRedirect({ validateRedirect({
from: ['heyho'] as any, from: (['heyho'] as unknown) as string,
to: '/toSomePath?queryString=xyz', to: '/toSomePath?queryString=xyz',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();

View file

@ -69,7 +69,7 @@ describe('toRedirectFilesMetadata', () => {
describe('writeRedirectFiles', () => { describe('writeRedirectFiles', () => {
test('write the files', async () => { test('write the files', async () => {
const outDir = '/tmp/docusaurus_tests_' + Math.random(); const outDir = `/tmp/docusaurus_tests_${Math.random()}`;
const filesMetadata = [ const filesMetadata = [
{ {
@ -94,7 +94,7 @@ describe('writeRedirectFiles', () => {
}); });
test('avoid overwriting existing files', async () => { test('avoid overwriting existing files', async () => {
const outDir = '/tmp/docusaurus_tests_' + Math.random(); const outDir = `/tmp/docusaurus_tests_${Math.random()}`;
const filesMetadata = [ const filesMetadata = [
{ {

View file

@ -53,7 +53,7 @@ export function createToExtensionsRedirects(
if (extensionFound) { if (extensionFound) {
const routePathWithoutExtension = removeSuffix(path, extensionFound); const routePathWithoutExtension = removeSuffix(path, extensionFound);
return [routePathWithoutExtension].map((from) => ({ return [routePathWithoutExtension].map((from) => ({
from: from, from,
to: path, to: path,
})); }));
} }
@ -78,12 +78,11 @@ export function createFromExtensionsRedirects(
const createPathRedirects = (path: string): RedirectMetadata[] => { const createPathRedirects = (path: string): RedirectMetadata[] => {
if (path === '' || path.endsWith('/') || alreadyEndsWithAnExtension(path)) { if (path === '' || path.endsWith('/') || alreadyEndsWithAnExtension(path)) {
return []; return [];
} else { }
return extensions.map((ext) => ({ return extensions.map((ext) => ({
from: `${path}.${ext}`, from: `${path}.${ext}`,
to: path, to: path,
})); }));
}
}; };
return flatten(paths.map(createPathRedirects)); return flatten(paths.map(createPathRedirects));

View file

@ -21,7 +21,7 @@ export const DefaultPluginOptions: PluginOptions = {
}; };
function isRedirectsCreator( function isRedirectsCreator(
value: any, value: unknown,
): value is CreateRedirectsFnOption | undefined { ): value is CreateRedirectsFnOption | undefined {
if (value === null || typeof value === 'undefined') { if (value === null || typeof value === 'undefined') {
return true; return true;

View file

@ -21,7 +21,7 @@ const RedirectSchema = Yup.object<RedirectMetadata>({
to: PathnameValidator.required(), to: PathnameValidator.required(),
}); });
export function validateRedirect(redirect: RedirectMetadata) { export function validateRedirect(redirect: RedirectMetadata): void {
try { try {
RedirectSchema.validateSync(redirect, { RedirectSchema.validateSync(redirect, {
strict: true, strict: true,

View file

@ -54,7 +54,9 @@ export function toRedirectFilesMetadata(
return redirects.map(createFileMetadata); return redirects.map(createFileMetadata);
} }
export async function writeRedirectFile(file: RedirectFileMetadata) { export async function writeRedirectFile(
file: RedirectFileMetadata,
): Promise<void> {
try { try {
// User-friendly security to prevent file overrides // User-friendly security to prevent file overrides
if (await fs.pathExists(file.fileAbsolutePath)) { if (await fs.pathExists(file.fileAbsolutePath)) {
@ -79,6 +81,6 @@ export async function writeRedirectFile(file: RedirectFileMetadata) {
export default async function writeRedirectFiles( export default async function writeRedirectFiles(
redirectFiles: RedirectFileMetadata[], redirectFiles: RedirectFileMetadata[],
) { ): Promise<void> {
await Promise.all(redirectFiles.map(writeRedirectFile)); await Promise.all(redirectFiles.map(writeRedirectFile));
} }

View file

@ -11,11 +11,9 @@
"access": "public" "access": "public"
}, },
"license": "MIT", "license": "MIT",
"devDependencies": {
"@docusaurus/types": "^2.0.0-alpha.58"
},
"dependencies": { "dependencies": {
"@docusaurus/mdx-loader": "^2.0.0-alpha.58", "@docusaurus/mdx-loader": "^2.0.0-alpha.58",
"@docusaurus/types": "^2.0.0-alpha.58",
"@docusaurus/utils": "^2.0.0-alpha.58", "@docusaurus/utils": "^2.0.0-alpha.58",
"feed": "^4.1.0", "feed": "^4.1.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",

View file

@ -19,7 +19,7 @@ import {
} from '@docusaurus/utils'; } from '@docusaurus/utils';
import {LoadContext} from '@docusaurus/types'; import {LoadContext} from '@docusaurus/types';
export function truncate(fileString: string, truncateMarker: RegExp) { export function truncate(fileString: string, truncateMarker: RegExp): string {
return fileString.split(truncateMarker, 1).shift()!; return fileString.split(truncateMarker, 1).shift()!;
} }
@ -37,7 +37,7 @@ function toUrl({date, link}: DateLink) {
export async function generateBlogFeed( export async function generateBlogFeed(
context: LoadContext, context: LoadContext,
options: PluginOptions, options: PluginOptions,
) { ): Promise<Feed | null> {
if (!options.feedOptions) { if (!options.feedOptions) {
throw new Error( throw new Error(
'Invalid options - `feedOptions` is not expected to be null.', 'Invalid options - `feedOptions` is not expected to be null.',
@ -76,7 +76,7 @@ export async function generateBlogFeed(
} = post; } = post;
feed.addItem({ feed.addItem({
title, title,
id: id, id,
link: normalizeUrl([siteUrl, permalink]), link: normalizeUrl([siteUrl, permalink]),
date, date,
description, description,
@ -90,7 +90,7 @@ export async function generateBlogPosts(
blogDir: string, blogDir: string,
{siteConfig, siteDir}: LoadContext, {siteConfig, siteDir}: LoadContext,
options: PluginOptions, options: PluginOptions,
) { ): Promise<BlogPost[]> {
const { const {
include, include,
routeBasePath, routeBasePath,
@ -181,14 +181,16 @@ export function linkify(
siteDir: string, siteDir: string,
blogPath: string, blogPath: string,
blogPosts: BlogPost[], blogPosts: BlogPost[],
) { ): string {
let fencedBlock = false; let fencedBlock = false;
const lines = fileContent.split('\n').map((line) => { const lines = fileContent.split('\n').map((line) => {
if (line.trim().startsWith('```')) { if (line.trim().startsWith('```')) {
fencedBlock = !fencedBlock; fencedBlock = !fencedBlock;
} }
if (fencedBlock) return line; if (fencedBlock) {
return line;
}
let modifiedLine = line; let modifiedLine = line;
const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.mdx?)/g; const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.mdx?)/g;

View file

@ -12,12 +12,12 @@
}, },
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@docusaurus/types": "^2.0.0-alpha.58",
"commander": "^5.0.0", "commander": "^5.0.0",
"picomatch": "^2.1.1" "picomatch": "^2.1.1"
}, },
"dependencies": { "dependencies": {
"@docusaurus/mdx-loader": "^2.0.0-alpha.58", "@docusaurus/mdx-loader": "^2.0.0-alpha.58",
"@docusaurus/types": "^2.0.0-alpha.58",
"@docusaurus/utils": "^2.0.0-alpha.58", "@docusaurus/utils": "^2.0.0-alpha.58",
"execa": "^3.4.0", "execa": "^3.4.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",

View file

@ -310,7 +310,7 @@ describe('versioned website', () => {
permalink: '/docs/next/', permalink: '/docs/next/',
}, },
}); });
expect(docsMetadata['hello']).toEqual({ expect(docsMetadata.hello).toEqual({
id: 'hello', id: 'hello',
isDocsHomePage: true, isDocsHomePage: true,
permalink: '/docs/next/', permalink: '/docs/next/',

View file

@ -68,7 +68,7 @@ const DEFAULT_OPTIONS: PluginOptions = {
function getFirstDocLinkOfSidebar( function getFirstDocLinkOfSidebar(
sidebarItems: DocsSidebarItem[], sidebarItems: DocsSidebarItem[],
): string | null { ): string | null {
for (let sidebarItem of sidebarItems) { for (const sidebarItem of sidebarItems) {
if (sidebarItem.type === 'category') { if (sidebarItem.type === 'category') {
const url = getFirstDocLinkOfSidebar(sidebarItem.items); const url = getFirstDocLinkOfSidebar(sidebarItem.items);
if (url) { if (url) {
@ -534,7 +534,7 @@ Available document ids=
options: { options: {
siteDir, siteDir,
docsDir, docsDir,
sourceToPermalink: sourceToPermalink, sourceToPermalink,
versionedDir, versionedDir,
}, },
}, },

View file

@ -17,7 +17,7 @@ export default function (
siteDir: string, siteDir: string,
sourceToPermalink: SourceToPermalink, sourceToPermalink: SourceToPermalink,
versionedDir?: string, versionedDir?: string,
) { ): string {
// Determine the source dir. e.g: /website/docs, /website/versioned_docs/version-1.0.0 // Determine the source dir. e.g: /website/docs, /website/versioned_docs/version-1.0.0
let sourceDir: string | undefined; let sourceDir: string | undefined;
const thisSource = filePath; const thisSource = filePath;
@ -40,7 +40,9 @@ export default function (
if (line.trim().startsWith('```')) { if (line.trim().startsWith('```')) {
fencedBlock = !fencedBlock; fencedBlock = !fencedBlock;
} }
if (fencedBlock) return line; if (fencedBlock) {
return line;
}
let modifiedLine = line; let modifiedLine = line;
// Replace inline-style links or reference-style links e.g: // Replace inline-style links or reference-style links e.g:

View file

@ -135,7 +135,7 @@ function normalizeItem(item: SidebarItemRaw): SidebarItem[] {
case 'doc': case 'doc':
assertIsDoc(item); assertIsDoc(item);
return [item]; return [item];
default: default: {
const extraMigrationError = const extraMigrationError =
item.type === 'subcategory' item.type === 'subcategory'
? "Docusaurus v2: 'subcategory' has been renamed as 'category'" ? "Docusaurus v2: 'subcategory' has been renamed as 'category'"
@ -147,6 +147,7 @@ function normalizeItem(item: SidebarItemRaw): SidebarItem[] {
); );
} }
} }
}
/** /**
* Converts sidebars object to mapping to arrays of sidebar item objects. * Converts sidebars object to mapping to arrays of sidebar item objects.
@ -168,7 +169,7 @@ function normalizeSidebar(sidebars: SidebarRaw): Sidebar {
export default function loadSidebars(sidebarPaths?: string[]): Sidebar { export default function loadSidebars(sidebarPaths?: string[]): Sidebar {
// We don't want sidebars to be cached because of hot reloading. // We don't want sidebars to be cached because of hot reloading.
let allSidebars: SidebarRaw = {}; const allSidebars: SidebarRaw = {};
if (!sidebarPaths || !sidebarPaths.length) { if (!sidebarPaths || !sidebarPaths.length) {
return {} as Sidebar; return {} as Sidebar;

View file

@ -19,7 +19,7 @@ export function docsVersion(
version: string | null | undefined, version: string | null | undefined,
siteDir: string, siteDir: string,
options: PathOptions, options: PathOptions,
) { ): void {
if (!version) { if (!version) {
throw new Error( throw new Error(
'No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0', 'No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0',

View file

@ -28,7 +28,7 @@ describe('createSitemap', () => {
test('empty site', () => { test('empty site', () => {
expect(() => { expect(() => {
createSitemap({} as any, [], {} as any); createSitemap({} as DocusaurusConfig, [], {} as any);
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"url in docusaurus.config.js cannot be empty/undefined"`, `"url in docusaurus.config.js cannot be empty/undefined"`,
); );

View file

@ -9,7 +9,7 @@ import fs from 'fs-extra';
import path from 'path'; import path from 'path';
import {PluginOptions} from './types'; import {PluginOptions} from './types';
import createSitemap from './createSitemap'; import createSitemap from './createSitemap';
import {LoadContext, Props} from '@docusaurus/types'; import {LoadContext, Props, Plugin} from '@docusaurus/types';
const DEFAULT_OPTIONS: PluginOptions = { const DEFAULT_OPTIONS: PluginOptions = {
cacheTime: 600 * 1000, // 600 sec - cache purge period. cacheTime: 600 * 1000, // 600 sec - cache purge period.
@ -20,7 +20,7 @@ const DEFAULT_OPTIONS: PluginOptions = {
export default function pluginSitemap( export default function pluginSitemap(
_context: LoadContext, _context: LoadContext,
opts: Partial<PluginOptions>, opts: Partial<PluginOptions>,
) { ): Plugin<void> {
const options = {...DEFAULT_OPTIONS, ...opts}; const options = {...DEFAULT_OPTIONS, ...opts};
return { return {

View file

@ -197,7 +197,7 @@ export function createExcerpt(fileString: string): string | undefined {
const fileLines = fileContent.split('\n'); const fileLines = fileContent.split('\n');
for (let fileLine of fileLines) { for (const fileLine of fileLines) {
const cleanedLine = fileLine const cleanedLine = fileLine
// Remove HTML tags. // Remove HTML tags.
.replace(/<[^>]*>/g, '') .replace(/<[^>]*>/g, '')
@ -338,14 +338,17 @@ export function normalizeUrl(rawUrls: string[]): string {
* don't expose user's site structure. * don't expose user's site structure.
* Example: some/path/to/website/docs/foo.md -> @site/docs/foo.md * Example: some/path/to/website/docs/foo.md -> @site/docs/foo.md
*/ */
export function aliasedSitePath(filePath: string, siteDir: string) { export function aliasedSitePath(filePath: string, siteDir: string): string {
const relativePath = path.relative(siteDir, filePath); const relativePath = path.relative(siteDir, filePath);
// Cannot use path.join() as it resolves '../' and removes // Cannot use path.join() as it resolves '../' and removes
// the '@site'. Let webpack loader resolve it. // the '@site'. Let webpack loader resolve it.
return `@site/${relativePath}`; return `@site/${relativePath}`;
} }
export function getEditUrl(fileRelativePath: string, editUrl?: string) { export function getEditUrl(
fileRelativePath: string,
editUrl?: string,
): string | undefined {
return editUrl return editUrl
? normalizeUrl([editUrl, posixPath(fileRelativePath)]) ? normalizeUrl([editUrl, posixPath(fileRelativePath)])
: undefined; : undefined;
@ -362,22 +365,22 @@ export function isValidPathname(str: string): boolean {
} }
} }
export function addTrailingSlash(str: string) { export function addTrailingSlash(str: string): string {
return str.endsWith('/') ? str : `${str}/`; return str.endsWith('/') ? str : `${str}/`;
} }
export function removeTrailingSlash(str: string) { export function removeTrailingSlash(str: string): string {
return removeSuffix(str, '/'); return removeSuffix(str, '/');
} }
export function removeSuffix(str: string, suffix: string) { export function removeSuffix(str: string, suffix: string): string {
if (suffix === '') { if (suffix === '') {
return str; // always returns "" otherwise! return str; // always returns "" otherwise!
} }
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str; return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
} }
export function getFilePathForRoutePath(routePath: string) { export function getFilePathForRoutePath(routePath: string): string {
const fileName = path.basename(routePath); const fileName = path.basename(routePath);
const filePath = path.dirname(routePath); const filePath = path.dirname(routePath);
return path.join(filePath, `${fileName}/index.html`); return path.join(filePath, `${fileName}/index.html`);

View file

@ -30,8 +30,7 @@
"url": "https://github.com/facebook/docusaurus/issues" "url": "https://github.com/facebook/docusaurus/issues"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "^2.0.0-alpha.58", "@docusaurus/module-type-aliases": "^2.0.0-alpha.58"
"@docusaurus/types": "^2.0.0-alpha.58"
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.9.0", "@babel/core": "^7.9.0",
@ -41,6 +40,7 @@
"@babel/preset-react": "^7.9.4", "@babel/preset-react": "^7.9.4",
"@babel/preset-typescript": "^7.9.0", "@babel/preset-typescript": "^7.9.0",
"@babel/runtime": "^7.9.2", "@babel/runtime": "^7.9.2",
"@docusaurus/types": "^2.0.0-alpha.58",
"@docusaurus/utils": "^2.0.0-alpha.58", "@docusaurus/utils": "^2.0.0-alpha.58",
"@endiliey/static-site-generator-webpack-plugin": "^4.0.0", "@endiliey/static-site-generator-webpack-plugin": "^4.0.0",
"@svgr/webpack": "^5.4.0", "@svgr/webpack": "^5.4.0",

View file

@ -50,6 +50,7 @@ function getTransformOptions(isServer: boolean): TransformOptions {
// By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0, better to // By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0, better to
// explicitly specify the version so that it can reuse the helper better // explicitly specify the version so that it can reuse the helper better
// See https://github.com/babel/babel/issues/10261 // See https://github.com/babel/babel/issues/10261
// eslint-disable-next-line @typescript-eslint/no-var-requires
version: require('@babel/runtime/package.json').version, version: require('@babel/runtime/package.json').version,
regenerator: true, regenerator: true,
useESModules: true, useESModules: true,
@ -74,8 +75,8 @@ function getTransformOptions(isServer: boolean): TransformOptions {
} }
function babelPresets(api: ConfigAPI): TransformOptions { function babelPresets(api: ConfigAPI): TransformOptions {
const caller = api.caller((caller) => caller?.name); const callerName = api.caller((caller) => caller?.name);
return getTransformOptions(caller === 'server'); return getTransformOptions(callerName === 'server');
} }
export = babelPresets; export = babelPresets;

View file

@ -15,7 +15,7 @@ import PendingNavigation from './PendingNavigation';
import './client-lifecycles-dispatcher'; import './client-lifecycles-dispatcher';
function App() { function App(): JSX.Element {
const [isClient, setIsClient] = useState(false); const [isClient, setIsClient] = useState(false);
useEffect(() => { useEffect(() => {

View file

@ -15,6 +15,7 @@ const fetched = {};
const loaded = {}; const loaded = {};
declare global { declare global {
// eslint-disable-next-line camelcase
const __webpack_require__: any; const __webpack_require__: any;
interface Navigator { interface Navigator {
connection: any; connection: any;

View file

@ -8,7 +8,7 @@
import React from 'react'; import React from 'react';
import {Helmet} from 'react-helmet'; import {Helmet} from 'react-helmet';
function Head(props) { function Head(props): JSX.Element {
return <Helmet {...props} />; return <Helmet {...props} />;
} }

View file

@ -23,7 +23,7 @@ interface Props {
readonly href: string; readonly href: string;
} }
function Link({isNavLink, ...props}: Props) { function Link({isNavLink, ...props}: Props): JSX.Element {
const {to, href} = props; const {to, href} = props;
const targetLink = to || href; const targetLink = to || href;
const isInternal = isInternalUrl(targetLink); const isInternal = isInternalUrl(targetLink);

View file

@ -5,4 +5,4 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
export default () => null; export default (): null => null;

View file

@ -7,6 +7,7 @@
import useBaseUrl from '../useBaseUrl'; import useBaseUrl from '../useBaseUrl';
import useDocusaurusContext from '../useDocusaurusContext'; import useDocusaurusContext from '../useDocusaurusContext';
jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true}); jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true});
const mockedContext = <jest.Mock>useDocusaurusContext; const mockedContext = <jest.Mock>useDocusaurusContext;

View file

@ -7,8 +7,9 @@
import {useContext} from 'react'; import {useContext} from 'react';
import context from './context'; import context from './context';
import {DocusaurusContext} from '@docusaurus/types';
function useDocusaurusContext() { function useDocusaurusContext(): DocusaurusContext {
return useContext(context); return useContext(context);
} }

View file

@ -22,7 +22,7 @@ function support(feature) {
return false; return false;
} }
function linkPrefetchStrategy(url) { function linkPrefetchStrategy(url: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (typeof document === 'undefined') { if (typeof document === 'undefined') {
reject(); reject();
@ -43,7 +43,7 @@ function linkPrefetchStrategy(url) {
}); });
} }
function xhrPrefetchStrategy(url) { function xhrPrefetchStrategy(url: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const req = new XMLHttpRequest(); const req = new XMLHttpRequest();
req.open('GET', url, true); req.open('GET', url, true);
@ -67,7 +67,7 @@ const supportedPrefetchStrategy = support('prefetch')
const preFetched = {}; const preFetched = {};
function prefetch(url) { function prefetch(url: string): Promise<void> {
return new Promise((resolve) => { return new Promise((resolve) => {
if (preFetched[url]) { if (preFetched[url]) {
resolve(); resolve();
@ -79,6 +79,7 @@ function prefetch(url) {
resolve(); resolve();
preFetched[url] = true; preFetched[url] = true;
}) })
// eslint-disable-next-line @typescript-eslint/no-empty-function
.catch(() => {}); // 404s are logged to the console anyway. .catch(() => {}); // 404s are logged to the console anyway.
}); });
} }

View file

@ -15,7 +15,7 @@ import {matchRoutes} from 'react-router-config';
* @param {string} pathname the route pathname, example: /docs/installation * @param {string} pathname the route pathname, example: /docs/installation
* @returns {Promise} Promise object represents whether pathname has been preloaded * @returns {Promise} Promise object represents whether pathname has been preloaded
*/ */
export default function preload(routes, pathname) { export default function preload(routes, pathname: string) {
const matches = matchRoutes(routes, pathname); const matches = matchRoutes(routes, pathname);
return Promise.all( return Promise.all(

View file

@ -36,7 +36,7 @@ function compile(config: Configuration[]): Promise<any> {
} }
if (stats.hasWarnings()) { if (stats.hasWarnings()) {
// Custom filtering warnings (see https://github.com/webpack/webpack/issues/7841). // Custom filtering warnings (see https://github.com/webpack/webpack/issues/7841).
let warnings = stats.toJson('errors-warnings').warnings; let {warnings} = stats.toJson('errors-warnings');
const warningsFilter = ((config[0].stats as Stats.ToJsonOptionsObject) const warningsFilter = ((config[0].stats as Stats.ToJsonOptionsObject)
?.warningsFilter || []) as any[]; ?.warningsFilter || []) as any[];
@ -142,7 +142,9 @@ export async function build(
) { ) {
const serverBundle = path.join(outDir, serverConfig.output.filename); const serverBundle = path.join(outDir, serverConfig.output.filename);
fs.pathExists(serverBundle).then((exist) => { fs.pathExists(serverBundle).then((exist) => {
exist && fs.unlink(serverBundle); if (exist) {
fs.unlink(serverBundle);
}
}); });
} }
@ -162,6 +164,8 @@ export async function build(
relativeDir, relativeDir,
)}.\n`, )}.\n`,
); );
forceTerminate && !cliOptions.bundleAnalyzer && process.exit(0); if (forceTerminate && !cliOptions.bundleAnalyzer) {
process.exit(0);
}
return outDir; return outDir;
} }

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {normalizeUrl} from '@docusaurus/utils'; import {normalizeUrl, posixPath} from '@docusaurus/utils';
import chalk = require('chalk'); import chalk = require('chalk');
import chokidar from 'chokidar'; import chokidar from 'chokidar';
import express from 'express'; import express from 'express';
@ -22,7 +22,6 @@ import merge from 'webpack-merge';
import HotModuleReplacementPlugin from 'webpack/lib/HotModuleReplacementPlugin'; import HotModuleReplacementPlugin from 'webpack/lib/HotModuleReplacementPlugin';
import {load} from '../server'; import {load} from '../server';
import {StartCLIOptions} from '@docusaurus/types'; import {StartCLIOptions} from '@docusaurus/types';
import {posixPath} from '@docusaurus/utils';
import {CONFIG_FILE_NAME, STATIC_DIR_NAME, DEFAULT_PORT} from '../constants'; import {CONFIG_FILE_NAME, STATIC_DIR_NAME, DEFAULT_PORT} from '../constants';
import {createClientConfig} from '../webpack/client'; import {createClientConfig} from '../webpack/client';
import {applyConfigureWebpack} from '../webpack/utils'; import {applyConfigureWebpack} from '../webpack/utils';

View file

@ -7,9 +7,9 @@
import {loadClientModules} from '../index'; import {loadClientModules} from '../index';
const pluginEmpty = require('./__fixtures__/plugin-empty'); import pluginEmpty from './__fixtures__/plugin-empty';
const pluginFooBar = require('./__fixtures__/plugin-foo-bar'); import pluginFooBar from './__fixtures__/plugin-foo-bar';
const pluginHelloWorld = require('./__fixtures__/plugin-hello-world'); import pluginHelloWorld from './__fixtures__/plugin-hello-world';
describe('loadClientModules', () => { describe('loadClientModules', () => {
test('empty', () => { test('empty', () => {

View file

@ -7,7 +7,7 @@
import {Plugin} from '@docusaurus/types'; import {Plugin} from '@docusaurus/types';
export function loadClientModules(plugins: Plugin<any>[]): string[] { export function loadClientModules(plugins: Plugin<unknown>[]): string[] {
return ([] as string[]).concat( return ([] as string[]).concat(
...plugins ...plugins
.map<any>( .map<any>(

View file

@ -32,10 +32,10 @@ const DEFAULT_CONFIG: {
plugins: PluginConfig[]; plugins: PluginConfig[];
themes: PluginConfig[]; themes: PluginConfig[];
customFields: { customFields: {
[key: string]: any; [key: string]: unknown;
}; };
themeConfig: { themeConfig: {
[key: string]: any; [key: string]: unknown;
}; };
} = { } = {
plugins: [], plugins: [],

View file

@ -7,10 +7,10 @@
import {loadHtmlTags} from '../index'; import {loadHtmlTags} from '../index';
const pluginEmpty = require('./__fixtures__/plugin-empty'); import pluginEmpty from './__fixtures__/plugin-empty';
const pluginPreBodyTags = require('./__fixtures__/plugin-preBodyTags'); import pluginPreBodyTags from './__fixtures__/plugin-preBodyTags';
const pluginHeadTags = require('./__fixtures__/plugin-headTags'); import pluginHeadTags from './__fixtures__/plugin-headTags';
const pluginPostBodyTags = require('./__fixtures__/plugin-postBodyTags'); import pluginPostBodyTags from './__fixtures__/plugin-postBodyTags';
describe('loadHtmlTags', () => { describe('loadHtmlTags', () => {
test('empty plugin', () => { test('empty plugin', () => {

View file

@ -23,7 +23,7 @@ function assertIsHtmlTagObject(val: any): asserts val is HtmlTagObject {
} }
} }
export function htmlTagObjectToString(tagDefinition: any): string { export function htmlTagObjectToString(tagDefinition: unknown): string {
assertIsHtmlTagObject(tagDefinition); assertIsHtmlTagObject(tagDefinition);
if (htmlTags.indexOf(tagDefinition.tagName) === -1) { if (htmlTags.indexOf(tagDefinition.tagName) === -1) {
throw new Error( throw new Error(
@ -40,13 +40,9 @@ export function htmlTagObjectToString(tagDefinition: any): string {
if (tagAttributes[attributeName] === true) { if (tagAttributes[attributeName] === true) {
return attributeName; return attributeName;
} }
return attributeName + '="' + tagAttributes[attributeName] + '"'; return `${attributeName}="${tagAttributes[attributeName]}"`;
}); });
return ( return `<${[tagDefinition.tagName].concat(attributes).join(' ')}>${
'<' + (!isVoidTag && tagDefinition.innerHTML) || ''
[tagDefinition.tagName].concat(attributes).join(' ') + }${isVoidTag ? '' : `</${tagDefinition.tagName}>`}`;
'>' +
((!isVoidTag && tagDefinition.innerHTML) || '') +
(isVoidTag ? '' : '</' + tagDefinition.tagName + '>')
);
} }

View file

@ -31,13 +31,13 @@ export function loadHtmlTags(plugins: Plugin<any>[]): InjectedHtmlTags {
plugin.injectHtmlTags() || {}; plugin.injectHtmlTags() || {};
return { return {
headTags: headTags headTags: headTags
? acc.headTags + '\n' + createHtmlTagsString(headTags) ? `${acc.headTags}\n${createHtmlTagsString(headTags)}`
: acc.headTags, : acc.headTags,
preBodyTags: preBodyTags preBodyTags: preBodyTags
? acc.preBodyTags + '\n' + createHtmlTagsString(preBodyTags) ? `${acc.preBodyTags}\n${createHtmlTagsString(preBodyTags)}`
: acc.preBodyTags, : acc.preBodyTags,
postBodyTags: postBodyTags postBodyTags: postBodyTags
? acc.postBodyTags + '\n' + createHtmlTagsString(postBodyTags) ? `${acc.postBodyTags}\n${createHtmlTagsString(postBodyTags)}`
: acc.postBodyTags, : acc.postBodyTags,
}; };
}, },

View file

@ -17,7 +17,7 @@ import {
} from '@docusaurus/types'; } from '@docusaurus/types';
import {initPlugins} from './init'; import {initPlugins} from './init';
export function sortConfig(routeConfigs: RouteConfig[]) { export function sortConfig(routeConfigs: RouteConfig[]): void {
// Sort the route config. This ensures that route with nested // Sort the route config. This ensures that route with nested
// routes is always placed last. // routes is always placed last.
routeConfigs.sort((a, b) => { routeConfigs.sort((a, b) => {
@ -55,11 +55,11 @@ export async function loadPlugins({
pluginConfigs: PluginConfig[]; pluginConfigs: PluginConfig[];
context: LoadContext; context: LoadContext;
}): Promise<{ }): Promise<{
plugins: Plugin<any>[]; plugins: Plugin<unknown>[];
pluginsRouteConfigs: RouteConfig[]; pluginsRouteConfigs: RouteConfig[];
}> { }> {
// 1. Plugin Lifecycle - Initialization/Constructor. // 1. Plugin Lifecycle - Initialization/Constructor.
const plugins: Plugin<any>[] = initPlugins({pluginConfigs, context}); const plugins: Plugin<unknown>[] = initPlugins({pluginConfigs, context});
// 2. Plugin Lifecycle - loadContent. // 2. Plugin Lifecycle - loadContent.
// Currently plugins run lifecycle methods in parallel and are not order-dependent. // Currently plugins run lifecycle methods in parallel and are not order-dependent.
@ -71,7 +71,7 @@ export async function loadPlugins({
return null; return null;
} }
return await plugin.loadContent(); return plugin.loadContent();
}), }),
); );
@ -116,7 +116,7 @@ export async function loadPlugins({
return null; return null;
} }
return await plugin.routesLoaded(pluginsRouteConfigs); return plugin.routesLoaded(pluginsRouteConfigs);
}), }),
); );

View file

@ -29,8 +29,7 @@ export function loadPresets(
if (typeof presetItem === 'string') { if (typeof presetItem === 'string') {
presetModuleImport = presetItem; presetModuleImport = presetItem;
} else if (Array.isArray(presetItem)) { } else if (Array.isArray(presetItem)) {
presetModuleImport = presetItem[0]; [presetModuleImport, presetOptions = {}] = presetItem;
presetOptions = presetItem[1] || {};
} else { } else {
throw new Error('Invalid presets format detected in config.'); throw new Error('Invalid presets format detected in config.');
} }
@ -41,8 +40,12 @@ export function loadPresets(
presetOptions, presetOptions,
); );
preset.plugins && unflatPlugins.push(preset.plugins); if (preset.plugins) {
preset.themes && unflatThemes.push(preset.themes); unflatPlugins.push(preset.plugins);
}
if (preset.themes) {
unflatThemes.push(preset.themes);
}
}); });
return { return {

View file

@ -18,7 +18,7 @@ import {
ChunkNames, ChunkNames,
} from '@docusaurus/types'; } from '@docusaurus/types';
function isModule(value: any): value is Module { function isModule(value: unknown): value is Module {
if (isString(value)) { if (isString(value)) {
return true; return true;
} }
@ -111,12 +111,11 @@ export async function loadRoutes(
return newValue; return newValue;
} }
routesChunkNames[routePath] = Object.assign( routesChunkNames[routePath] = {
{}, ...routesChunkNames[routePath],
routesChunkNames[routePath], ...genRouteChunkNames({component}, 'component', component),
genRouteChunkNames({component}, 'component', component), ...genRouteChunkNames(modules, 'module', routePath),
genRouteChunkNames(modules, 'module', routePath), };
);
const routesStr = routes const routesStr = routes
? `routes: [${routes.map(generateRouteCode).join(',')}],` ? `routes: [${routes.map(generateRouteCode).join(',')}],`

View file

@ -21,7 +21,7 @@ const CSS_REGEX = /\.css$/;
const CSS_MODULE_REGEX = /\.module\.css$/; const CSS_MODULE_REGEX = /\.module\.css$/;
export const clientDir = path.join(__dirname, '..', 'client'); export const clientDir = path.join(__dirname, '..', 'client');
export function excludeJS(modulePath: string) { export function excludeJS(modulePath: string): boolean {
// always transpile client dir // always transpile client dir
if (modulePath.startsWith(clientDir)) { if (modulePath.startsWith(clientDir)) {
return false; return false;

View file

@ -10,7 +10,7 @@ import {Template, Compiler} from 'webpack';
const pluginName = 'chunk-asset-plugin'; const pluginName = 'chunk-asset-plugin';
class ChunkAssetPlugin { class ChunkAssetPlugin {
apply(compiler: Compiler) { apply(compiler: Compiler): void {
compiler.hooks.thisCompilation.tap(pluginName, ({mainTemplate}) => { compiler.hooks.thisCompilation.tap(pluginName, ({mainTemplate}) => {
/* We modify webpack runtime to add an extra function called "__webpack_require__.gca" /* We modify webpack runtime to add an extra function called "__webpack_require__.gca"
that will allow us to get the corresponding chunk asset for a webpack chunk. that will allow us to get the corresponding chunk asset for a webpack chunk.
@ -20,18 +20,19 @@ class ChunkAssetPlugin {
mainTemplate.hooks.requireExtensions.tap(pluginName, (source, chunk) => { mainTemplate.hooks.requireExtensions.tap(pluginName, (source, chunk) => {
const chunkIdToName = chunk.getChunkMaps(false).name; const chunkIdToName = chunk.getChunkMaps(false).name;
const chunkNameToId = Object.create(null); const chunkNameToId = Object.create(null);
for (const chunkId of Object.keys(chunkIdToName)) { Object.keys(chunkIdToName).forEach((chunkId) => {
const chunkName = chunkIdToName[chunkId]; const chunkName = chunkIdToName[chunkId];
chunkNameToId[chunkName] = chunkId; chunkNameToId[chunkName] = chunkId;
} });
const buf = [source]; const buf = [source];
buf.push(''); buf.push('');
buf.push('// function to get chunk assets'); buf.push('// function to get chunk assets');
buf.push( buf.push(
mainTemplate.requireFn +
// If chunkName is passed, we convert it to chunk id // If chunkName is passed, we convert it to chunk id
// Note that jsonpScriptSrc is an internal webpack function // Note that jsonpScriptSrc is an internal webpack function
`.gca = function(chunkId) { chunkId = ${JSON.stringify( `${
mainTemplate.requireFn
}.gca = function(chunkId) { chunkId = ${JSON.stringify(
chunkNameToId, chunkNameToId,
)}[chunkId]||chunkId; return jsonpScriptSrc(chunkId); };`, )}[chunkId]||chunkId; return jsonpScriptSrc(chunkId); };`,
); );

View file

@ -180,7 +180,7 @@ class CleanWebpackPlugin {
this.removeFiles = this.removeFiles.bind(this); this.removeFiles = this.removeFiles.bind(this);
} }
apply(compiler: Compiler) { apply(compiler: Compiler): void {
if (!compiler.options.output || !compiler.options.output.path) { if (!compiler.options.output || !compiler.options.output.path) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn( console.warn(
@ -197,7 +197,7 @@ class CleanWebpackPlugin {
* *
* Check for hooks in-order to support old plugin system * Check for hooks in-order to support old plugin system
*/ */
const hooks = compiler.hooks; const {hooks} = compiler;
if (this.cleanOnceBeforeBuildPatterns.length !== 0) { if (this.cleanOnceBeforeBuildPatterns.length !== 0) {
if (hooks) { if (hooks) {
@ -229,7 +229,7 @@ class CleanWebpackPlugin {
* *
* Warning: It is recommended to initially clean your build directory outside of webpack to minimize unexpected behavior. * Warning: It is recommended to initially clean your build directory outside of webpack to minimize unexpected behavior.
*/ */
handleInitial() { handleInitial(): void {
if (this.initialClean) { if (this.initialClean) {
return; return;
} }
@ -239,7 +239,7 @@ class CleanWebpackPlugin {
this.removeFiles(this.cleanOnceBeforeBuildPatterns); this.removeFiles(this.cleanOnceBeforeBuildPatterns);
} }
handleDone(stats: Stats) { handleDone(stats: Stats): void {
/** /**
* Do nothing if there is a webpack error * Do nothing if there is a webpack error
*/ */
@ -304,7 +304,7 @@ class CleanWebpackPlugin {
} }
} }
removeFiles(patterns: string[]) { removeFiles(patterns: string[]): void {
try { try {
const deleted = delSync(patterns, { const deleted = delSync(patterns, {
force: this.dangerouslyAllowCleanPatternsOutsideProject, force: this.dangerouslyAllowCleanPatternsOutsideProject,

View file

@ -53,6 +53,7 @@ export function getStyleLoaders(
// https://github.com/facebook/create-react-app/issues/2677 // https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss', ident: 'postcss',
plugins: () => [ plugins: () => [
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('postcss-preset-env')({ require('postcss-preset-env')({
autoprefixer: { autoprefixer: {
flexbox: 'no-2009', flexbox: 'no-2009',
@ -76,12 +77,10 @@ export function getCacheLoader(
return { return {
loader: require.resolve('cache-loader'), loader: require.resolve('cache-loader'),
options: Object.assign( options: {
{
cacheIdentifier: `cache-loader:${cacheLoaderVersion}${isServer}`, cacheIdentifier: `cache-loader:${cacheLoaderVersion}${isServer}`,
...cacheOptions,
}, },
cacheOptions,
),
}; };
} }

View file

@ -32,8 +32,8 @@ describe('lqip-loader', () => {
const vibrant = new Vibrant(imgPath, {}); const vibrant = new Vibrant(imgPath, {});
return vibrant.getPalette().then((palette) => { return vibrant.getPalette().then((palette) => {
correctTestSwatch = Object.assign({}, palette); correctTestSwatch = {...palette};
testSwatchWithNull = Object.assign({}, palette, {Vibrant: null}); testSwatchWithNull = {...palette, Vibrant: null};
}); });
}); });