Skip to content

Instantly share code, notes, and snippets.

@ascorbic
Created June 5, 2020 08:54
Show Gist options
  • Save ascorbic/107a0adf2d2d3b5bdd3d7a64a45f4aa7 to your computer and use it in GitHub Desktop.
Save ascorbic/107a0adf2d2d3b5bdd3d7a64a45f4aa7 to your computer and use it in GitHub Desktop.
--- src/bootstrap/index.js 2020-06-05 09:41:29.000000000 +0100
+++ src/services/initialize.ts 2020-06-05 09:41:29.000000000 +0100
@@ -1,52 +1,47 @@
-/* @flow */
+import _ from "lodash"
+import { slash } from "gatsby-core-utils"
+import fs from "fs-extra"
+import md5File from "md5-file/promise"
+import crypto from "crypto"
+import del from "del"
+import path from "path"
+import telemetry from "gatsby-telemetry"
-const _ = require(`lodash`)
-const { slash } = require(`gatsby-core-utils`)
-const fs = require(`fs-extra`)
-const md5File = require(`md5-file/promise`)
-const crypto = require(`crypto`)
-const del = require(`del`)
-const path = require(`path`)
-const Promise = require(`bluebird`)
-const telemetry = require(`gatsby-telemetry`)
-
-const apiRunnerNode = require(`../utils/api-runner-node`)
+import apiRunnerNode from "../utils/api-runner-node"
import { getBrowsersList } from "../utils/browserslist"
-import { createSchemaCustomization } from "../utils/create-schema-customization"
+import { Store } from "../.."
+import { Span } from "opentracing"
+import { preferDefault } from "../bootstrap/prefer-default"
+import * as WorkerPool from "../utils/worker/pool"
+import JestWorker from "jest-worker"
import { startPluginRunner } from "../redux/plugin-runner"
-const { store, emitter } = require(`../redux`)
+import { loadPlugins } from "../bootstrap/load-plugins"
+import { store, emitter } from "../redux"
+import loadThemes from "../bootstrap/load-themes"
+import reporter from "gatsby-cli/lib/reporter"
+import { getConfigFile } from "../bootstrap/get-config-file"
+import { removeStaleJobs } from "../bootstrap/remove-stale-jobs"
+import { ErrorMeta } from "gatsby-cli/lib/reporter/types"
+import { globalTracer } from "opentracing"
+import { IPluginInfoOptions } from "../bootstrap/load-plugins/types"
import { internalActions } from "../redux/actions"
-const { loadPlugins } = require(`./load-plugins`)
-const loadThemes = require(`./load-themes`)
-const reporter = require(`gatsby-cli/lib/reporter`)
-import { getConfigFile } from "./get-config-file"
-const tracer = require(`opentracing`).globalTracer()
-import { preferDefault } from "./prefer-default"
-import { removeStaleJobs } from "./remove-stale-jobs"
+
+const tracer = globalTracer()
// Show stack trace on unhandled promises.
-process.on(`unhandledRejection`, (reason, p) => {
- reporter.panic(reason)
+process.on(`unhandledRejection`, reason => {
+ reporter.panic({ id: ``, context: reason } as ErrorMeta)
})
-import { createGraphQLRunner } from "./create-graphql-runner"
-const { extractQueries } = require(`../query/query-watcher`)
-import * as requiresWriter from "./requires-writer"
-import { writeRedirects, startRedirectListener } from "./redirects-writer"
-
// Override console.log to add the source file + line number.
// Useful for debugging if you lose a console.log somewhere.
// Otherwise leave commented out.
-// import "./log-line-function"
+// require(`../bootstrap/log-line-function`)
-type BootstrapArgs = {
- directory: string,
- prefixPaths?: boolean,
- parentSpan: Object,
- graphqlTracing: boolean,
-}
-
-module.exports = async (args: BootstrapArgs) => {
+export async function initialize(
+ context
+): Promise<{ store: Store; bootstrapSpan: Span; workerPool: JestWorker }> {
+ const args = context.program
const spanArgs = args.parentSpan ? { childOf: args.parentSpan } : {}
const bootstrapSpan = tracer.startSpan(`bootstrap`, spanArgs)
@@ -71,8 +66,6 @@
// and invokes Gatsby API based on actions.
startPluginRunner()
- startRedirectListener()
-
const directory = slash(args.directory)
const program = {
@@ -96,7 +89,7 @@
}
})
- const onEndJob = () => {
+ const onEndJob = (): void => {
if (activityForJobs && store.getState().jobs.active.length === 0) {
activityForJobs.end()
activityForJobs = null
@@ -293,12 +286,8 @@
const siteDir = cacheDirectory
const tryRequire = `${__dirname}/../utils/test-require-error.js`
try {
- await fs.copy(srcDir, siteDir, {
- clobber: true,
- })
- await fs.copy(tryRequire, `${siteDir}/test-require-error.js`, {
- clobber: true,
- })
+ await fs.copy(srcDir, siteDir)
+ await fs.copy(tryRequire, `${siteDir}/test-require-error.js`)
await fs.ensureDirSync(`${cacheDirectory}/json`)
// Ensure .cache/fragments exists and is empty. We want fragments to be
@@ -311,7 +300,7 @@
// Find plugins which implement gatsby-browser and gatsby-ssr and write
// out api-runners for them.
- const hasAPIFile = (env, plugin) => {
+ const hasAPIFile = (env, plugin): string | undefined => {
// The plugin loader has disabled SSR APIs for this plugin. Usually due to
// multiple implementations of an API that can only be implemented once
if (env === `ssr` && plugin.skipSSR === true) return undefined
@@ -336,25 +325,30 @@
return undefined
}
- const ssrPlugins = _.filter(
- flattenedPlugins.map(plugin => {
+ interface IPluginResolution {
+ resolve: string
+ options: IPluginInfoOptions
+ }
+
+ const isResolved = (plugin): plugin is IPluginResolution => !!plugin.resolve
+
+ const ssrPlugins: IPluginResolution[] = flattenedPlugins
+ .map(plugin => {
return {
resolve: hasAPIFile(`ssr`, plugin),
options: plugin.pluginOptions,
}
- }),
- plugin => plugin.resolve
- )
+ })
+ .filter(isResolved)
- const browserPlugins = _.filter(
- flattenedPlugins.map(plugin => {
+ const browserPlugins: IPluginResolution[] = flattenedPlugins
+ .map(plugin => {
return {
resolve: hasAPIFile(`browser`, plugin),
options: plugin.pluginOptions,
}
- }),
- plugin => plugin.resolve
- )
+ })
+ .filter(isResolved)
const browserPluginsRequires = browserPlugins
.map(plugin => {
@@ -410,39 +404,6 @@
})
activity.end()
- // Prepare static schema types
- activity = reporter.activityTimer(`createSchemaCustomization`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await createSchemaCustomization({
- parentSpan: bootstrapSpan,
- })
- activity.end()
-
- // Source nodes
- activity = reporter.activityTimer(`source and transform nodes`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await require(`../utils/source-nodes`).default({ parentSpan: activity.span })
- reporter.verbose(
- `Now have ${store.getState().nodes.size} nodes with ${
- store.getState().nodesByType.size
- } types: [${[...store.getState().nodesByType.entries()]
- .map(([type, nodes]) => type + `:` + nodes.size)
- .join(`, `)}]`
- )
- activity.end()
-
- // Create Schema.
- activity = reporter.activityTimer(`building schema`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await require(`../schema`).build({ parentSpan: activity.span })
- activity.end()
-
// Collect resolvable extensions and attach to program.
const extensions = [`.mjs`, `.js`, `.jsx`, `.wasm`, `.json`]
// Change to this being an action and plugins implement `onPreBootstrap`
@@ -457,110 +418,11 @@
payload: _.flattenDeep([extensions, apiResults]),
})
- const graphqlRunner = createGraphQLRunner(store, reporter, {
- graphqlTracing: args.graphqlTracing,
- parentSpan: args.parentSpan ? args.parentSpan : bootstrapSpan,
- })
+ const workerPool = WorkerPool.create()
- // Collect pages.
- activity = reporter.activityTimer(`createPages`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await apiRunnerNode(
- `createPages`,
- {
- graphql: graphqlRunner,
- traceId: `initial-createPages`,
- waitForCascadingActions: true,
- parentSpan: activity.span,
- },
- { activity }
- )
- reporter.verbose(
- `Now have ${store.getState().nodes.size} nodes with ${
- store.getState().nodesByType.size
- } types, and ${
- store.getState().nodesByType?.get(`SitePage`).size
- } SitePage nodes`
- )
- activity.end()
-
- // A variant on createPages for plugins that want to
- // have full control over adding/removing pages. The normal
- // "createPages" API is called every time (during development)
- // that data changes.
- activity = reporter.activityTimer(`createPagesStatefully`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await apiRunnerNode(
- `createPagesStatefully`,
- {
- graphql: graphqlRunner,
- traceId: `initial-createPagesStatefully`,
- waitForCascadingActions: true,
- parentSpan: activity.span,
- },
- {
- activity,
- }
- )
- activity.end()
-
- activity = reporter.activityTimer(`onPreExtractQueries`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await apiRunnerNode(`onPreExtractQueries`, { parentSpan: activity.span })
- activity.end()
-
- // Update Schema for SitePage.
- activity = reporter.activityTimer(`update schema`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await require(`../schema`).rebuildWithSitePage({ parentSpan: activity.span })
- activity.end()
-
- await extractQueries({ parentSpan: bootstrapSpan })
-
- // Write out files.
- activity = reporter.activityTimer(`write out requires`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- try {
- await requiresWriter.writeAll(store.getState())
- } catch (err) {
- reporter.panic(`Failed to write out requires`, err)
+ return {
+ store,
+ bootstrapSpan,
+ workerPool,
}
- activity.end()
-
- // Write out redirects.
- activity = reporter.activityTimer(`write out redirect data`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await writeRedirects()
- activity.end()
-
- activity = reporter.activityTimer(`onPostBootstrap`, {
- parentSpan: bootstrapSpan,
- })
- activity.start()
- await apiRunnerNode(`onPostBootstrap`, { parentSpan: activity.span })
- activity.end()
-
- reporter.log(``)
- reporter.info(`bootstrap finished - ${process.uptime().toFixed(3)}s`)
- reporter.log(``)
- emitter.emit(`BOOTSTRAP_FINISHED`)
- require(`../redux/actions`).boundActionCreators.setProgramStatus(
- `BOOTSTRAP_FINISHED`
- )
-
- bootstrapSpan.finish()
-
- return { graphqlRunner }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment