198 lines
5.0 KiB
JavaScript
198 lines
5.0 KiB
JavaScript
const path = require('path');
|
|
const {createFilePath} = require('gatsby-source-filesystem');
|
|
const rollup = require('rollup');
|
|
const resolve = require('rollup-plugin-node-resolve');
|
|
const common = require('rollup-plugin-commonjs');
|
|
const fse = require('fs-extra');
|
|
const compileTemplate = require('string-template/compile');
|
|
|
|
let rollupCache;
|
|
const rollupPlugins = [resolve(), common()];
|
|
|
|
let olCss;
|
|
async function getOLCss() {
|
|
if (olCss) {
|
|
return olCss;
|
|
}
|
|
const cssPath = path.join(__dirname, '..', '..', '..', 'css', 'ol.css');
|
|
olCss = await fse.readFile(cssPath, {encoding: 'utf8'});
|
|
return olCss;
|
|
}
|
|
|
|
let embedTemplate;
|
|
async function getEmbedTemplate() {
|
|
if (embedTemplate) {
|
|
return embedTemplate;
|
|
}
|
|
const embedPath = path.join(__dirname, 'embed.html');
|
|
const src = await fse.readFile(embedPath, {encoding: 'utf8'});
|
|
embedTemplate = compileTemplate(src);
|
|
return embedTemplate;
|
|
}
|
|
|
|
exports.onCreateNode = ({node, getNode, boundActionCreators}) => {
|
|
const {createNodeField} = boundActionCreators;
|
|
if (node.internal.type === 'MarkdownRemark') {
|
|
const slug = createFilePath({node, getNode});
|
|
createNodeField({
|
|
node,
|
|
name: 'slug',
|
|
value: `/examples${slug}` // TODO: get this from options
|
|
});
|
|
}
|
|
};
|
|
|
|
exports.createPages = async (
|
|
{graphql, boundActionCreators},
|
|
{sourceInstanceName, baseCss = ''}
|
|
) => {
|
|
const {createPage, createRedirect} = boundActionCreators;
|
|
|
|
createRedirect({
|
|
fromPath: `/examples/`,
|
|
isPermanent: true,
|
|
redirectInBrowser: true,
|
|
toPath: `/examples/map/`
|
|
});
|
|
|
|
const {data} = await graphql(`
|
|
{
|
|
allFile(
|
|
filter: {sourceInstanceName: {eq: "${sourceInstanceName}"}, extension: {ne: ""}}
|
|
) {
|
|
edges {
|
|
node {
|
|
base
|
|
name
|
|
extension
|
|
absolutePath
|
|
childMarkdownRemark {
|
|
frontmatter {
|
|
title
|
|
}
|
|
fields {
|
|
slug
|
|
}
|
|
html
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`);
|
|
|
|
const rollupInputs = [];
|
|
|
|
const examples = {};
|
|
data.allFile.edges.forEach(({node}) => {
|
|
const name = node.name;
|
|
if (!(name in examples)) {
|
|
examples[name] = {};
|
|
}
|
|
examples[name][node.extension] = node;
|
|
if (node.extension === 'js') {
|
|
rollupInputs.push(node.absolutePath);
|
|
}
|
|
});
|
|
|
|
const bundle = await rollup.rollup({
|
|
input: rollupInputs,
|
|
plugins: rollupPlugins,
|
|
experimentalCodeSplitting: true,
|
|
cache: rollupCache
|
|
});
|
|
|
|
const embedDirName = 'example-embeds';
|
|
const embedDir = path.join(__dirname, '..', '..', 'public', embedDirName);
|
|
const exampleDir = path.join(__dirname, '..', '..', 'public', 'examples');
|
|
|
|
rollupCache = await bundle.write({
|
|
format: 'es',
|
|
sourcemap: true,
|
|
dir: embedDir
|
|
});
|
|
|
|
const writes = [];
|
|
const index = {};
|
|
|
|
for (const name in examples) {
|
|
const node = examples[name].md;
|
|
if (!node) {
|
|
throw new Error(`Missing ${name}.md`);
|
|
}
|
|
const markdownNode = node.childMarkdownRemark;
|
|
if (!markdownNode) {
|
|
throw new Error(`Expected a MarkdownRemark node for ${name}`);
|
|
}
|
|
|
|
const mainBundleUrl = `${name}.js`;
|
|
const bundleInfo = rollupCache[mainBundleUrl];
|
|
if (!bundleInfo) {
|
|
throw new Error(`Expected a js bundle for ${name}`);
|
|
}
|
|
|
|
const jsNode = examples[name].js;
|
|
if (!jsNode) {
|
|
throw new Error(`Missing ${name}.js`);
|
|
}
|
|
|
|
const moduleIndex = bundleInfo.map.sources.findIndex(
|
|
filepath => path.resolve(filepath) === jsNode.absolutePath
|
|
);
|
|
if (moduleIndex < 0) {
|
|
throw new Error(`Could not find ${node.absolutePath} in module list`);
|
|
}
|
|
const source = bundleInfo.map.sourcesContent[moduleIndex];
|
|
if (!source) {
|
|
throw new Error(`Could not find source for ${jsNode.absolutePath}`);
|
|
}
|
|
|
|
let exampleCss = '';
|
|
const cssNode = examples[name].css;
|
|
if (cssNode) {
|
|
exampleCss = await fse.readFile(cssNode.absolutePath, {encoding: 'utf8'});
|
|
await fse.writeFile(path.join(embedDir, cssNode.base), exampleCss);
|
|
}
|
|
|
|
const embedTemplate = await getEmbedTemplate();
|
|
const embed = embedTemplate({
|
|
title: markdownNode.frontmatter.title,
|
|
baseCss,
|
|
olCss: await getOLCss(),
|
|
exampleCss,
|
|
html: markdownNode.html,
|
|
mainBundleUrl
|
|
});
|
|
|
|
const embedName = `${name}.html`;
|
|
writes.push(fse.writeFile(path.join(embedDir, embedName), embed));
|
|
|
|
const slug = markdownNode.fields.slug;
|
|
index[name] = {
|
|
title: markdownNode.frontmatter.title,
|
|
slug
|
|
};
|
|
|
|
createPage({
|
|
path: slug,
|
|
component: path.join(__dirname, 'components', 'Example.js'),
|
|
context: {
|
|
slug,
|
|
frontmatter: markdownNode.frontmatter,
|
|
embedUrl: `/${embedDirName}/${embedName}`,
|
|
html: markdownNode.html,
|
|
js: source.replace(/'\.\.\/src\/(.*?)\.js/g, "'$1"),
|
|
css: exampleCss
|
|
}
|
|
});
|
|
}
|
|
|
|
await fse.ensureDir(exampleDir);
|
|
|
|
writes.push(
|
|
fse.writeFile(path.join(exampleDir, 'index.json'), JSON.stringify(index))
|
|
);
|
|
|
|
await Promise.all(writes);
|
|
};
|