Skip to content

Commit 5b56934

Browse files
committedNov 10, 2017
Split gatsby-node into separate files
1 parent c899c61 commit 5b56934

File tree

5 files changed

+284
-249
lines changed

5 files changed

+284
-249
lines changed
 

‎gatsby-node.js

+4-249
Original file line numberDiff line numberDiff line change
@@ -6,252 +6,7 @@
66

77
'use strict';
88

9-
const {resolve} = require('path');
10-
const webpack = require('webpack');
11-
12-
exports.modifyWebpackConfig = ({config, stage}) => {
13-
// See https://github.com/FormidableLabs/react-live/issues/5
14-
config.plugin('ignore', () => new webpack.IgnorePlugin(/^(xor|props)$/));
15-
16-
config.merge({
17-
resolve: {
18-
root: resolve(__dirname, './src'),
19-
extensions: ['', '.js', '.jsx', '.json'],
20-
},
21-
});
22-
return config;
23-
};
24-
25-
exports.createPages = async ({graphql, boundActionCreators}) => {
26-
const {createPage, createRedirect} = boundActionCreators;
27-
28-
// Used to detect and prevent duplicate redirects
29-
const redirectToSlugMap = {};
30-
31-
const blogTemplate = resolve('./src/templates/blog.js');
32-
const communityTemplate = resolve('./src/templates/community.js');
33-
const docsTemplate = resolve('./src/templates/docs.js');
34-
const tutorialTemplate = resolve('./src/templates/tutorial.js');
35-
36-
// Redirect /index.html to root.
37-
createRedirect({
38-
fromPath: '/index.html',
39-
redirectInBrowser: true,
40-
toPath: '/',
41-
});
42-
43-
const allMarkdown = await graphql(
44-
`
45-
{
46-
allMarkdownRemark(limit: 1000) {
47-
edges {
48-
node {
49-
fields {
50-
redirect
51-
slug
52-
}
53-
}
54-
}
55-
}
56-
}
57-
`,
58-
);
59-
60-
if (allMarkdown.errors) {
61-
console.error(allMarkdown.errors);
62-
63-
throw Error(allMarkdown.errors);
64-
}
65-
66-
allMarkdown.data.allMarkdownRemark.edges.forEach(edge => {
67-
const slug = edge.node.fields.slug;
68-
69-
if (slug === 'docs/error-decoder.html') {
70-
// No-op so far as markdown templates go.
71-
// Error codes are managed by a page in src/pages
72-
// (which gets created by Gatsby during a separate phase).
73-
} else if (
74-
slug.includes('blog/') ||
75-
slug.includes('community/') ||
76-
slug.includes('contributing/') ||
77-
slug.includes('docs/') ||
78-
slug.includes('tutorial/') ||
79-
slug.includes('warnings/')
80-
) {
81-
let template;
82-
if (slug.includes('blog/')) {
83-
template = blogTemplate;
84-
} else if (slug.includes('community/')) {
85-
template = communityTemplate;
86-
} else if (
87-
slug.includes('contributing/') ||
88-
slug.includes('docs/') ||
89-
slug.includes('warnings/')
90-
) {
91-
template = docsTemplate;
92-
} else if (slug.includes('tutorial/')) {
93-
template = tutorialTemplate;
94-
}
95-
96-
const createArticlePage = path =>
97-
createPage({
98-
path: path,
99-
component: template,
100-
context: {
101-
slug,
102-
},
103-
});
104-
105-
// Register primary URL.
106-
createArticlePage(slug);
107-
108-
// Register redirects as well if the markdown specifies them.
109-
if (edge.node.fields.redirect) {
110-
let redirect = JSON.parse(edge.node.fields.redirect);
111-
if (!Array.isArray(redirect)) {
112-
redirect = [redirect];
113-
}
114-
115-
redirect.forEach(fromPath => {
116-
if (redirectToSlugMap[fromPath] != null) {
117-
console.error(
118-
`Duplicate redirect detected from "${fromPath}" to:\n` +
119-
`* ${redirectToSlugMap[fromPath]}\n` +
120-
`* ${slug}\n`,
121-
);
122-
process.exit(1);
123-
}
124-
125-
// A leading "/" is required for redirects to work,
126-
// But multiple leading "/" will break redirects.
127-
// For more context see github.com/reactjs/reactjs.org/pull/194
128-
const toPath = slug.startsWith('/') ? slug : `/${slug}`;
129-
130-
redirectToSlugMap[fromPath] = slug;
131-
createRedirect({
132-
fromPath: `/${fromPath}`,
133-
redirectInBrowser: true,
134-
toPath,
135-
});
136-
});
137-
}
138-
}
139-
});
140-
141-
const newestBlogEntry = await graphql(
142-
`
143-
{
144-
allMarkdownRemark(
145-
limit: 1
146-
filter: {id: {regex: "/blog/"}}
147-
sort: {fields: [fields___date], order: DESC}
148-
) {
149-
edges {
150-
node {
151-
fields {
152-
slug
153-
}
154-
}
155-
}
156-
}
157-
}
158-
`,
159-
);
160-
const newestBlogNode = newestBlogEntry.data.allMarkdownRemark.edges[0].node;
161-
162-
// Blog landing page should always show the most recent blog entry.
163-
createRedirect({
164-
fromPath: '/blog/',
165-
redirectInBrowser: true,
166-
toPath: newestBlogNode.fields.slug,
167-
});
168-
};
169-
170-
// Parse date information out of blog post filename.
171-
const BLOG_POST_FILENAME_REGEX = /([0-9]+)\-([0-9]+)\-([0-9]+)\-(.+)\.md$/;
172-
173-
// Add custom fields to MarkdownRemark nodes.
174-
exports.onCreateNode = ({node, boundActionCreators, getNode}) => {
175-
const {createNodeField} = boundActionCreators;
176-
177-
switch (node.internal.type) {
178-
case 'MarkdownRemark':
179-
const {permalink, redirect_from} = node.frontmatter;
180-
const {relativePath} = getNode(node.parent);
181-
182-
let slug = permalink;
183-
184-
if (!slug) {
185-
if (relativePath.includes('blog')) {
186-
// Blog posts don't have embedded permalinks.
187-
// Their slugs follow a pattern: /blog/<year>/<month>/<day>/<slug>.html
188-
// The date portion comes from the file name: <date>-<title>.md
189-
const match = BLOG_POST_FILENAME_REGEX.exec(relativePath);
190-
const year = match[1];
191-
const month = match[2];
192-
const day = match[3];
193-
const filename = match[4];
194-
195-
slug = `/blog/${year}/${month}/${day}/${filename}.html`;
196-
197-
const date = new Date(year, month - 1, day);
198-
199-
// Blog posts are sorted by date and display the date in their header.
200-
createNodeField({
201-
node,
202-
name: 'date',
203-
value: date.toJSON(),
204-
});
205-
}
206-
}
207-
208-
if (!slug) {
209-
slug = `/${relativePath.replace('.md', '.html')}`;
210-
211-
// This should only happen for the partials in /content/home,
212-
// But let's log it in case it happens for other files also.
213-
console.warn(
214-
`Warning: No slug found for "${relativePath}". Falling back to default "${slug}".`,
215-
);
216-
}
217-
218-
// Used to generate URL to view this content.
219-
createNodeField({
220-
node,
221-
name: 'slug',
222-
value: slug,
223-
});
224-
225-
// Used to generate a GitHub edit link.
226-
createNodeField({
227-
node,
228-
name: 'path',
229-
value: relativePath,
230-
});
231-
232-
// Used by createPages() above to register redirects.
233-
createNodeField({
234-
node,
235-
name: 'redirect',
236-
value: redirect_from ? JSON.stringify(redirect_from) : '',
237-
});
238-
return;
239-
}
240-
};
241-
242-
exports.onCreatePage = async ({page, boundActionCreators}) => {
243-
const {createPage} = boundActionCreators;
244-
245-
return new Promise(resolvePromise => {
246-
// page.matchPath is a special key that's used for matching pages only on the client.
247-
// Explicitly wire up all error code wildcard matches to redirect to the error code page.
248-
if (page.path.includes('docs/error-decoder.html')) {
249-
page.matchPath = 'docs/error-decoder:path?';
250-
page.context.slug = 'docs/error-decoder.html';
251-
252-
createPage(page);
253-
}
254-
255-
resolvePromise();
256-
});
257-
};
9+
exports.modifyWebpackConfig = require('./gatsby/modifyWebpackConfig');
10+
exports.createPages = require('./gatsby/createPages');
11+
exports.onCreateNode = require('./gatsby/onCreateNode');
12+
exports.onCreatePage = require('./gatsby/onCreatePage');

0 commit comments

Comments
 (0)