Skip to content

Commit e8ff619

Browse files
Fix parent/child warnings (gatsbyjs#84)
The parent child warnings described in gatsbyjs#83 were the result of us trying to stuff fileNode into Mdx graphql types. As it turns out, this is not necessary because you can query the parent using fragments which more accurately reflect the existence or non-existence of parent types. This also means you could query the base contentful/remote CMS types when trying to add slug fields, etc. Additionally, we unified the code paths that create nodes for all sources and transformers. Since we now use the public APIs, we can have more confidence that people can do everything we can in core when creating new content types.
1 parent 0410761 commit e8ff619

File tree

3 files changed

+55
-66
lines changed

3 files changed

+55
-66
lines changed
Lines changed: 30 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,43 @@
1-
const crypto = require("crypto");
1+
const { isFunction } = require("lodash");
2+
const debug = require("debug")("gatsby-mdx:on-create-node");
3+
24
const defaultOptions = require("./utils/default-options");
3-
const mdx = require("./utils/mdx");
4-
const extractExports = require("./utils/extract-exports");
55
const createMDXNode = require("./utils/create-mdx-node");
66

77
module.exports = async (
88
{ node, getNode, loadNodeContent, actions, createNodeId },
99
pluginOptions
1010
) => {
11-
const { extensions, ...options } = defaultOptions(pluginOptions);
12-
const { createNode, createParentChildLink } = actions;
11+
const options = defaultOptions(pluginOptions);
1312

13+
/**
14+
* transformerOptions can be a function or a {transformer, filter} object
15+
*/
1416
if (Object.keys(options.transformers).includes(node.internal.type)) {
15-
createMDXNode(
16-
{
17-
node,
18-
transform: options.transformers[node.internal.type],
19-
createNode,
20-
getNode,
21-
createNodeId
22-
},
23-
actions,
24-
pluginOptions
17+
const transformerOptions = options.transformers[node.internal.type];
18+
const transformerFn = isFunction(transformerOptions)
19+
? transformerOptions
20+
: transformerOptions.transformer;
21+
const filterFn = transformerOptions ? transformerOptions.filter : undefined;
22+
debug(
23+
`${node.internal.type} has transformerFn ${isFunction(transformerFn)}`
2524
);
26-
}
27-
// We only care about markdown content.
28-
// replace with mediaType when mime-db is merged
29-
// node.internal.mediaType !== `text/mdx`
30-
if (!extensions.includes(node.ext)) {
31-
return;
32-
}
33-
34-
const nodeContent = await loadNodeContent(node);
35-
const code = await mdx(nodeContent, options);
36-
37-
// extract all the exports
38-
const { frontmatter, ...nodeExports } = extractExports(code);
39-
40-
const mdxNode = {
41-
id: createNodeId(`${node.id} >>> Mdx`),
42-
children: [],
43-
parent: node.id,
44-
internal: {
45-
content: nodeContent,
46-
type: `Mdx`
25+
debug(`${node.internal.type} has filterFn ${isFunction(filterFn)}`);
26+
if (transformerFn) {
27+
if ((isFunction(filterFn) && filterFn({ node })) || !filterFn) {
28+
debug(`processing node ${node.id}`);
29+
await createMDXNode(
30+
{
31+
createNodeId,
32+
getNode,
33+
loadNodeContent,
34+
node,
35+
transform: transformerFn
36+
},
37+
actions,
38+
{ __internalMdxTypeName: "Mdx", ...pluginOptions }
39+
);
40+
}
4741
}
48-
};
49-
50-
mdxNode.frontmatter = {
51-
title: ``, // always include a title
52-
...frontmatter,
53-
_PARENT: node.id
54-
};
55-
56-
mdxNode.excerpt = frontmatter.excerpt;
57-
mdxNode.exports = nodeExports;
58-
mdxNode.rawBody = nodeContent;
59-
60-
// Add path to the markdown file path
61-
if (node.internal.type === `File`) {
62-
mdxNode.fileAbsolutePath = node.absolutePath;
63-
mdxNode.relativePath = node.relativePath;
64-
mdxNode.fileNode = node;
6542
}
66-
67-
mdxNode.internal.contentDigest = crypto
68-
.createHash(`md5`)
69-
.update(JSON.stringify(mdxNode))
70-
.digest(`hex`);
71-
72-
createNode(mdxNode);
73-
createParentChildLink({ parent: node, child: mdxNode });
7443
};

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
const crypto = require("crypto");
2+
const debug = require("debug")("gatsby-mdx:utils/create-mdx-node");
3+
24
const mdx = require("./mdx");
35
const extractExports = require("./extract-exports");
46

57
module.exports = async (
6-
{ node, transform, getNode, createNodeId },
8+
{ node, transform, loadNodeContent, getNode, createNodeId },
79
{ createNode, createParentChildLink },
8-
options
10+
{ __internalMdxTypeName, ...options }
911
) => {
10-
const { meta, content: nodeContent } = transform({ node, getNode });
12+
const nodeType = __internalMdxTypeName || `${node.internal.type}Mdx`;
13+
debug(`creating node for nodeType \`${nodeType}\``);
14+
const { meta, content: nodeContent } = await transform({
15+
node,
16+
getNode,
17+
loadNodeContent
18+
});
1119

1220
const code = await mdx(nodeContent, options);
1321

1422
// extract all the exports
1523
const { frontmatter, ...nodeExports } = extractExports(code);
1624

1725
const mdxNode = {
18-
id: createNodeId(`${node.id} >>> ${node.internal.type}Mdx`),
26+
id: createNodeId(`${node.id} >>> ${nodeType}`),
1927
children: [],
2028
parent: node.id,
2129
internal: {
2230
content: nodeContent,
23-
type: `${node.internal.type}Mdx`
31+
type: nodeType
2432
}
2533
};
2634

packages/gatsby-plugin-mdx/utils/default-options.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ module.exports = pluginOptions => {
1919
pluginOptions
2020
);
2121

22+
// ensure File transformer is always ours
23+
options.transformers.File = {
24+
transformer: async ({ loadNodeContent, node }) => {
25+
const mdxContent = await loadNodeContent(node);
26+
return { meta: undefined, content: mdxContent };
27+
},
28+
// We only care about markdown content.
29+
// replace with mediaType when mime-db is merged
30+
// node.internal.mediaType !== `text/mdx`
31+
filter: ({ node }) => options.extensions.includes(node.ext)
32+
};
33+
2234
// support single layout set in the `defaultLayouts` option
2335
if (options.defaultLayouts && isString(options.defaultLayouts)) {
2436
options.defaultLayouts = {

0 commit comments

Comments
 (0)