Skip to content

Commit

Permalink
Merge branch 'master' into renovate/gatsby-plugin-sass-dev-minor
Browse files Browse the repository at this point in the history
  • Loading branch information
wardpeet authored Oct 30, 2021
2 parents 251222a + 79494f5 commit 47b64d4
Show file tree
Hide file tree
Showing 78 changed files with 1,056 additions and 203 deletions.
4 changes: 4 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ executors:
default: "14.17.0"
docker:
- image: cimg/node:<< parameters.image >>
environment:
GATSBY_CPU_COUNT: 2

aliases:
e2e-executor: &e2e-executor
docker:
- image: cypress/browsers:node14.15.0-chrome86-ff82
environment:
GATSBY_CPU_COUNT: 2

restore_cache: &restore_cache
restore_cache:
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/how-to/sourcing-data/sourcing-from-contentful.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ npm install gatsby-source-contentful

## How to use

To get setup quickly with a new site and have Gatsby Cloud do the heavy lifting, [deploy a new Gatsby Contentful site with just a few clicks on gatsbyjs.com](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/contentful/starter-gatsby-blog).

For more detailed instructions on manually configuring your Gatsby Contentful site for production builds and Preview builds visit [the Gatsby Cloud knowledgebase](https://support.gatsbyjs.com/hc/en-us/articles/360056047134-Add-the-Gatsby-Cloud-App-to-Contentful).

### With the Delivery API

```javascript:title=gatsby-config.js
Expand Down
20 changes: 20 additions & 0 deletions docs/docs/reference/config-files/gatsby-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,23 @@ See more about [Proxying API Requests in Develop](/docs/api-proxy/).
## Advanced proxying with `developMiddleware`

See more about [adding develop middleware](/docs/api-proxy/#advanced-proxying).

## jsxRuntime

Setting to "automatic" allows the use of JSX without having to import React. More information can be found on the [Introducing the new JSX Transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) blog post.

```javascript:title=gatsby-config.js
module.exports = {
jsxRuntime: "automatic",
}
```

## jsxImportSource

With the new jsxRuntime you can set which package React should use as underlying jsx transformer. For example you can set it to "@emotion/react" so by default @emotion/react is used instead of the react package.

```javascript:title=gatsby-config.js
module.exports = {
jsxImportSource: "@emotion/react",
}
```
2 changes: 1 addition & 1 deletion docs/docs/tutorial/part-4/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ query MyQuery {
summary="Seeing more nodes than expected?"
>

If you're still using a `StaticImage` from an external URL (like `https://some-site/image.jpg`) on your home page, you'll see an extra node for that image show up in your GraphQL response. That's because `StaticImage` uses [`createRemoteFileNode`](https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#createremotefilenode) under the hood which creates a `File` node for each image it downloads. If you're only using images from your filesystem, you won't see the extra ndoe.
If you're still using a `StaticImage` from an external URL (like `https://some-site/image.jpg`) on your home page, you'll see an extra node for that image show up in your GraphQL response. That's because `StaticImage` uses [`createRemoteFileNode`](https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#createremotefilenode) under the hood which creates a `File` node for each image it downloads. If you're only using images from your filesystem, you won't see the extra node.
To get rid of it, you can update your GraphQL query to filter the File nodes using the `sourceInstanceName` field (which corresponds to the value of the `name` option you set for `gatsby-source-filesystem` in your `gatsby-config.js` file).
Expand Down
13 changes: 13 additions & 0 deletions e2e-tests/contentful/cypress/integration/download-local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
describe(`downloadLocal`, () => {
beforeEach(() => {
cy.visit("/download-local").waitForRouteChange()
})

it(`renders dynamic image from static directory`, () => {
cy.get("#gatsby-plugin-image-download-local").should("be.visible")
cy.get("#gatsby-plugin-image-download-local").should("have.attr", "srcset")
cy.get("#gatsby-plugin-image-download-local")
.should("have.attr", "src")
.should("match", /^\/static/)
})
})
2 changes: 2 additions & 0 deletions e2e-tests/contentful/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ module.exports = {
spaceId: `k8iqpp6u0ior`,
accessToken: `hO_7N0bLaCJFbu5nL3QVekwNeB_TNtg6tOCB_9qzKUw`,
enableTags: true,
downloadLocal: true,
},
},
`gatsby-transformer-remark`,
`gatsby-transformer-sharp`,
`gatsby-transformer-sqip`,
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
Expand Down
34 changes: 34 additions & 0 deletions e2e-tests/contentful/src/pages/download-local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import * as React from "react"

import Layout from "../components/layout"

const DownloadLocalPage = ({ data }) => {
return (
<Layout>
<h1>Test downloadLocal feature</h1>
<GatsbyImage
id="gatsby-plugin-image-download-local"
image={data.contentfulAsset.localFile.childImageSharp.gatsbyImageData}
/>
</Layout>
)
}

export default DownloadLocalPage

export const pageQuery = graphql`
query DownloadLocalQuery {
contentfulAsset(contentful_id: { eq: "3BSI9CgDdAn1JchXmY5IJi" }) {
contentful_id
title
localFile {
absolutePath
childImageSharp {
gatsbyImageData
}
}
}
}
`
3 changes: 3 additions & 0 deletions e2e-tests/contentful/src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const IndexPage = () => (
<li>
<Link to="/gatsby-plugin-image">/gatsby-plugin-image</Link>
</li>
<li>
<Link to="/download-local">/download-local</Link>
</li>
</ul>
<h2>Content Rendering</h2>
<ul>
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin-remove-graphql-queries/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-plugin-remove-graphql-queries",
"version": "4.1.0-next.0",
"version": "4.1.0-next.1",
"author": "Jason Quense <monastic.panic@gmail.com>",
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,50 @@ const siteMetaQuery = \\"504726680\\";
const query = \\"3211238532\\";"
`;

exports[`babel-plugin-remove-graphql-queries Replaces graphql query inside config with global call 1`] = `
"import * as React from 'react';
const Test = () => /*#__PURE__*/React.createElement(\\"div\\", null);
export default Test;
export async function config() {
const data = await global.__gatsbyGraphql(\`{ __typename }\`);
return () => {
return {
defer: true
};
};
}"
`;
exports[`babel-plugin-remove-graphql-queries Replaces graphql query inside config with global call 2`] = `
"\\"use strict\\";
exports.__esModule = true;
exports.config = config;
exports.default = void 0;
var React = _interopRequireWildcard(require(\\"react\\"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== \\"object\\" && typeof obj !== \\"function\\") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const Test = () => /*#__PURE__*/React.createElement(\\"div\\", null);
var _default = Test;
exports.default = _default;
async function config() {
const data = await global.__gatsbyGraphql(\`{ __typename }\`);
return () => {
return {
defer: true
};
};
}"
`;
exports[`babel-plugin-remove-graphql-queries Transformation does not break custom hooks 1`] = `
"import staticQueryData from \\"public/static/d/426988268.json\\";
import React from \\"react\\";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ function matchesSnapshot(query) {
expect(codeWithFileName).toMatchSnapshot()
}

function transform(query, filename) {
const { code } = babel.transform(query, {
presets: [`@babel/preset-react`],
plugins: [plugin],
filename,
})
return code
}

describe(`babel-plugin-remove-graphql-queries`, () => {
it.todo(
`Works correctly with the kitchen sink`
Expand Down Expand Up @@ -465,4 +474,54 @@ describe(`babel-plugin-remove-graphql-queries`, () => {
\`
`)
})

it(`Replaces graphql query inside config with global call`, () => {
matchesSnapshot(`
import * as React from 'react'
import { graphql } from "gatsby"
const Test = () => (
<div></div>
)
export default Test
export async function config() {
const data = graphql\`{ __typename }\`
return () => {
return {
defer: true
}
}
}
`)
})

it(`validates that config export is async`, () => {
const run = () =>
transform(`
import * as React from 'react'
import { graphql } from "gatsby"
const Test = () => (
<div></div>
)
export default Test
export function config() {
const data = graphql\`{ __typename }\`
return () => {
return {
defer: true
}
}
}
`)
expect(run).toThrowErrorMatchingInlineSnapshot(
`"unknown: BabelPluginRemoveGraphQLQueries: the \\"config\\" export must be async when using it with graphql"`
)
})
})
75 changes: 73 additions & 2 deletions packages/babel-plugin-remove-graphql-queries/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {
VariableDeclarator,
SourceLocation,
Expression,
ExportNamedDeclaration,
isFunctionDeclaration,
isVariableDeclaration,
isFunction,
isIdentifier,
} from "@babel/types"

interface ISourcePosition {
Expand Down Expand Up @@ -98,6 +103,20 @@ class GraphQLSyntaxError extends Error {
}
}

class ExportIsNotAsyncError extends Error {
exportStart: ISourcePosition | undefined
exportName: string

constructor(exportName: string, exportStart: ISourcePosition | undefined) {
super(
`BabelPluginRemoveGraphQLQueries: the "${exportName}" export must be async when using it with graphql`
)
this.exportName = exportName
this.exportStart = JSON.parse(JSON.stringify(exportStart))
Error.captureStackTrace(this, ExportIsNotAsyncError)
}
}

const isGlobalIdentifier = (
tag: NodePath,
tagName: string = `graphql`
Expand Down Expand Up @@ -536,22 +555,74 @@ export default function ({ types: t }): PluginObj {
tagsToRemoveImportsFrom.add(tag)
}

// Replace the query with the hash of the query.
// When graphql tag is found inside config function, we replace it with global call, e.g.:
// export async function config() {
// const { data } = graphql`{ __typename }`
// }
// is replaced with:
// export async function config() {
// const { data } = await global.__gatsbyGraphql(`{ __typename }`)
// }
// Note: isWithinConfigExport will throw if "config" export is not async
if (isWithinConfigExport(path2)) {
const globalCall = t.awaitExpression(
t.callExpression(
t.memberExpression(
t.identifier(`global`),
t.identifier(`__gatsbyGraphql`)
),
[path2.node.quasi]
)
)
path2.replaceWith(globalCall)
return null
}

path2.replaceWith(t.StringLiteral(queryHash))
return null
},
})

tagsToRemoveImportsFrom.forEach(removeImport)
},
},
}
}

function isWithinConfigExport(
path: NodePath<TaggedTemplateExpression>
): boolean {
const parentExport = path.findParent(parent =>
parent.isExportNamedDeclaration()
) as NodePath<ExportNamedDeclaration> | null

const declaration = parentExport?.node?.declaration

if (isFunctionDeclaration(declaration) && declaration.id?.name === `config`) {
if (!declaration.async) {
throw new ExportIsNotAsyncError(`config`, declaration.loc?.start)
}
return true
}
if (
isVariableDeclaration(declaration) &&
isIdentifier(declaration.declarations[0]?.id) &&
declaration.declarations[0]?.id?.name === `config`
) {
const init = declaration.declarations[0]?.init
if (!isFunction(init) || !init.async) {
throw new ExportIsNotAsyncError(`config`, init?.loc?.start)
}
return true
}
return false
}

export {
getGraphQLTag,
StringInterpolationNotAllowedError,
EmptyGraphQLTagError,
GraphQLSyntaxError,
ExportIsNotAsyncError,
isWithinConfigExport,
murmurhash,
}
4 changes: 2 additions & 2 deletions packages/babel-preset-gatsby/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-preset-gatsby",
"version": "2.1.0-next.0",
"version": "2.1.0-next.1",
"author": "Philipp Spiess <hello@philippspiess.com>",
"repository": {
"type": "git",
Expand All @@ -23,7 +23,7 @@
"babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"gatsby-core-utils": "^3.1.0-next.0",
"gatsby-legacy-polyfills": "^2.1.0-next.0"
"gatsby-legacy-polyfills": "^2.1.0-next.1"
},
"peerDependencies": {
"@babel/core": "^7.11.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/create-gatsby/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-gatsby",
"version": "2.1.0-next.0",
"version": "2.1.0-next.1",
"main": "lib/index.js",
"bin": "cli.js",
"license": "MIT",
Expand Down
Loading

0 comments on commit 47b64d4

Please sign in to comment.