Skip to content

Commit 29298f6

Browse files
authored
feat(gatsby): engines activity (#33273)
1 parent 3f1fa78 commit 29298f6

16 files changed

+311
-311
lines changed

integration-tests/artifacts/gatsby-config.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,5 @@ module.exports = {
66
github: `sidharthachatterjee`,
77
moreInfo: `Sid is amazing`,
88
},
9-
flags: {
10-
PRESERVE_WEBPACK_CACHE: true,
11-
},
129
plugins: [`gatsby-plugin-webpack-1`, `gatsby-plugin-webpack-2`],
1310
}

packages/gatsby/src/commands/build-html.ts

Lines changed: 51 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import fs from "fs-extra"
33
import reporter from "gatsby-cli/lib/reporter"
44
import { createErrorFromString } from "gatsby-cli/lib/reporter/errors"
55
import { chunk, truncate } from "lodash"
6-
import webpack, { Stats } from "webpack"
6+
import { build, watch } from "../utils/webpack/bundle"
77
import * as path from "path"
88

99
import { emitter, store } from "../redux"
1010
import { IWebpackWatchingPauseResume } from "../utils/start-server"
11+
import webpack from "webpack"
1112
import webpackConfig from "../utils/webpack.config"
1213
import { structureWebpackErrors } from "../utils/webpack-error-utils"
1314
import * as buildUtils from "./build-utils"
@@ -17,10 +18,10 @@ import { Span } from "opentracing"
1718
import { IProgram, Stage } from "./types"
1819
import { ROUTES_DIRECTORY } from "../constants"
1920
import { PackageJson } from "../.."
20-
import type { GatsbyWorkerPool } from "../utils/worker/pool"
2121
import { IPageDataWithQueryResult } from "../utils/page-data"
2222
import { processNodeManifests } from "../utils/node-manifest"
2323

24+
import type { GatsbyWorkerPool } from "../utils/worker/pool"
2425
type IActivity = any // TODO
2526

2627
export interface IBuildArgs extends IProgram {
@@ -37,8 +38,13 @@ export interface IBuildArgs extends IProgram {
3738
keepPageRenderer: boolean
3839
}
3940

40-
let devssrWebpackCompiler: webpack.Compiler
41-
let devssrWebpackWatcher: IWebpackWatchingPauseResume
41+
interface IBuildRendererResult {
42+
rendererPath: string
43+
stats: webpack.Stats
44+
close: ReturnType<typeof watch>["close"]
45+
}
46+
47+
let devssrWebpackCompiler: webpack.Watching | undefined
4248
let needToRecompileSSRBundle = true
4349
export const getDevSSRWebpack = (): {
4450
devssrWebpackWatcher: IWebpackWatchingPauseResume
@@ -50,8 +56,8 @@ export const getDevSSRWebpack = (): {
5056
}
5157

5258
return {
53-
devssrWebpackWatcher,
54-
devssrWebpackCompiler,
59+
devssrWebpackWatcher: devssrWebpackCompiler as webpack.Watching,
60+
devssrWebpackCompiler: (devssrWebpackCompiler as webpack.Watching).compiler,
5561
needToRecompileSSRBundle,
5662
}
5763
}
@@ -61,60 +67,33 @@ let newHash = ``
6167
const runWebpack = (
6268
compilerConfig,
6369
stage: Stage,
64-
directory,
65-
parentSpan?: Span
66-
): Bluebird<{
67-
stats: Stats
68-
waitForCompilerClose: Promise<void>
69-
}> =>
70-
new Bluebird((resolve, reject) => {
71-
if (!process.env.GATSBY_EXPERIMENTAL_DEV_SSR || stage === `build-html`) {
70+
directory: string
71+
): Promise<{
72+
stats: webpack.Stats
73+
close: ReturnType<typeof watch>["close"]
74+
}> => {
75+
const isDevSSREnabledAndViable =
76+
process.env.GATSBY_EXPERIMENTAL_DEV_SSR && stage === `develop-html`
77+
78+
return new Promise((resolve, reject) => {
79+
if (isDevSSREnabledAndViable) {
7280
const compiler = webpack(compilerConfig)
73-
compiler.run((err, stats) => {
74-
let activity
75-
if (process.env.GATSBY_EXPERIMENTAL_PRESERVE_WEBPACK_CACHE) {
76-
activity = reporter.activityTimer(
77-
`Caching HTML renderer compilation`,
78-
{ parentSpan }
79-
)
80-
activity.start()
81-
}
82-
83-
const waitForCompilerClose = new Promise<void>((resolve, reject) => {
84-
compiler.close(error => {
85-
if (activity) {
86-
activity.end()
87-
}
88-
89-
if (error) {
90-
return reject(error)
91-
}
92-
return resolve()
93-
})
94-
})
9581

96-
if (err) {
97-
return reject(err)
98-
} else {
99-
return resolve({ stats: stats as Stats, waitForCompilerClose })
100-
}
101-
})
102-
} else if (
103-
process.env.GATSBY_EXPERIMENTAL_DEV_SSR &&
104-
stage === `develop-html`
105-
) {
106-
devssrWebpackCompiler = webpack(compilerConfig)
107-
devssrWebpackCompiler.hooks.invalid.tap(`ssr file invalidation`, () => {
82+
// because of this line we can't use our watch helper
83+
// These things should use emitter
84+
compiler.hooks.invalid.tap(`ssr file invalidation`, () => {
10885
needToRecompileSSRBundle = true
10986
})
110-
devssrWebpackWatcher = devssrWebpackCompiler.watch(
87+
88+
const watcher = compiler.watch(
11189
{
11290
ignored: /node_modules/,
11391
},
11492
(err, stats) => {
93+
// this runs multiple times
11594
needToRecompileSSRBundle = false
11695
emitter.emit(`DEV_SSR_COMPILATION_DONE`)
117-
devssrWebpackWatcher.suspend()
96+
watcher.suspend()
11897

11998
if (err) {
12099
return reject(err)
@@ -132,59 +111,52 @@ const runWebpack = (
132111
oldHash = newHash
133112

134113
return resolve({
135-
stats: stats as Stats,
136-
waitForCompilerClose: Promise.resolve(),
114+
stats: stats as webpack.Stats,
115+
close: () =>
116+
new Promise((resolve, reject): void =>
117+
watcher.close(err => (err ? reject(err) : resolve()))
118+
),
137119
})
138120
}
139121
}
140-
) as IWebpackWatchingPauseResume
122+
)
123+
devssrWebpackCompiler = watcher
124+
} else {
125+
build(compilerConfig).then(({ stats, close }) => {
126+
resolve({ stats, close })
127+
})
141128
}
142129
})
130+
}
143131

144132
const doBuildRenderer = async (
145-
{ directory }: IProgram,
133+
directory: string,
146134
webpackConfig: webpack.Configuration,
147-
stage: Stage,
148-
parentSpan?: Span
149-
): Promise<{ rendererPath: string; waitForCompilerClose }> => {
150-
const { stats, waitForCompilerClose } = await runWebpack(
151-
webpackConfig,
152-
stage,
153-
directory,
154-
parentSpan
155-
)
156-
if (stats.hasErrors()) {
135+
stage: Stage
136+
): Promise<IBuildRendererResult> => {
137+
const { stats, close } = await runWebpack(webpackConfig, stage, directory)
138+
if (stats?.hasErrors()) {
157139
reporter.panic(structureWebpackErrors(stage, stats.compilation.errors))
158140
}
159141

160-
if (
161-
stage === `build-html` &&
162-
store.getState().html.ssrCompilationHash !== stats.hash
163-
) {
164-
store.dispatch({
165-
type: `SET_SSR_WEBPACK_COMPILATION_HASH`,
166-
payload: stats.hash as string,
167-
})
168-
}
169-
170142
// render-page.js is hard coded in webpack.config
171143
return {
172144
rendererPath: `${directory}/${ROUTES_DIRECTORY}render-page.js`,
173-
waitForCompilerClose,
145+
stats,
146+
close,
174147
}
175148
}
176149

177150
export const buildRenderer = async (
178151
program: IProgram,
179152
stage: Stage,
180153
parentSpan?: IActivity
181-
): Promise<{ rendererPath: string; waitForCompilerClose }> => {
182-
const { directory } = program
183-
const config = await webpackConfig(program, directory, stage, null, {
154+
): Promise<IBuildRendererResult> => {
155+
const config = await webpackConfig(program, program.directory, stage, null, {
184156
parentSpan,
185157
})
186158

187-
return doBuildRenderer(program, config, stage, parentSpan)
159+
return doBuildRenderer(program.directory, config, stage)
188160
}
189161

190162
// TODO remove after v4 release and update cloud internals
Lines changed: 4 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
import { Span } from "opentracing"
2-
import webpack, { WebpackError } from "webpack"
32
import webpackConfig from "../utils/webpack.config"
4-
import { IProgram } from "./types"
5-
import reporter from "gatsby-cli/lib/reporter"
6-
import {
7-
showExperimentNoticeAfterTimeout,
8-
CancelExperimentNoticeCallbackOrUndefined,
9-
} from "../utils/show-experiment-notice"
3+
import { build } from "../utils/webpack/bundle"
4+
import type { IProgram } from "./types"
105

116
export const buildProductionBundle = async (
127
program: IProgram,
138
parentSpan: Span
14-
): Promise<{
15-
stats: webpack.Stats | Error | Array<WebpackError>
16-
waitForCompilerClose: Promise<void>
17-
}> => {
9+
): Promise<ReturnType<typeof build>> => {
1810
const { directory } = program
1911

2012
const compilerConfig = await webpackConfig(
@@ -25,67 +17,5 @@ export const buildProductionBundle = async (
2517
{ parentSpan }
2618
)
2719

28-
return new Promise((resolve, reject) => {
29-
const compiler = webpack(compilerConfig)
30-
31-
const THIRTY_SECONDS = 30 * 1000
32-
let cancelCacheNotice: CancelExperimentNoticeCallbackOrUndefined
33-
if (
34-
process.env.gatsby_executing_command === `build` &&
35-
!process.env.GATSBY_EXPERIMENTAL_PRESERVE_WEBPACK_CACHE
36-
) {
37-
cancelCacheNotice = showExperimentNoticeAfterTimeout(
38-
`Persistent webpack caching`,
39-
`https://github.com/gatsbyjs/gatsby/discussions/28331`,
40-
`which enables webpack's persist caching and changes Gatsby's cache clearing behavior to not clear webpack's
41-
cache unless you run "gatsby clean" or delete the .cache folder manually.
42-
Here's how to try it:
43-
44-
module.exports = {
45-
flags: { PRESERVE_WEBPACK_CACHE: true },
46-
plugins: [...]
47-
}`,
48-
THIRTY_SECONDS
49-
)
50-
}
51-
52-
compiler.run((err, stats) => {
53-
if (cancelCacheNotice) {
54-
cancelCacheNotice()
55-
}
56-
57-
// stats can only be empty when an error occurs. Adding it to the if makes typescript happy.
58-
if (err || !stats) {
59-
return reject(err)
60-
}
61-
62-
if (stats.hasErrors()) {
63-
return reject(stats.compilation.errors)
64-
}
65-
66-
let activity
67-
if (process.env.GATSBY_EXPERIMENTAL_PRESERVE_WEBPACK_CACHE) {
68-
activity = reporter.activityTimer(
69-
`Caching JavaScript and CSS webpack compilation`,
70-
{ parentSpan }
71-
)
72-
activity.start()
73-
}
74-
75-
const waitForCompilerClose = new Promise<void>((resolve, reject) => {
76-
compiler.close(error => {
77-
if (activity) {
78-
activity.end()
79-
}
80-
81-
if (error) {
82-
return reject(error)
83-
}
84-
return resolve()
85-
})
86-
})
87-
88-
return resolve({ stats, waitForCompilerClose })
89-
})
90-
})
20+
return build(compilerConfig)
9121
}

0 commit comments

Comments
 (0)