Files
openlayers/site/plugins/examples/gatsby-node.js
2018-06-12 08:00:27 -06:00

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);
};