Files
30-seconds-of-code/node_modules/gatsby/dist/bootstrap/requires-writer.js
2019-08-20 15:52:05 +02:00

107 lines
3.1 KiB
JavaScript

"use strict";
var _gatsbyCoreUtils = require("gatsby-core-utils");
const _ = require(`lodash`);
const fs = require(`fs-extra`);
const crypto = require(`crypto`);
const {
store,
emitter
} = require(`../redux/`);
let lastHash = null;
const resetLastHash = () => {
lastHash = null;
};
const pickComponentFields = page => _.pick(page, [`component`, `componentChunkName`]);
const getComponents = pages => _(pages).map(pickComponentFields).uniqBy(c => c.componentChunkName).value();
const pickMatchPathFields = page => _.pick(page, [`path`, `matchPath`]);
const getMatchPaths = pages => pages.filter(page => page.matchPath).map(pickMatchPathFields);
const createHash = (matchPaths, components) => crypto.createHash(`md5`).update(JSON.stringify({
matchPaths,
components
})).digest(`hex`); // Write out pages information.
const writeAll = async state => {
const {
program
} = state;
const pages = [...state.pages.values()];
const matchPaths = getMatchPaths(pages);
const components = getComponents(pages);
const newHash = createHash(matchPaths, components);
if (newHash === lastHash) {
// Nothing changed. No need to rewrite files
return Promise.resolve();
}
lastHash = newHash; // Create file with sync requires of components/json files.
let syncRequires = `const { hot } = require("react-hot-loader/root")
// prefer default export if available
const preferDefault = m => m && m.default || m
\n\n`;
syncRequires += `exports.components = {\n${components.map(c => ` "${c.componentChunkName}": hot(preferDefault(require("${(0, _gatsbyCoreUtils.joinPath)(c.component)}")))`).join(`,\n`)}
}\n\n`; // Create file with async requires of components/json files.
let asyncRequires = `// prefer default export if available
const preferDefault = m => m && m.default || m
\n`;
asyncRequires += `exports.components = {\n${components.map(c => ` "${c.componentChunkName}": () => import("${(0, _gatsbyCoreUtils.joinPath)(c.component)}" /* webpackChunkName: "${c.componentChunkName}" */)`).join(`,\n`)}
}\n\n`;
const writeAndMove = (file, data) => {
const destination = (0, _gatsbyCoreUtils.joinPath)(program.directory, `.cache`, file);
const tmp = `${destination}.${Date.now()}`;
return fs.writeFile(tmp, data).then(() => fs.move(tmp, destination, {
overwrite: true
}));
};
const result = await Promise.all([writeAndMove(`sync-requires.js`, syncRequires), writeAndMove(`async-requires.js`, asyncRequires), writeAndMove(`match-paths.json`, JSON.stringify(matchPaths, null, 4))]);
return result;
};
const debouncedWriteAll = _.debounce(() => writeAll(store.getState()), 500, {
leading: true
});
/**
* Start listening to CREATE/DELETE_PAGE events so we can rewrite
* files as required
*/
const startListener = () => {
emitter.on(`CREATE_PAGE`, () => {
debouncedWriteAll();
});
emitter.on(`CREATE_PAGE_END`, () => {
debouncedWriteAll();
});
emitter.on(`DELETE_PAGE`, () => {
debouncedWriteAll();
});
emitter.on(`DELETE_PAGE_BY_PATH`, () => {
debouncedWriteAll();
});
};
module.exports = {
writeAll,
resetLastHash,
startListener
};
//# sourceMappingURL=requires-writer.js.map