Skip to content

Commit

Permalink
Fix parent/child warnings (gatsbyjs#84)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ChristopherBiscardi committed Jun 27, 2019
1 parent 0410761 commit e8ff619
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 66 deletions.
91 changes: 30 additions & 61 deletions packages/gatsby-plugin-mdx/on-create-node.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,43 @@
const crypto = require("crypto");
const { isFunction } = require("lodash");
const debug = require("debug")("gatsby-mdx:on-create-node");

const defaultOptions = require("./utils/default-options");
const mdx = require("./utils/mdx");
const extractExports = require("./utils/extract-exports");
const createMDXNode = require("./utils/create-mdx-node");

module.exports = async (
{ node, getNode, loadNodeContent, actions, createNodeId },
pluginOptions
) => {
const { extensions, ...options } = defaultOptions(pluginOptions);
const { createNode, createParentChildLink } = actions;
const options = defaultOptions(pluginOptions);

/**
* transformerOptions can be a function or a {transformer, filter} object
*/
if (Object.keys(options.transformers).includes(node.internal.type)) {
createMDXNode(
{
node,
transform: options.transformers[node.internal.type],
createNode,
getNode,
createNodeId
},
actions,
pluginOptions
const transformerOptions = options.transformers[node.internal.type];
const transformerFn = isFunction(transformerOptions)
? transformerOptions
: transformerOptions.transformer;
const filterFn = transformerOptions ? transformerOptions.filter : undefined;
debug(
`${node.internal.type} has transformerFn ${isFunction(transformerFn)}`
);
}
// We only care about markdown content.
// replace with mediaType when mime-db is merged
// node.internal.mediaType !== `text/mdx`
if (!extensions.includes(node.ext)) {
return;
}

const nodeContent = await loadNodeContent(node);
const code = await mdx(nodeContent, options);

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

const mdxNode = {
id: createNodeId(`${node.id} >>> Mdx`),
children: [],
parent: node.id,
internal: {
content: nodeContent,
type: `Mdx`
debug(`${node.internal.type} has filterFn ${isFunction(filterFn)}`);
if (transformerFn) {
if ((isFunction(filterFn) && filterFn({ node })) || !filterFn) {
debug(`processing node ${node.id}`);
await createMDXNode(
{
createNodeId,
getNode,
loadNodeContent,
node,
transform: transformerFn
},
actions,
{ __internalMdxTypeName: "Mdx", ...pluginOptions }
);
}
}
};

mdxNode.frontmatter = {
title: ``, // always include a title
...frontmatter,
_PARENT: node.id
};

mdxNode.excerpt = frontmatter.excerpt;
mdxNode.exports = nodeExports;
mdxNode.rawBody = nodeContent;

// Add path to the markdown file path
if (node.internal.type === `File`) {
mdxNode.fileAbsolutePath = node.absolutePath;
mdxNode.relativePath = node.relativePath;
mdxNode.fileNode = node;
}

mdxNode.internal.contentDigest = crypto
.createHash(`md5`)
.update(JSON.stringify(mdxNode))
.digest(`hex`);

createNode(mdxNode);
createParentChildLink({ parent: node, child: mdxNode });
};
18 changes: 13 additions & 5 deletions packages/gatsby-plugin-mdx/utils/create-mdx-node.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
const crypto = require("crypto");
const debug = require("debug")("gatsby-mdx:utils/create-mdx-node");

const mdx = require("./mdx");
const extractExports = require("./extract-exports");

module.exports = async (
{ node, transform, getNode, createNodeId },
{ node, transform, loadNodeContent, getNode, createNodeId },
{ createNode, createParentChildLink },
options
{ __internalMdxTypeName, ...options }
) => {
const { meta, content: nodeContent } = transform({ node, getNode });
const nodeType = __internalMdxTypeName || `${node.internal.type}Mdx`;
debug(`creating node for nodeType \`${nodeType}\``);
const { meta, content: nodeContent } = await transform({
node,
getNode,
loadNodeContent
});

const code = await mdx(nodeContent, options);

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

const mdxNode = {
id: createNodeId(`${node.id} >>> ${node.internal.type}Mdx`),
id: createNodeId(`${node.id} >>> ${nodeType}`),
children: [],
parent: node.id,
internal: {
content: nodeContent,
type: `${node.internal.type}Mdx`
type: nodeType
}
};

Expand Down
12 changes: 12 additions & 0 deletions packages/gatsby-plugin-mdx/utils/default-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ module.exports = pluginOptions => {
pluginOptions
);

// ensure File transformer is always ours
options.transformers.File = {
transformer: async ({ loadNodeContent, node }) => {
const mdxContent = await loadNodeContent(node);
return { meta: undefined, content: mdxContent };
},
// We only care about markdown content.
// replace with mediaType when mime-db is merged
// node.internal.mediaType !== `text/mdx`
filter: ({ node }) => options.extensions.includes(node.ext)
};

// support single layout set in the `defaultLayouts` option
if (options.defaultLayouts && isString(options.defaultLayouts)) {
options.defaultLayouts = {
Expand Down

0 comments on commit e8ff619

Please sign in to comment.