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

chore(gatsby): convert build-html to typescript #20535

Merged
merged 12 commits into from
Jan 28, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
3 changes: 1 addition & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ module.exports = {
`__tests__/fixtures`,
],
transform: {
"^.+\\.js$": `<rootDir>/jest-transformer.js`,
"^.+\\.tsx?$": `<rootDir>/jest-transformer.js`,
"^.+\\.[jt]s$": `<rootDir>/jest-transformer.js`,
},
moduleNameMapper: {
"^highlight.js$": `<rootDir>/node_modules/highlight.js/lib/index.js`,
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
"@babel/plugin-transform-typescript": "^7.7.4",
"@babel/runtime": "^7.7.7",
"@lerna/prompt": "3.18.5",
"@types/bluebird": "^3.5.29",
"@types/express": "^4.17.2",
"@types/fs-extra": "^8.0.1",
"@types/got": "^9.6.9",
"@types/jest": "^24.0.23",
"@types/lodash": "^4.14.149",
"@types/node": "^12.12.11",
"@types/webpack": "^4.41.0",
"@typescript-eslint/eslint-plugin": "^2.12.0",
Expand Down
140 changes: 0 additions & 140 deletions packages/gatsby/src/commands/build-html.js

This file was deleted.

141 changes: 141 additions & 0 deletions packages/gatsby/src/commands/build-html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import Bluebird from "bluebird"
blainekasten marked this conversation as resolved.
Show resolved Hide resolved
import webpack from "webpack"
import fs from "fs-extra"
// import convertHrtime from "convert-hrtime"
blainekasten marked this conversation as resolved.
Show resolved Hide resolved
import { chunk } from "lodash"
import webpackConfig from "../utils/webpack.config"
import reporter from "gatsby-cli/lib/reporter"
import { createErrorFromString } from "gatsby-cli/lib/reporter/errors"
import telemetry from "gatsby-telemetry"
import { BuildHTMLStage, IProgram } from "./types"

type IActivity = any // TODO
type IWorkerPool = any // TODO

import { structureWebpackErrors } from "../utils/webpack-error-utils"

const runWebpack = (compilerConfig): Bluebird<webpack.Stats> =>
new Bluebird((resolve, reject) => {
webpack(compilerConfig).run((err, stats) => {
if (err) {
reject(err)
} else {
resolve(stats)
}
})
})

const doBuildRenderer = async (
program: IProgram,
webpackConfig: webpack.Configuration
): Promise<string> => {
ascorbic marked this conversation as resolved.
Show resolved Hide resolved
const { directory } = program
const stats = await runWebpack(webpackConfig)
// render-page.js is hard coded in webpack.config
const outputFile = `${directory}/public/render-page.js`
if (stats.hasErrors()) {
reporter.panic(
structureWebpackErrors(`build-html`, stats.compilation.errors)
)
}
return outputFile
}

const buildRenderer = async (
program: IProgram,
stage: BuildHTMLStage,
parentSpan: IActivity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parentSpan is destructured in the previous code. Was that a mistake? It does seem a bit odd to destructure it then immediately recreate the object below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

): Promise<string> => {
const { directory } = program
const config = await webpackConfig(program, directory, stage, null, {
parentSpan,
blainekasten marked this conversation as resolved.
Show resolved Hide resolved
})
return await doBuildRenderer(program, config)
}

const deleteRenderer = async (rendererPath: string): Promise<void> => {
try {
await fs.remove(rendererPath)
await fs.remove(`${rendererPath}.map`)
} catch (e) {
// This function will fail on Windows with no further consequences.
}
}

const renderHTMLQueue = async (
workerPool: IWorkerPool,
activity: IActivity,
htmlComponentRendererPath: string,
pages: string[]
): Promise<void> => {
// We need to only pass env vars that are set programmatically in gatsby-cli
// to child process. Other vars will be picked up from environment.
const envVars = [
[`NODE_ENV`, process.env.NODE_ENV],
[`gatsby_executing_command`, process.env.gatsby_executing_command],
[`gatsby_log_level`, process.env.gatsby_log_level],
]

// const start = process.hrtime()
const segments = chunk(pages, 50)
// let finished = 0

await Bluebird.map(segments, async pageSegment => {
await workerPool.renderHTML({
htmlComponentRendererPath,
paths: pageSegment,
envVars,
})
// finished += pageSegment.length
if (activity && activity.tick) {
activity.tick(pageSegment.length)
// activity.setStatus(
// `${finished}/${pages.length} ${(
// finished / convertHrtime(process.hrtime(start)).seconds
// ).toFixed(2)} pages/second`
// )
}
})
}

const doBuildPages = async (
rendererPath: string,
pagePaths: string[],
activity: IActivity,
workerPool: IWorkerPool
): Promise<void> => {
telemetry.addSiteMeasurement(`BUILD_END`, {
pagesCount: pagePaths.length,
})

try {
await renderHTMLQueue(workerPool, activity, rendererPath, pagePaths)
} catch (e) {
const prettyError = await createErrorFromString(
e.stack,
`${rendererPath}.map`
)
prettyError.context = e.context
throw prettyError
}
}

const buildHTML = async ({
blainekasten marked this conversation as resolved.
Show resolved Hide resolved
program,
stage,
pagePaths,
activity,
workerPool,
}: {
program: IProgram
stage: BuildHTMLStage
pagePaths: string[]
activity: IActivity
workerPool: IWorkerPool
}): Promise<void> => {
const rendererPath = await buildRenderer(program, stage, activity.span)
await doBuildPages(rendererPath, pagePaths, activity, workerPool)
await deleteRenderer(rendererPath)
}

export default buildHTML
4 changes: 2 additions & 2 deletions packages/gatsby/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const path = require(`path`)
const report = require(`gatsby-cli/lib/reporter`)
const buildHTML = require(`./build-html`)
import buildHTML from "./build-html"
blainekasten marked this conversation as resolved.
Show resolved Hide resolved
const buildProductionBundle = require(`./build-javascript`)
const bootstrap = require(`../bootstrap`)
const apiRunnerNode = require(`../utils/api-runner-node`)
Expand Down Expand Up @@ -142,7 +142,7 @@ module.exports = async function build(program: BuildArgs) {
)
activity.start()
try {
await buildHTML.buildPages({
await buildHTML({
program,
stage: `build-html`,
pagePaths,
Expand Down
26 changes: 3 additions & 23 deletions packages/gatsby/src/commands/develop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import chokidar from "chokidar"

import webpackHotMiddleware from "webpack-hot-middleware"
import webpackDevMiddleware from "webpack-dev-middleware"
import { PackageJson } from "gatsby"
import glob from "glob"
import express from "express"
import got from "got"
Expand Down Expand Up @@ -54,26 +53,7 @@ import {
structureWebpackErrors,
} from "../utils/webpack-error-utils"

interface ICert {
keyPath: string
certPath: string
key: string
cert: string
}

interface IProgram {
useYarn: boolean
open: boolean
openTracingConfigFile: string
port: number
host: string
[`cert-file`]?: string
[`key-file`]?: string
directory: string
https?: boolean
sitePackageJson: PackageJson
ssl?: ICert
}
import { BuildHTMLStage, IProgram } from "./types"

// const isInteractive = process.stdout.isTTY

Expand Down Expand Up @@ -116,9 +96,9 @@ async function startServer(program: IProgram): Promise<IServer> {
const workerPool = WorkerPool.create()
const createIndexHtml = async (activity: ActivityTracker): Promise<void> => {
try {
await buildHTML.buildPages({
await buildHTML({
program,
stage: `develop-html`,
stage: BuildHTMLStage.DevelopHTML,
pagePaths: [`/`],
workerPool,
activity,
Expand Down
27 changes: 27 additions & 0 deletions packages/gatsby/src/commands/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { PackageJson } from "gatsby"

export interface ICert {
keyPath: string
certPath: string
key: string
cert: string
}

export interface IProgram {
useYarn: boolean
open: boolean
openTracingConfigFile: string
port: number
host: string
[`cert-file`]?: string
[`key-file`]?: string
directory: string
https?: boolean
sitePackageJson: PackageJson
ssl?: ICert
}

export enum BuildHTMLStage {
DevelopHTML = `develop-html`,
BuildHTML = `build-html`,
}
Loading