Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby): Support Functions in plugins #31466

Merged
merged 3 commits into from May 18, 2021
Merged

Conversation

KyleAMathews
Copy link
Contributor

@KyleAMathews KyleAMathews commented May 18, 2021

Enable plugins/themes to ship Functions.

Their Functions must be created within their namespace: src/api/{pluginName}/.

Shadowing work with functions similar to how it does in general. You can shadow a plugin/theme Function by copying the file from its src tree into the site's src tree e.g. node_modules/gatsby-plugin-cool/src/api/gatsby-plugin-cool/function.js => src/api/gatsby-plugin-cool/function.js.

Also fix a few small bugs most noticeably I didn't rename apiRoute to functionRoute before.

Also fix a couple small bugs most noticibly I didn't rename `apiRoute` to `functionRoute` before.
@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label May 18, 2021
@KyleAMathews KyleAMathews added topic: functions and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels May 18, 2021
@@ -238,6 +238,26 @@ export function runTests(env, host) {
})
})

describe(`plugins can declare functions and they can be shadowed`, () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests for plugin functions + shadowing

}

// Create glob type w/ glob, plugin name, root path
const createGlobArray = (siteDirectoryPath, plugins): Array<IGlobPattern> => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate globs for the default src/api directory & one for each plugin (that's not a default plugin)

}
// Glob and return object with relative/absolute paths + which plugin
// they belong to.
const allFunctions = await Promise.all(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setup the route + metadata for each function file

@@ -240,7 +317,11 @@ export async function onPreBootstrap({

// Log success in dev
if (!isProductionEnv) {
reporter.success(`Re-building functions`)
if (isFirstBuild) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove unneeded message from bootstrap


// Combine functions by the route name so that functions in the default
// functions directory can override the plugin's implementations.
const knownFunctions = _.unionBy(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we implement shadowing using lodash's unionBy and combine by the functionRoute. The site's function implementations are first so they override any matching functions that come later.

@@ -363,20 +452,26 @@ export async function onCreateDevServer({

await Promise.resolve(fnToExecute(req, res))
} catch (e) {
// Override the default error with something more specific.
if (e.message.includes(`fnToExecute is not a function`)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set a better error if the function file doesn't export a function

Copy link
Contributor

@dmccraw dmccraw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me with my limited understanding of core

@c1freitas
Copy link

FYI: I don't believe we support this (nested functions) from a hosting side of things, unless I am wrong @dmccraw

@dmccraw
Copy link
Contributor

dmccraw commented May 18, 2021

We don't support dynamic functions on the Cloud side of things but this pr sets up the manifest file so we can support it.

@KyleAMathews
Copy link
Contributor Author

functions in subdirectories work e.g. /src/api/directory/function.js but yeah, dynamic functions e.g. src/api/users/[id].js don't yet.

@KyleAMathews KyleAMathews merged commit 54aaca4 into master May 18, 2021
@KyleAMathews KyleAMathews deleted the function-plugins branch May 18, 2021 21:16
@ehowey
Copy link
Contributor

ehowey commented May 19, 2021

As a theme creator this is exciting. I can package up a plug-and-play e-commerce theme now that abstracts the function for someone in a powerful way...nice work!!

@KyleAMathews
Copy link
Contributor Author

Thanks! Yeah, I'm very excited by the possibilities. Make themes and plugins 75% more powerful plus creates a lot of new use cases.

@LekoArts LekoArts added the topic: DX Developer Experience (e.g. Fast Refresh, i18n, SSR, page creation, starters) label May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: DX Developer Experience (e.g. Fast Refresh, i18n, SSR, page creation, starters)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants