Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| const _ = require(`lodash`) | |
| const fs = require(`fs-extra`) | |
| const crypto = require(`crypto`) | |
| const { store, emitter } = require(`../../redux/`) | |
| import { joinPath } from "../../utils/path" | |
| let lastHash = null | |
| // Write out pages information. | |
| const writePages = async () => { | |
| bootstrapFinished = true | |
| let { program, jsonDataPaths, pages } = store.getState() | |
| pages = [...pages.values()] | |
| const pagesComponentDependencies = {} | |
| // Write out pages.json | |
| let pagesData = [] | |
| pages.forEach(({ path, matchPath, componentChunkName, jsonName }) => { | |
| const pageComponentsChunkNames = { | |
| componentChunkName, | |
| } | |
| if (program._[0] === `develop`) { | |
| pagesComponentDependencies[path] = pageComponentsChunkNames | |
| } | |
| pagesData.push({ | |
| ...pageComponentsChunkNames, | |
| jsonName, | |
| path, | |
| matchPath, | |
| }) | |
| }) | |
| pagesData = _.sortBy( | |
| pagesData, | |
| // Sort pages with matchPath to end so explicit routes | |
| // will match before general. | |
| p => (p.matchPath ? 1 : 0) | |
| ) | |
| const newHash = crypto | |
| .createHash(`md5`) | |
| .update(JSON.stringify(pagesComponentDependencies)) | |
| .digest(`hex`) | |
| if (newHash === lastHash) { | |
| // components didn't change - no need to rewrite pages.json | |
| return Promise.resolve() | |
| } | |
| lastHash = newHash | |
| // Get list of components, and json files. | |
| let components = [] | |
| let json = [] | |
| pages.forEach(p => { | |
| components.push({ | |
| componentChunkName: p.componentChunkName, | |
| component: p.component, | |
| }) | |
| if (p.jsonName && jsonDataPaths[p.jsonName]) { | |
| json.push({ jsonName: p.jsonName, dataPath: jsonDataPaths[p.jsonName] }) | |
| } | |
| }) | |
| components = _.uniqBy(components, c => c.componentChunkName) | |
| // Create file with sync requires of components/json files. | |
| let syncRequires = `// prefer default export if available | |
| const preferDefault = m => m && m.default || m | |
| \n\n` | |
| syncRequires += `exports.components = {\n${components | |
| .map( | |
| c => | |
| ` "${c.componentChunkName}": preferDefault(require("${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("${joinPath( | |
| c.component | |
| )}" /* webpackChunkName: "${c.componentChunkName}" */)` | |
| ) | |
| .join(`,\n`)} | |
| }\n\n` | |
| asyncRequires += `exports.data = () => import("${joinPath( | |
| program.directory, | |
| `.cache`, | |
| `data.json` | |
| )}")\n\n` | |
| const writeAndMove = (file, data) => { | |
| const destination = 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(`pages.json`, JSON.stringify(pagesData, null, 4)), | |
| writeAndMove(`sync-requires.js`, syncRequires), | |
| writeAndMove(`async-requires.js`, asyncRequires), | |
| writeAndMove( | |
| `data.json`, | |
| JSON.stringify({ | |
| pages: pagesData, | |
| dataPaths: jsonDataPaths, | |
| }) | |
| ), | |
| ]) | |
| return result | |
| } | |
| exports.writePages = writePages | |
| let bootstrapFinished = false | |
| let oldPages | |
| const debouncedWritePages = _.debounce( | |
| () => { | |
| // Don't write pages again until bootstrap has finished. | |
| if (bootstrapFinished && !_.isEqual(oldPages, store.getState().pages)) { | |
| writePages() | |
| oldPages = store.getState().pages | |
| } | |
| }, | |
| 500, | |
| { leading: true } | |
| ) | |
| emitter.on(`CREATE_PAGE`, () => { | |
| // Ignore CREATE_PAGE until bootstrap is finished | |
| // as this is called many many times during bootstrap and | |
| // we can ignore them until CREATE_PAGE_END is called. | |
| // | |
| // After bootstrap, we need to listen for this as stateful page | |
| // creators e.g. the plugin "gatsby-plugin-page-creator" | |
| // calls createPage directly so CREATE_PAGE_END won't get fired. | |
| if (bootstrapFinished) { | |
| debouncedWritePages() | |
| } | |
| }) | |
| emitter.on(`CREATE_PAGE_END`, () => { | |
| debouncedWritePages() | |
| }) | |
| emitter.on(`DELETE_PAGE`, () => { | |
| debouncedWritePages() | |
| }) | |
| emitter.on(`DELETE_PAGE_BY_PATH`, () => { | |
| debouncedWritePages() | |
| }) |