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): add support for image-cdn #34825

Merged
merged 46 commits into from
Mar 1, 2022
Merged

feat(gatsby): add support for image-cdn #34825

merged 46 commits into from
Mar 1, 2022

Conversation

wardpeet
Copy link
Contributor

Description

Improve remote file handling by adding a new interface "RemoteFile" to GraphQL. This new interface allows source plugins to lazily download images and has native compatibility with gatsby-plugin-image.

To enable support for RemoteInterface, you'll need a couple of fields to be present on your node:

  url: `https://remote-url-to-file`,
  placeholderUrl: `https://remote-url-to-file?w=%width%&h=%height%&q=%quality%`,
  mimeType: `image/jpg`,
  filename: `name.jpg`,
  filesize: 10000,
  width: 800,
  height: 600,

As noted about only url, filename and mimeType are mandatory for regular files. Images also need width & height specified. The placeholderUrl field is a bit special as we added the option to give use a url with macros, so we can generate a smaller image to generate a placeholder to speed up query running.

With these nodes the RemoteFile Interface adds custom resolvers to your GraphQL type, without you needing to know how they work.
It adds publicUrl to generate a public facing url, resize to resize an image to a specific size and gatsbyImageData to give you a compatible data blob to use with gatsby-plugin-image.


The implementation is a bit hard to follow as everything is added inside gatsby-plugin-utils to support older gatsby v4 versions as well. You can upgrade gatsby-source-contentful without upgrading gatsby itself.

A source plugin can implement Gatsby's image CDN by wrapping the GraphQL type with the addRemoteFilePolyfillInterface in `createSchemaCustimization like this

import { addRemoteFilePolyfillInterface } from "gatsby-plugin-utils/polyfill-remote-file"

addRemoteFilePolyfillInterface(
  schema.buildObjectType({
    name: `PrefixAsset`,
    fields: {
      // your fields
    },
    interfaces: [`Node`, 'RemoteFile'],
  }),
  {
    schema, // schema you get as an argument from createSchemaCustomization
    store, // the redux store of gatsby also part of createSchemaCustomization
  }
)

Last but not least you'll need to add some extra routes to the dev server as well.

import { addRemoteFilePolyfillInterface } from "gatsby-plugin-utils/polyfill-remote-file"

addRemoteFilePolyfillInterface(
  schema.buildObjectType({
    name: `PrefixAsset`,
    fields: {
      // your fields
    },
    interfaces: [`Node`, 'RemoteFile'],
  }),
  {
    schema, // schema you get as an argument from createSchemaCustomization
    store, // the redux store of gatsby also part of createSchemaCustomization
  }
)

Documentation

Related Issues

@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Feb 15, 2022
@wardpeet wardpeet added topic: media Related to gatsby-plugin-image, or general image/media processing topics and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Feb 15, 2022
@wardpeet wardpeet changed the base branch from master to feat/remote-file-update February 15, 2022 21:46
@wardpeet wardpeet marked this pull request as draft February 15, 2022 21:46
@wardpeet wardpeet force-pushed the feat/remote-file-update branch 2 times, most recently from 56b467b to 11a8c68 Compare February 16, 2022 15:19
Base automatically changed from feat/remote-file-update to master February 17, 2022 10:24
@wardpeet wardpeet force-pushed the image-cdn branch 7 times, most recently from b0dfb18 to 6ef7bf2 Compare February 23, 2022 15:00
@wardpeet wardpeet marked this pull request as ready for review February 23, 2022 19:13
@TylerBarnes
Copy link
Contributor

TylerBarnes commented Feb 23, 2022

@wardpeet nice work! 🙌 The polyfill means it will work for users upgrading source plugins while staying on an old gatsby version. What about the other way around? Users upgrading gatsby but not source plugins. Will that break their existing GraphQL queries? I think we need to release a breaking change release for source plugins, but for gatsby we should probably put the new resolver changes under a flag or some other opt-in mechanism (perhaps a new gql field to make it opt-in?)

@wardpeet wardpeet force-pushed the image-cdn branch 2 times, most recently from 581402b to c608729 Compare February 25, 2022 17:20
Copy link
Contributor

@LekoArts LekoArts left a comment

Choose a reason for hiding this comment

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

Only managed to look at the first couple of files, need to look at it again tomorrow

e2e-tests/development-runtime/gatsby-node.js Outdated Show resolved Hide resolved
e2e-tests/development-runtime/gatsby-node.js Outdated Show resolved Hide resolved
docs/docs/how-to/testing/unit-testing.md Outdated Show resolved Hide resolved
packages/gatsby-plugin-utils/README.md Outdated Show resolved Hide resolved
packages/gatsby-plugin-utils/README.md Outdated Show resolved Hide resolved
packages/gatsby-plugin-utils/package.json Outdated Show resolved Hide resolved
@wardpeet wardpeet changed the base branch from master to fix/gatsby-core-utils-remote-file March 1, 2022 00:11
export default function (source: string): string {
let lmdbBinaryLocation
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function (this: any, source: string): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These changes are necessary as lmdb can also be required from gatsby-core-utils which can lead to multiple versions. Wich leads to different paths and we want to patch all lmdb versions that need patching.

@@ -71,7 +71,7 @@ export async function createGraphqlEngineBundle(
module: {
rules: [
{
test: require.resolve(`lmdb`),
test: /node_modules[/\\]lmdb[/\\].*\.[cm]?js/,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

make the test reach other lmdb modules

@@ -22,7 +22,7 @@ describe(`NodeModel`, () => {
`SiteBuildMetadata`,
`Author`,
`Contributor`,
`RemoteFile`,
`ExternalFile`,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes necessary to pass tests, without it name conflicts happen

@wardpeet wardpeet merged commit 29b236b into master Mar 1, 2022
@wardpeet wardpeet deleted the image-cdn branch March 1, 2022 21:57
@nrandell
Copy link
Contributor

nrandell commented Mar 4, 2022

Quick question on this. If you do a 'gatsby clean' on your development machine, does this delete the cache folder containing any processed images?

I love the feature though!

@TylerBarnes
Copy link
Contributor

@nrandell it does 👍 On Gatsby Cloud images will be cached even when the site cache is invalidated but locally the images will be deleted. The nice thing is they're only fetched and processed once you visit localhost in gatsby develop, so it's not such a big deal if they're deleted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: media Related to gatsby-plugin-image, or general image/media processing topics
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants