diff --git a/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts b/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts index 192f457620b06..15155f419d82d 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts @@ -100,7 +100,7 @@ describe(`Load plugins`, () => { } }) - it(`Overrides the options for gatsby-plugin-page-creator`, async () => { + it.only(`Overrides the options for gatsby-plugin-page-creator`, async () => { const config = { plugins: [ { diff --git a/packages/gatsby/src/bootstrap/load-plugins/resolve-plugin.ts b/packages/gatsby/src/bootstrap/load-plugins/resolve-plugin.ts index 9cd103b95eca6..4244c51594cd0 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/resolve-plugin.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/resolve-plugin.ts @@ -1,7 +1,6 @@ import path from "path" import fs from "fs" import { slash, createRequireFromPath } from "gatsby-core-utils" -import { sync as existsSync } from "fs-exists-cached" import { warnOnIncompatiblePeerDependency } from "./validate" import { PackageJson } from "../../.." import { IPluginInfo, PluginRef } from "./types" @@ -9,6 +8,7 @@ import { createPluginId } from "./utils/create-id" import { createFileContentHash } from "./utils/create-hash" import reporter from "gatsby-cli/lib/reporter" import { isString } from "lodash" +import { checkLocalPlugin } from "./utils/check-local-plugin" /** * @param plugin @@ -24,30 +24,25 @@ import { isString } from "lodash" export function resolvePlugin(plugin: PluginRef, rootDir: string): IPluginInfo { const pluginName = isString(plugin) ? plugin : plugin.resolve - // Only find plugins when we're not given an absolute path - if (!existsSync(pluginName) && rootDir) { - // Find the plugin in the local plugins folder - const resolvedPath = slash(path.join(rootDir, `plugins/${pluginName}`)) + // Handle local plugins + const { validLocalPlugin, localPluginPath = `` } = checkLocalPlugin( + plugin, + rootDir + ) - if (existsSync(resolvedPath)) { - if (existsSync(`${resolvedPath}/package.json`)) { - const packageJSON = JSON.parse( - fs.readFileSync(`${resolvedPath}/package.json`, `utf-8`) - ) as PackageJson - const name = packageJSON.name || pluginName - warnOnIncompatiblePeerDependency(name, packageJSON) + if (validLocalPlugin && localPluginPath) { + const packageJSON = JSON.parse( + fs.readFileSync(`${localPluginPath}/package.json`, `utf-8`) + ) as PackageJson + const name = packageJSON.name || pluginName + warnOnIncompatiblePeerDependency(name, packageJSON) - return { - resolve: resolvedPath, - name, - id: createPluginId(name), - version: - packageJSON.version || createFileContentHash(resolvedPath, `**`), - } - } else { - // Make package.json a requirement for local plugins too - throw new Error(`Plugin ${pluginName} requires a package.json file`) - } + return { + resolve: localPluginPath, + name, + id: createPluginId(name), + version: + packageJSON.version || createFileContentHash(localPluginPath, `**`), } } diff --git a/packages/gatsby/src/bootstrap/load-plugins/utils/check-local-plugin.ts b/packages/gatsby/src/bootstrap/load-plugins/utils/check-local-plugin.ts new file mode 100644 index 0000000000000..974926b56c656 --- /dev/null +++ b/packages/gatsby/src/bootstrap/load-plugins/utils/check-local-plugin.ts @@ -0,0 +1,41 @@ +import { PluginRef } from "../types" +import { sync as existsSync } from "fs-exists-cached" +import { slash } from "gatsby-core-utils" +import path from "path" + +/** + * Checks if a plugin is a valid local plugin and returns the resolved path if it is. + */ +export function checkLocalPlugin( + plugin: PluginRef, + rootDir: string +): { validLocalPlugin: boolean; localPluginPath?: string } { + const pluginName = typeof plugin === `string` ? plugin : plugin.resolve + + // Make sure the plugin exists relatively + if (existsSync(pluginName) || !rootDir) { + return { + validLocalPlugin: false, + } + } + + const resolvedPath = slash(path.join(rootDir, `plugins/${pluginName}`)) + + if (!existsSync(resolvedPath)) { + return { + validLocalPlugin: false, + } + } + + const resolvedPackageJson = existsSync(`${resolvedPath}/package.json`) + + // package.json is a requirement for local plugins + if (!resolvedPackageJson) { + throw new Error(`Local plugin ${pluginName} requires a package.json file`) + } + + return { + validLocalPlugin: true, + localPluginPath: resolvedPath, + } +}