Skip to content

Commit 3c4069f

Browse files
authored
pref(gatsby-plugin-mdx): add lessBabel option, 40% perf win (#27941)
* pref(gatsby-plugin-mdx): add lessBabel option, 40% perf win * clean up * Add e2e tests with the lessBabel option * Add `lessBabel` option to other mdx tests where relevant
1 parent 172cb10 commit 3c4069f

File tree

25 files changed

+818
-22
lines changed

25 files changed

+818
-22
lines changed

benchmarks/gabe-fs-mdx/gatsby-config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ module.exports = {
1010
path: `${__dirname}/generated_articles/`,
1111
},
1212
},
13-
`gatsby-plugin-mdx`,
13+
{
14+
resolve: `gatsby-plugin-mdx`,
15+
options: {
16+
lessBabel: true,
17+
},
18+
},
1419
],
1520
}

e2e-tests/mdx-less-babel/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Project dependencies
2+
.cache
3+
node_modules
4+
yarn-error.log
5+
6+
# Build directory
7+
/public
8+
.DS_Store
9+
10+
# Cypress output
11+
cypress/videos/

e2e-tests/mdx-less-babel/cypress.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"baseUrl": "http://localhost:9000"
3+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* global cy */
2+
3+
describe(`Pages`, () => {
4+
it(`can be created with MDX`, () => {
5+
cy.visit(`/`).waitForRouteChange()
6+
cy.get(`h2`).invoke(`text`).should(`eq`, `Do you work`)
7+
})
8+
9+
it(`can include shortcode component`, () => {
10+
cy.visit(`/`).waitForRouteChange()
11+
cy.getTestElement(`shortcode`).contains(`I am an example of a component in MDX.`)
12+
})
13+
14+
it(`can include external import`, () => {
15+
cy.visit(`/`).waitForRouteChange()
16+
cy.getTestElement(`external`).contains(`Now an external import`)
17+
})
18+
19+
it (`generates slug for mdx in pages dir`, () => {
20+
cy.visit(`/list`).waitForRouteChange()
21+
cy.getTestElement(`mdx-slug`).contains(`another`)
22+
})
23+
24+
it (`generates complex slug with md extension`, () => {
25+
cy.visit(`/list`).waitForRouteChange()
26+
cy.getTestElement(`md-slug`).contains(`my-blog`)
27+
})
28+
29+
it (`generates a slug with an index file`, () => {
30+
cy.visit(`/list`).waitForRouteChange()
31+
cy.getTestElement(`complex-slug`).contains(`about`)
32+
})
33+
34+
it (`generates a slug with a slash`, () => {
35+
cy.visit(`/list`).waitForRouteChange()
36+
cy.getTestElement(`embed-slug`).contains(`about/embedded`)
37+
})
38+
})
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ***********************************************************
2+
// This example plugins/index.js can be used to load plugins
3+
//
4+
// You can change the location of this file or turn off loading
5+
// the plugins file with the 'pluginsFile' configuration option.
6+
//
7+
// You can read more here:
8+
// https://on.cypress.io/plugins-guide
9+
// ***********************************************************
10+
11+
// This function is called when a project is opened or re-opened (e.g. due to
12+
// the project's config changing)
13+
14+
module.exports = (on, config) => {
15+
// `on` is used to hook into various events Cypress emits
16+
// `config` is the resolved Cypress config
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// ***********************************************************
2+
// This example support/index.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
import "gatsby-cypress"
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module.exports = {
2+
siteMetadata: {
3+
title: `Gatsby MDX e2e`,
4+
},
5+
plugins: [
6+
{
7+
resolve: `gatsby-source-filesystem`,
8+
options: {
9+
name: `pages`,
10+
path: `${__dirname}/src/pages/`,
11+
},
12+
},
13+
{
14+
resolve: `gatsby-source-filesystem`,
15+
options: {
16+
name: `pages`,
17+
path: `${__dirname}/src/posts`,
18+
},
19+
},
20+
{
21+
resolve: `gatsby-plugin-mdx`,
22+
options: {
23+
lessBabel: true,
24+
extensions: [`.mdx`, `.md`],
25+
defaultLayouts: {
26+
default: require.resolve("./src/components/layout.js"),
27+
},
28+
remarkPlugins: [remarkRequireFilePathPlugin],
29+
},
30+
},
31+
],
32+
}
33+
34+
/**
35+
* This is a test to ensure that `gatsby-plugin-mdx` correctly pass the `file` argument to the underlying remark plugins.
36+
* See #26914 for more info.
37+
*/
38+
function remarkRequireFilePathPlugin() {
39+
return function transformer(tree, file) {
40+
if (!file.dirname) {
41+
throw new Error("No directory name for this markdown file!")
42+
}
43+
}
44+
}

e2e-tests/mdx-less-babel/package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "gatsby-mdx-tester",
3+
"description": "Gatsby MDX tester",
4+
"version": "1.0.0",
5+
"dependencies": {
6+
"@mdx-js/mdx": "^1.6.6",
7+
"@mdx-js/react": "^1.6.6",
8+
"cypress": "^3.1.0",
9+
"gatsby": "^2.0.118",
10+
"gatsby-plugin-mdx": "^1.2.19",
11+
"gatsby-source-filesystem": "^2.3.14",
12+
"react": "^16.8.0",
13+
"react-dom": "^16.8.0",
14+
"theme-ui": "^0.3.1"
15+
},
16+
"keywords": [
17+
"gatsby"
18+
],
19+
"license": "MIT",
20+
"scripts": {
21+
"build": "gatsby build",
22+
"develop": "gatsby develop",
23+
"format": "prettier --write '**/*.js'",
24+
"test": "cross-env CYPRESS_SUPPORT=y npm run build && npm run start-server-and-test",
25+
"start-server-and-test": "start-server-and-test serve http://localhost:9000 cy:run",
26+
"serve": "gatsby serve",
27+
"cy:open": "cypress open",
28+
"cy:run": "(is-ci && cypress run --browser chrome --record) || cypress run --browser chrome"
29+
},
30+
"devDependencies": {
31+
"cross-env": "^5.2.0",
32+
"gatsby-cypress": "^0.1.7",
33+
"is-ci": "^2.0.0",
34+
"prettier": "2.0.4",
35+
"start-server-and-test": "^1.7.1"
36+
}
37+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from "react"
2+
3+
const Example = () => (
4+
<div data-testid="shortcode">I am an example of a component in MDX.</div>
5+
)
6+
7+
export default Example
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from "react"
2+
import { MDXProvider } from "@mdx-js/react"
3+
import Example from "./example"
4+
5+
const shortcodes = { Example }
6+
export default function Layout({ children }) {
7+
return (
8+
<MDXProvider components={shortcodes}>{children}</MDXProvider>
9+
)
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is to add another source page for slugification.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Message } from "theme-ui"
2+
3+
Let's go MDX!
4+
5+
## Do you work
6+
7+
- nobody knows
8+
9+
````
10+
```javascript
11+
const codefence = true
12+
```
13+
````
14+
15+
<Example/>
16+
17+
<Message data-testid="external">Now an external import</Message>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react'
2+
import { graphql } from 'gatsby'
3+
4+
const ListPage = ({ data }) => {
5+
const anotherPage = data.another.nodes[0]
6+
const blogPage = data.blog.nodes[0]
7+
const aboutPage = data.complex.nodes[0]
8+
const embedPage = data.embed.nodes[0]
9+
10+
11+
return (
12+
<div>
13+
<div data-testid="mdx-slug">{anotherPage.slug}</div>
14+
<div data-testid="md-slug">{blogPage.slug}</div>
15+
<div data-testid="complex-slug">{aboutPage.slug}</div>
16+
<div data-testid="embed-slug">{embedPage.slug}</div>
17+
18+
</div>
19+
)
20+
}
21+
22+
export const query = graphql`
23+
{
24+
another: allMdx(filter: {slug: {eq: "another"}}) {
25+
nodes {
26+
slug
27+
}
28+
}
29+
blog: allMdx(filter: {slug: {eq: "my-blog"}}) {
30+
nodes {
31+
slug
32+
}
33+
}
34+
complex: allMdx(filter: {slug: {eq: "about/"}}) {
35+
nodes {
36+
slug
37+
}
38+
}
39+
embed: allMdx(filter: {slug: {eq: "about/embedded"}}) {
40+
nodes {
41+
slug
42+
}
43+
}
44+
}
45+
`
46+
export default ListPage
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a page that should include a slash slug
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This should be an about page we can access with a nested slug.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Let's see if we can generate a slug for this too

e2e-tests/mdx/gatsby-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module.exports = {
2020
{
2121
resolve: `gatsby-plugin-mdx`,
2222
options: {
23+
lessBabel: false,
2324
extensions: [`.mdx`, `.md`],
2425
defaultLayouts: {
2526
default: require.resolve("./src/components/layout.js"),

packages/gatsby-plugin-mdx/__tests__/gatsby-node.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe(`pluginOptionsSchema`, () => {
4848
},
4949
`gatsby-remark-other-plugin`,
5050
],
51+
lessBabel: false,
5152
remarkPlugins: [
5253
require(`../gatsby-node.js`),
5354
[require(`../gatsby-node.js`), { target: false }],

packages/gatsby-plugin-mdx/gatsby-node.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ exports.pluginOptionsSchema = function ({ Joi }) {
9090
)
9191
.default([])
9292
.description(`Use Gatsby-specific remark plugins`),
93+
lessBabel: Joi.boolean()
94+
.default(false)
95+
.description(
96+
"Enable fast parsing mode? This may break certain implied transformation dependencies. Disable if you have problems"
97+
),
9398
remarkPlugins: Joi.array()
9499
.items(
95100
Joi.function(),

0 commit comments

Comments
 (0)