diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js new file mode 100644 index 000000000000..98da91910299 --- /dev/null +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js @@ -0,0 +1,19 @@ +/** + * 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 = { + title: 'My Site', + tagline: 'The tagline of my site', + url: 'https://your-docusaurus-site.example.com', + baseUrl: '/', + favicon: 'img/favicon.ico', + plugins: [ + function (context, options) { + return {noname: 'on-purpose'}; + }, + ], +}; diff --git a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap b/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap deleted file mode 100644 index 048fb326e44f..000000000000 --- a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`initPlugins throws user-friendly error message for plugins with bad values 1`] = ` -" => Bad Docusaurus plugin value plugins[0]. -Example valid plugin config: -{ - plugins: [ - ["@docusaurus/plugin-content-docs",options], - "./myPlugin", - ["./myPlugin",{someOption: 42}], - function myPlugin() { }, - [function myPlugin() { },options] - ], -}; - - => Bad Docusaurus plugin value plugins[1]. -Example valid plugin config: -{ - plugins: [ - ["@docusaurus/plugin-content-docs",options], - "./myPlugin", - ["./myPlugin",{someOption: 42}], - function myPlugin() { }, - [function myPlugin() { },options] - ], -}; - -" -`; diff --git a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts index 6cbb8af06c3d..d61d913e1f18 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts @@ -10,17 +10,20 @@ import path from 'path'; import {loadContext, type LoadContextParams} from '../../site'; import {initPlugins} from '../init'; -describe('initPlugins', () => { - async function loadSite(options: Omit = {}) { - const siteDir = path.join(__dirname, '__fixtures__', 'site-with-plugin'); - const context = await loadContext({...options, siteDir}); - const plugins = await initPlugins(context); +async function loadSite( + fixtureName: string, + options: Omit = {}, +) { + const siteDir = path.join(__dirname, '__fixtures__', fixtureName); + const context = await loadContext({...options, siteDir}); + const plugins = await initPlugins(context); - return {siteDir, context, plugins}; - } + return {siteDir, context, plugins}; +} +describe('initPlugins', () => { it('parses plugins correctly and loads them in correct order', async () => { - const {context, plugins} = await loadSite(); + const {context, plugins} = await loadSite('site-with-plugin'); expect(context.siteConfig.plugins).toHaveLength(6); expect(plugins).toHaveLength(10); @@ -45,7 +48,41 @@ describe('initPlugins', () => { it('throws user-friendly error message for plugins with bad values', async () => { await expect(() => - loadSite({config: 'badPlugins.docusaurus.config.js'}), - ).rejects.toThrowErrorMatchingSnapshot(); + loadSite('site-with-plugin', {config: 'badPlugins.docusaurus.config.js'}), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + " => Bad Docusaurus plugin value plugins[0]. + Example valid plugin config: + { + plugins: [ + ["@docusaurus/plugin-content-docs",options], + "./myPlugin", + ["./myPlugin",{someOption: 42}], + function myPlugin() { }, + [function myPlugin() { },options] + ], + }; + + => Bad Docusaurus plugin value plugins[1]. + Example valid plugin config: + { + plugins: [ + ["@docusaurus/plugin-content-docs",options], + "./myPlugin", + ["./myPlugin",{someOption: 42}], + function myPlugin() { }, + [function myPlugin() { },options] + ], + }; + + " + `); + }); + + it('throws user-friendly error message for plugins with no name', async () => { + await expect(() => loadSite('site-with-unnamed-plugin')).rejects + .toThrowErrorMatchingInlineSnapshot(` + "A Docusaurus plugin is missing a 'name' property. + Note that even inline/anonymous plugin functions require a 'name' property." + `); }); }); diff --git a/packages/docusaurus/src/server/plugins/init.ts b/packages/docusaurus/src/server/plugins/init.ts index a6100c24ec59..f3dae7c2e9df 100644 --- a/packages/docusaurus/src/server/plugins/init.ts +++ b/packages/docusaurus/src/server/plugins/init.ts @@ -125,6 +125,13 @@ export async function initPlugins( pluginOptions, ); + if (!pluginInstance.name) { + throw new Error( + `A Docusaurus plugin is missing a 'name' property. +Note that even inline/anonymous plugin functions require a 'name' property.`, + ); + } + return { ...pluginInstance, options: pluginOptions,