Skip to content

Commit

Permalink
BREAKING CHANGE(gatsby-plugin-mdx): MDX v2 (#35650)
Browse files Browse the repository at this point in the history
Co-authored-by: Josh Johnson <jcjohnson77@gmail.com>
Co-authored-by: LekoArts <lekoarts@gmail.com>
Co-authored-by: Ward Peeters <ward@coding-tech.com>
Co-authored-by: Lennart <lekoarts@gmail.com>
Co-authored-by: pieh <misiek.piechowiak@gmail.com>
Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
  • Loading branch information
5 people committed Aug 10, 2022
1 parent 3c0dd6d commit c92db36
Show file tree
Hide file tree
Showing 200 changed files with 5,763 additions and 8,418 deletions.
9 changes: 3 additions & 6 deletions .circleci/config.yml
Expand Up @@ -434,15 +434,12 @@ jobs:
test_path: e2e-tests/themes
test_command: cd production-runtime; yarn test

mdx_e2e_tests:
e2e_tests_mdx:
<<: *e2e-executor
steps:
- e2e-test:
test_path: e2e-tests/mdx
test_command: CYPRESS_PROJECT_ID=spbj28 CYPRESS_RECORD_KEY=af30ea46-121f-4fb7-97dd-f17ec224402e yarn test
- e2e-test:
test_path: e2e-tests/mdx-less-babel
test_command: CYPRESS_PROJECT_ID=xo139a CYPRESS_RECORD_KEY=74d485b5-3ba6-40e1-a7d4-e63c0a8d2a4d yarn test

e2e_tests_visual-regression:
<<: *e2e-executor
Expand Down Expand Up @@ -646,6 +643,8 @@ workflows:
<<: *e2e-test-workflow
- e2e_tests_contentful:
<<: *e2e-test-workflow
- e2e_tests_mdx:
<<: *e2e-test-workflow
- e2e_tests_trailing-slash:
<<: *e2e-test-workflow
- e2e_tests_development_runtime:
Expand All @@ -660,8 +659,6 @@ workflows:
<<: *e2e-test-workflow
- themes_e2e_tests_development_runtime:
<<: *e2e-test-workflow
- mdx_e2e_tests:
<<: *e2e-test-workflow
- starters_validate:
<<: *ignore_master
- starters_publish:
Expand Down
8 changes: 4 additions & 4 deletions benchmarks/gabe-fs-mdx/gatsby-config.js
@@ -1,3 +1,5 @@
const path = require("path")

module.exports = {
siteMetadata: {
siteTitle: `Gatsby MDX Benchmark`,
Expand All @@ -12,9 +14,7 @@ module.exports = {
},
{
resolve: `gatsby-plugin-mdx`,
options: {
lessBabel: true,
},
},
],
!process.env.CI && `gatsby-plugin-webpack-bundle-analyser-v2`,
].filter(Boolean),
}
15 changes: 11 additions & 4 deletions benchmarks/gabe-fs-mdx/gatsby-node.js
@@ -1,7 +1,5 @@
const path = require("path")

const blogPost = path.resolve(`./src/templates/blog-post.js`)

exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions

Expand All @@ -14,6 +12,13 @@ exports.createPages = async ({ graphql, actions }) => {
frontmatter {
title # used in prev/next
}
parent {
... on File {
id
name
absolutePath
}
}
}
}
}
Expand All @@ -25,13 +30,15 @@ exports.createPages = async ({ graphql, actions }) => {

const posts = result.data.allMdx.nodes

posts.forEach(({ id, slug }, index) => {
posts.forEach(({ id, slug, parent }, index) => {
const previous = index === posts.length - 1 ? null : posts[index + 1]
const next = index === 0 ? null : posts[index - 1]

createPage({
path: slug,
component: blogPost,
component: `${path.resolve(
`./src/templates/blog-post.js`
)}?__contentFilePath=${parent.absolutePath}`,
context: {
id,
slug,
Expand Down
1 change: 0 additions & 1 deletion benchmarks/gabe-fs-mdx/gen.js
Expand Up @@ -19,7 +19,6 @@ date: ${faker.date.recent(1000).toISOString().slice(0, 10)}
import { Link } from "gatsby"
export const author = "Fred Flintstone"
export default props => <main {...props} />
<Link to="/">Go Home</Link>
Expand Down
14 changes: 7 additions & 7 deletions benchmarks/gabe-fs-mdx/package.json
Expand Up @@ -13,6 +13,7 @@
"format": "prettier --write \"**/*.{js,jsx,json,md}\""
},
"devDependencies": {
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.27",
"prettier": "2.0.4"
},
"repository": {
Expand All @@ -28,13 +29,12 @@
"mdx"
],
"dependencies": {
"@mdx-js/mdx": "^1",
"@mdx-js/react": "^1",
"@mdx-js/react": "^2",
"faker": "^4.1.0",
"gatsby": "^2",
"gatsby-plugin-mdx": "^1",
"gatsby-source-filesystem": "^2",
"react": "^16.12.0",
"react-dom": "^16.12.0"
"gatsby": "^4",
"gatsby-plugin-mdx": "^3",
"gatsby-source-filesystem": "^4",
"react": "^17",
"react-dom": "^17"
}
}
16 changes: 5 additions & 11 deletions benchmarks/gabe-fs-mdx/src/templates/blog-post.js
@@ -1,29 +1,23 @@
import React from "react"
import { graphql, Link } from "gatsby"
import Layout from "../components/layout_1"
import { MDXRenderer } from "gatsby-plugin-mdx"

const Article = ({ data }) => {
const { body } = data.mdx
const { mdx } = data

const Article = ({ children, data: { mdx } }) => {
return (
<Layout>
<Link to="/">Go back to index page</Link>
<div>
<h1>{mdx.frontmatter.title}</h1>
<div>
<MDXRenderer>{body}</MDXRenderer>
</div>
{children}
</div>
</Layout>
)
}

export const query = graphql`
query MdxQuery($id: String!) {
export const pageQuery = graphql`
query($id: String!) {
mdx(id: { eq: $id }) {
body
id
frontmatter {
title
}
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/how-to/routing/mdx.md
Expand Up @@ -2,7 +2,7 @@
title: Add components to content using MDX
examples:
- label: Using MDX
href: "https://github.com/gatsbyjs/gatsby/tree/master/examples/using-MDX"
href: "https://github.com/gatsbyjs/gatsby/tree/master/examples/using-mdx"
---

## Introduction
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/mdx/importing-and-using-components.md
Expand Up @@ -119,4 +119,4 @@ Here is a demo:

### Additional resources

- Follow this detailed [example on using MDX](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-MDX) to import and render components.
- Follow this detailed [example on using MDX](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-mdx) to import and render components.
104 changes: 86 additions & 18 deletions docs/docs/reference/graphql-data-layer/schema-customization.md
Expand Up @@ -131,7 +131,7 @@ suddenly fail.
Both problems can be solved by providing explicit type definitions for Gatsby's
GraphQL schema.

### Creating type definitions
## Creating type definitions

Look at the latter case first. Assume a new author joins the team, but in the
new author entry there is a typo on the `joinedAt` field: "201-04-02" which is
Expand All @@ -150,7 +150,7 @@ not a valid Date.
This will confuse Gatsby's type inference since the `joinedAt`
field will now have both Date and String values.

#### Fixing field types
### Fixing field types

To ensure that the field will always be of Date type, you can provide explicit
type definitions to Gatsby with the [`createTypes`](/docs/reference/config-files/actions/#createTypes) action.
Expand All @@ -176,7 +176,7 @@ provided, they will still be handled by Gatsby's type inference.
> (available in Gatsby v2.12 and above),
> and [`sourceNodes`](/docs/reference/config-files/gatsby-node/#sourceNodes) APIs.
#### Opting out of type inference
### Opting out of type inference

There are however advantages to providing full definitions for a node type, and
bypassing the type inference mechanism altogether. With smaller scale projects
Expand Down Expand Up @@ -209,7 +209,7 @@ Note that you don't need to explicitly provide the Node interface fields (`id`,
> [specifying nullability](https://graphql.org/learn/schema/#lists-and-non-null)
> in GraphQL, i.e. if a field value is allowed to be `null` or not.
#### Defining media types
### Defining media types

You can specify the media types handled by a node type using the `@mimeTypes` extension:

Expand All @@ -222,7 +222,7 @@ type Markdown implements Node

The types passed in are used to determine child relations of the node.

#### Defining child relations
### Defining child relations

The `@childOf` extension can be used to explicitly define what node types or media types a node is a child of and immediately add `child[MyType]` and `children[MyType]` fields on the parent.

Expand Down Expand Up @@ -255,7 +255,7 @@ type Mdx implements Node
}
```

#### Nested types
### Nested types

So far, the example project has only been dealing with scalar values (`String` and `Date`;
GraphQL also knows `ID`, `Int`, `Float`, `Boolean` and `JSON`). Fields can
Expand Down Expand Up @@ -305,7 +305,7 @@ always starting from the Node types created by source and transformer plugins.
> it is not a top-level type created by source or transformer plugins: it has no
> `id` field, and is there to describe the data shape on a nested field.
#### Gatsby Type Builders
### Gatsby Type Builders

In many cases, GraphQL SDL provides a succinct way to provide type definitions
for your schema. If however you need more flexibility, `createTypes` also
Expand Down Expand Up @@ -362,7 +362,7 @@ schema.buildObjectType({
> Note that the `createTypes` action also accepts `graphql-js` types directly,
> but usually either SDL or Type Builders are the better alternatives.
#### Foreign-key fields
### Foreign-key fields

In the example project, the `frontmatter.author` field on
`MarkdownRemark` nodes to expand the provided field value to a full `AuthorJson` node.
Expand Down Expand Up @@ -466,15 +466,15 @@ For the above example you can read `@link` this way: Use the value from the fiel

Keep in mind that in the example above, the link of `posts` in `AuthorJson` works because `frontmatter` and `author` are both objects. If, for example, the `Frontmatter` type had a list of `authors` instead (`frontmatter.authors.email`), it wouldn't work since the `by` argument doesn't support arrays. In that case, you'd have to provide a custom resolver with [Gatsby Type Builders](/docs/reference/graphql-data-layer/schema-customization/#gatsby-type-builders) or [createResolvers API](/docs/reference/graphql-data-layer/schema-customization/#createresolvers-api).

#### Extensions and directives
### Extensions and directives

Out of the box, Gatsby provides [four extensions](/docs/reference/config-files/actions/#createTypes)
that allow adding custom functionality to fields without having to manually
write field resolvers: the `link` extension has already been discussed above,
`dateformat` allows adding date formatting options, `fileByRelativePath` is
similar to `link` but will resolve relative paths when linking to `File` nodes,
and `proxy` is helpful when dealing with data that contains field names with
characters that are invalid in GraphQL.
Out of the box, Gatsby provides [four extensions](/docs/reference/config-files/actions/#createTypes) that allow adding custom functionality to fields without having to manually write field resolvers:

1. The `link` extension has already been discussed above
1. `dateformat` allows adding date formatting options
1. `fileByRelativePath` is similar to `link` but will resolve relative paths when linking to `File` nodes
1. `proxy` is helpful when dealing with data that contains field names with
characters that are invalid in GraphQL or to alias fields

To add an extension to a field you can either use a directive in SDL, or the
`extensions` property when using Gatsby Type Builders:
Expand Down Expand Up @@ -518,7 +518,75 @@ query {
`publishedAt` is also provided a default `formatString` which will be used
when no explicit formatting options are provided in the query.

#### Setting default field values
If the JSON would contain keys you'd want to `proxy` to other names, you could do it like this:

```json
{
"name": "Doe",
"firstName": "Zoe",
"email": "zoe@example.com",
"start_date": "2022/08/01"
}
```

```graphql
type AuthorJson implements Node {
startDate: Date! @dateformat @proxy(from: "start_date")
}
```

You can also combine multiple extensions (built-in and custom ones).

#### Aliasing fields

You can use the `@proxy` directive to alias (nested) fields to another field on the same node. This is helpful if e.g. you want to keep the shape you have to query flat or if you need it to keep things backwards compatible.

If you'd add a new field using [`createNodeField`](/docs/reference/config-files/actions/#createNodeField) to the `MarkdownRemark` nodes (change this check if you use another source/type) like this:

```js:title=gatsby-node.js
exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
createNodeField({
node,
name: `someInformation`,
value: `Hello World`
})
}
}
```

The `Hello World` would be queryable at:

```graphql
nodes {
fields {
someInformation
}
}
```

To be able to query `someInformation` like this instead you have to alias the `fields.someInformation` field.

```graphql
nodes {
someInformation
}
```

```javascript:title=source-plugin/gatsby-node.js
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions

createTypes(`
type MarkdownRemark implements Node {
someInformation: String @proxy(from: "fields.someInformation")
}
`)
}
```

### Setting default field values

For setting default field values, Gatsby currently does not (yet) provide an
out-of-the-box extension, so resolving a field to a default value (instead of
Expand Down Expand Up @@ -552,7 +620,7 @@ exports.createSchemaCustomization = ({ actions, schema }) => {
}
```

#### Creating custom extensions
### Creating custom extensions

With the [`createFieldExtension`](/docs/reference/config-files/actions/#createFieldExtension) action
it is possible to define custom extensions as a way to add reusable functionality
Expand Down
12 changes: 0 additions & 12 deletions e2e-tests/mdx-less-babel/.gitignore

This file was deleted.

3 changes: 0 additions & 3 deletions e2e-tests/mdx-less-babel/cypress.json

This file was deleted.

This file was deleted.

0 comments on commit c92db36

Please sign in to comment.