Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pages-writer -> requires-writer (and remove data.json) #13729

Merged
merged 1 commit into from
Apr 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions packages/gatsby/src/bootstrap/__tests__/requires-writer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { joinPath } = require(`../../utils/path`)
const requiresWriter = require(`../requires-writer`)

const now = Date.now()

const newMockState = () => {
const pages = new Map()
pages.set(`path1`, {
component: `component1`,
componentChunkName: `chunkName1`,
matchPath: `matchPath1`,
path: `/path1`,
})
pages.set(`path2`, {
component: `component2`,
componentChunkName: `chunkName2`,
path: `/path2`,
})
const program = { directory: `/dir` }
return { pages, program }
}

jest.mock(`fs-extra`, () => {
return {
writeFile: () => Promise.resolve(),
move: () => {},
}
})

const mockFsExtra = require(`fs-extra`)

describe(`requires-writer`, () => {
beforeEach(() => {
global.Date.now = () => now
requiresWriter.resetLastHash()
})
describe(`writeAll`, () => {
it(`writes requires files`, async () => {
const spy = jest.spyOn(mockFsExtra, `writeFile`)
await requiresWriter.writeAll(newMockState())
expect(spy).toBeCalledWith(
joinPath(`/dir`, `.cache`, `match-paths.json.${now}`),
JSON.stringify([{ path: `/path1`, matchPath: `matchPath1` }], null, 4)
)
})
})
})
4 changes: 2 additions & 2 deletions packages/gatsby/src/bootstrap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ process.on(`unhandledRejection`, (reason, p) => {

const { extractQueries } = require(`../query/query-watcher`)
const queryUtil = require(`../query`)
const { writePages } = require(`../query/pages-writer`)
const requiresWriter = require(`./requires-writer`)
const { writeRedirects } = require(`./redirects-writer`)

// Override console.log to add the source file + line number.
Expand Down Expand Up @@ -480,7 +480,7 @@ module.exports = async (args: BootstrapArgs) => {
})
activity.start()
try {
await writePages()
await requiresWriter.writeAll(store.getState())
} catch (err) {
report.panic(`Failed to write out page data`, err)
}
Expand Down
126 changes: 126 additions & 0 deletions packages/gatsby/src/bootstrap/requires-writer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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

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("${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`

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(`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,
}
2 changes: 2 additions & 0 deletions packages/gatsby/src/commands/develop.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const onExit = require(`signal-exit`)
const queryUtil = require(`../query`)
const queryQueue = require(`../query/queue`)
const queryWatcher = require(`../query/query-watcher`)
const requiresWriter = require(`../bootstrap/requires-writer`)

// const isInteractive = process.stdout.isTTY

Expand Down Expand Up @@ -93,6 +94,7 @@ async function startServer(program) {

db.startAutosave()
queryUtil.startListening(queryQueue.createDevelopQueue())
requiresWriter.startListener()
queryWatcher.startWatchDeletePage()

await createIndexHtml()
Expand Down
27 changes: 0 additions & 27 deletions packages/gatsby/src/query/__tests__/fixtures/pages.json

This file was deleted.

104 changes: 0 additions & 104 deletions packages/gatsby/src/query/__tests__/pages-writer.js

This file was deleted.

Loading