diff --git a/packages/gatsby/src/utils/webpack.config.js b/packages/gatsby/src/utils/webpack.config.js index 14206ba7860ea..355490ded00ae 100644 --- a/packages/gatsby/src/utils/webpack.config.js +++ b/packages/gatsby/src/utils/webpack.config.js @@ -192,7 +192,7 @@ module.exports = async ( return hasES6ModuleSupport(directory) ? { app: directoryPath(`.cache/production-app`), - rsc: directoryPath(`.cache/rsc`), + // rsc: directoryPath(`.cache/rsc`), } : { polyfill: directoryPath(`.cache/polyfill-entry`), @@ -632,77 +632,90 @@ module.exports = async ( cacheGroups: { default: false, defaultVendors: false, - // framework: { - // chunks: `all`, - // name: `framework`, - // // This regex ignores nested copies of framework libraries so they're bundled with their issuer. - // test: new RegExp( - // `(? 160000 && - // /node_modules[/\\]/.test(module.identifier()) - // ) - // }, - // name(module) { - // const hash = crypto.createHash(`sha1`) - // if (!module.libIdent) { - // throw new Error( - // `Encountered unknown module type: ${module.type}. Please open an issue.` - // ) - // } + framework: { + chunks: `all`, + name: `framework`, + // This regex ignores nested copies of framework libraries so they're bundled with their issuer. + test: new RegExp( + `(? 160000 && + /node_modules[/\\]/.test(module.identifier()) + ) + }, + name(module) { + const hash = crypto.createHash(`sha1`) + if (!module.libIdent) { + throw new Error( + `Encountered unknown module type: ${module.type}. Please open an issue.` + ) + } + + hash.update(module.libIdent({ context: program.directory })) + + return hash.digest(`hex`).substring(0, 8) + }, + priority: 30, + minChunks: 1, + reuseExistingChunk: true, + }, + commons: { + name: `commons`, + // if a chunk is used on all components we put it in commons (we need at least 2 components) + minChunks: Math.max(componentsCount, 2), + priority: 20, + }, + // If a chunk is used in at least 2 components we create a separate chunk + shared: { + test(module, ...rest) { + // if (!global.logged) { + // console.log({ module, rest, that: this }) + // global.logged = true + // } + + for (const chunk of module.chunksIterable) { + if (chunk.canBeInitial()) { + return false + } + } + + return !isCssModule(module) + }, + name(module, chunks) { + const hash = crypto + .createHash(`sha1`) + .update(chunks.reduce((acc, chunk) => acc + chunk.name, ``)) + .digest(`hex`) + + return hash + }, + priority: 10, + minChunks: 2, + reuseExistingChunk: true, + }, - // hash.update(module.libIdent({ context: program.directory })) - - // return hash.digest(`hex`).substring(0, 8) - // }, - // priority: 30, - // minChunks: 1, - // reuseExistingChunk: true, - // }, - // commons: { - // name: `commons`, - // // if a chunk is used on all components we put it in commons (we need at least 2 components) - // minChunks: Math.max(componentsCount, 2), - // priority: 20, - // }, - // // If a chunk is used in at least 2 components we create a separate chunk - // shared: { - // test: module => !isCssModule(module), - // name(module, chunks) { - // const hash = crypto - // .createHash(`sha1`) - // .update(chunks.reduce((acc, chunk) => acc + chunk.name, ``)) - // .digest(`hex`) - - // return hash - // }, - // priority: 10, - // minChunks: 2, - // reuseExistingChunk: true, - // }, - - // // Bundle all css & lazy css into one stylesheet to make sure lazy components do not break - // // TODO make an exception for css-modules - // styles: { - // test(module) { - // return isCssModule(module) - // }, - - // name: `styles`, - // priority: 40, - // enforce: true, - // }, + // Bundle all css & lazy css into one stylesheet to make sure lazy components do not break + // TODO make an exception for css-modules + styles: { + test(module) { + return isCssModule(module) + }, + + name: `styles`, + priority: 40, + enforce: true, + }, }, // We load our pages async through async-requires, maxInitialRequests doesn't have an effect on chunks derived from page components. // By default webpack has set maxAsyncRequests to 6, in some cases this isn't enough an actually makes the bundle size blow up. diff --git a/packages/gatsby/src/utils/webpack/loaders/virtual.js b/packages/gatsby/src/utils/webpack/loaders/virtual.js index 3d8e97ee792ec..604a0c59dc574 100644 --- a/packages/gatsby/src/utils/webpack/loaders/virtual.js +++ b/packages/gatsby/src/utils/webpack/loaders/virtual.js @@ -1,7 +1,7 @@ const Template = require(`webpack/lib/Template`) -module.exports = async function virtual(source, sourceMap): string { - console.log({ options: this.getOptions() }) +module.exports = async function virtual(source, sourceMap) { + // console.log({ options: this.getOptions() }) const { modules } = this.getOptions() const requests = modules.split(`,`) @@ -10,7 +10,7 @@ module.exports = async function virtual(source, sourceMap): string { // Filter out css files on the server .map(request => { const chunkName = Template.toPath(request) - console.log({ chunkName }) + // console.log({ chunkName }) return `import(/* webpackChunkName: "${chunkName}" */ ${JSON.stringify( request @@ -31,7 +31,7 @@ module.exports = async function virtual(source, sourceMap): string { // requests: resolvedRequests, // } - console.log({ code }) + // console.log({ code }) return code } diff --git a/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts b/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts index 5c223276c2103..aea43b7d1f028 100644 --- a/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts +++ b/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts @@ -12,7 +12,10 @@ import webpack, { Compilation, Compiler, } from "webpack" +import ConcatenatedModule from "webpack/lib/optimize/ConcatenatedModule" import type Reporter from "gatsby-cli/lib/reporter" +import { store } from "../../../redux" +import { getRealPath } from "./static-query-mapper" interface IModuleExport { id: string @@ -91,6 +94,7 @@ export class PartialHydrationPlugin { const chunkGraph = compilation.chunkGraph const json: Record> = {} + const mapOriginalModuleToPotentiallyConcatanetedModule = new Map() // @see https://github.com/facebook/react/blob/3f70e68cea8d2ed0f53d35420105ae20e22ce428/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js#L220-L252 const recordModule = ( id: string, @@ -111,23 +115,27 @@ export class PartialHydrationPlugin { if (normalModule.modules) { normalModule.modules.forEach(mod => { + if (this._clientModules.has(mod)) { + const normalizedModuleKey = createNormalizedModuleKey( + mod.resource, + rootContext + ) + + if (normalizedModuleKey !== undefined) { + json[normalizedModuleKey] = moduleExports + } + } + }) + } else { + if (this._clientModules.has(normalModule)) { const normalizedModuleKey = createNormalizedModuleKey( - mod.resource, + normalModule.resource, rootContext ) if (normalizedModuleKey !== undefined) { json[normalizedModuleKey] = moduleExports } - }) - } else { - const normalizedModuleKey = createNormalizedModuleKey( - normalModule.resource, - rootContext - ) - - if (normalizedModuleKey !== undefined) { - json[normalizedModuleKey] = moduleExports } } } @@ -143,7 +151,7 @@ export class PartialHydrationPlugin { > > = new Map() - function stuff(module) { + function stuff(module): any { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const childMap = new Map() toRecord.set(module, childMap) @@ -183,12 +191,17 @@ export class PartialHydrationPlugin { ) as Iterable for (const mod of chunkModules) { if (mod.buildInfo.rsc) { + mapOriginalModuleToPotentiallyConcatanetedModule.set(mod, mod) newClientModules.add(mod) } if (mod.modules) { for (const subMod of mod.modules) { if (subMod.buildInfo.rsc) { + mapOriginalModuleToPotentiallyConcatanetedModule.set( + subMod, + mod + ) newClientModules.add(mod) } } @@ -215,7 +228,7 @@ export class PartialHydrationPlugin { } console.log({ toRecord }) - debugger + // debugger for (const [originalModule, resolvedMap] of toRecord) { for (const [resolvedModule, exports] of resolvedMap) { @@ -252,21 +265,22 @@ export class PartialHydrationPlugin { const clientSSRLoader = `gatsby/dist/utils/webpack/loaders/virtual?modules=${Array.from( this._clientModules ) - .map(module => { - console.log({ module }) - return module.userRequest - }) + .map( + module => + // console.log({ module }) + module.userRequest + ) .join(`,`)}!` // if (clientSSRLoader !== this._handledClientSSRLoader) { const clientComponentEntryDep = webpack.EntryPlugin.createDependency( clientSSRLoader, { - name: `rsc`, + name: `app`, } ) await this.addEntry(compilation, ``, clientComponentEntryDep, { - name: `rsc`, + name: `app`, }) } @@ -283,19 +297,20 @@ export class PartialHydrationPlugin { try { const oldEntry = compilation.entries.get(options.name) - console.log(`???`, { - entry, - options, - entries: compilation.entries, - cname: compilation.name, - }) + // console.log(`???`, { + // entry, + // options, + // entries: compilation.entries, + // cname: compilation.name, + // }) if (!oldEntry) { - return resolve(null) + resolve(null) + return } - const includeDependencies = oldEntry.includeDependencies + // const includeDependencies = oldEntry.includeDependencies - console.log({ includeDependencies }) + // console.log({ includeDependencies }) // if (!includeDependencies.has(e)) // @ts-ignore oldEntry.includeDependencies.push(entry) @@ -307,7 +322,7 @@ export class PartialHydrationPlugin { }, // @ts-ignore (err: Error | undefined, module: any) => { - console.log(`addModuleTree callback`, { err, module }) + // console.log(`addModuleTree callback`, { err, module }) if (err) { compilation.hooks.failedEntry.call(entry, options, err) return reject(err) @@ -347,9 +362,11 @@ export class PartialHydrationPlugin { }) compiler.hooks.finishMake.tapPromise(this.name, async compilation => { + if (compilation.compiler.parentCompilation) { + return + } console.log(`==== finish make ===`) await this.addClientModuleEntries(compiler, compilation) - return Promise.resolve() }) compiler.hooks.thisCompilation.tap( @@ -406,6 +423,71 @@ export class PartialHydrationPlugin { }) } + compilation.hooks.optimizeChunks.tap(this.name, () => { + const { components } = store.getState() + const realPathCache = new Map() + + compilation.modules.forEach(webpackModule => { + if (webpackModule.buildInfo.rsc) { + return + } + + for (const [id, component] of components) { + const componentComponentPath = getRealPath( + realPathCache, + component.componentPath + ) + + if (!(webpackModule instanceof ConcatenatedModule)) { + if ( + !( + (webpackModule as NormalModule).resource === + componentComponentPath + `?export=default` + ) + ) { + continue + } + } else { + // ConcatenatedModule is a collection of modules so we have to go deeper to actually get it + if ( + !webpackModule.modules.some( + innerModule => + (innerModule as NormalModule).resource === + componentComponentPath + `?export=default` + ) + ) { + continue + } + } + + const connections = + compilation.moduleGraph.getIncomingConnections(webpackModule) + for (const connection of connections) { + if (connection.dependency) { + compilation.moduleGraph.removeConnection( + connection.dependency + ) + } + } + + const chunks = webpackModule.chunksIterable + for (const chunk of chunks) { + console.log(`discconect`, { + name: chunk.name, + canBeInitial: chunk.canBeInitial(), + isOnlyInitial: chunk.isOnlyInitial(), + }) + + compilation.chunkGraph.disconnectChunk(chunk) + compilation.chunks.delete(chunk) + chunk.disconnectFromGroups() + } + + compilation.modules.delete(webpackModule) + } + }) + }) + // compilation.hooks.optimizeChunks.tap( // this.name, // // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/packages/gatsby/src/utils/webpack/plugins/static-query-mapper.ts b/packages/gatsby/src/utils/webpack/plugins/static-query-mapper.ts index d8cb63be39c98..088d06ab05e29 100644 --- a/packages/gatsby/src/utils/webpack/plugins/static-query-mapper.ts +++ b/packages/gatsby/src/utils/webpack/plugins/static-query-mapper.ts @@ -43,7 +43,7 @@ export const removeExportQueryParam = ( /** * Checks if a module matches a resourcePath */ -function doesModuleMatchResourcePath( +export function doesModuleMatchResourcePath( resourcePath: string, webpackModule: Module | NormalModule | ConcatenatedModule ): boolean { @@ -65,7 +65,7 @@ function doesModuleMatchResourcePath( /** * A helper to set/get path resolving */ -function getRealPath( +export function getRealPath( cache: Map, componentPath: string ): string { @@ -80,7 +80,7 @@ function getRealPath( * Grab the actual webpackModule from the resourcePath * We return staticQueries and componentPaths cause that's what we care about */ -function getWebpackModulesByResourcePaths( +export function getWebpackModulesByResourcePaths( modules: Set, staticQueries: IGatsbyState["staticQueryComponents"], components: IGatsbyState["components"], @@ -205,49 +205,104 @@ export class StaticQueryMapper { this.store.getState() compiler.hooks.done.tap(this.name, stats => { - const compilation = stats.compilation - // We only care about the main compilation - // Chunkgraph should always be available when it's done but you know typescript. - if (compilation.compiler.parentCompilation || !compilation.chunkGraph) { - return + // In dev mode we want to write page-data when compilation succeeds + if (!stats.hasErrors() && compiler.watchMode) { + enqueueFlush() } + }) - const staticQueriesByChunkGroup = new Map>() - const pageSliceUsageByChunkGroup = new Map< - ChunkGroup, - Record - >() - const chunkGroupsWithPageComponents = new Set() - const chunkGroupsByComponentPath = new Map< - IGatsbyPageComponent["componentPath"], - ChunkGroup - >() - - const { - webpackModulesByStaticQueryId, - webpackModulesByComponentId, - webpackModulesUsingSlices, - } = getWebpackModulesByResourcePaths( - compilation.modules, - staticQueryComponents, - components, - componentsUsingSlices - ) + compiler.hooks.thisCompilation.tap(this.name, compilation => { + compilation.hooks.afterChunks.tap(this.name, () => { + // console.log(`after chunks`) + // + // }) + // compiler.hooks.done.tap(this.name, stats => { + // const compilation = stats.compilation + // We only care about the main compilation + // Chunkgraph should always be available when it's done but you know typescript. + if (compilation.compiler.parentCompilation || !compilation.chunkGraph) { + return + } + // console.log(`after chunks2`) + + const staticQueriesByChunkGroup = new Map>() + const pageSliceUsageByChunkGroup = new Map< + ChunkGroup, + Record + >() + const chunkGroupsWithPageComponents = new Set() + const chunkGroupsByComponentPath = new Map< + IGatsbyPageComponent["componentPath"], + ChunkGroup + >() + + const { + webpackModulesByStaticQueryId, + webpackModulesByComponentId, + webpackModulesUsingSlices, + } = getWebpackModulesByResourcePaths( + compilation.modules, + staticQueryComponents, + components, + componentsUsingSlices + ) - const appEntryPoint = ( - compilation.entrypoints.has(`app`) - ? compilation.entrypoints.get(`app`) - : compilation.entrypoints.get(`commons`) - ) as EntryPoint + const appEntryPoint = ( + compilation.entrypoints.has(`app`) + ? compilation.entrypoints.get(`app`) + : compilation.entrypoints.get(`commons`) + ) as EntryPoint + + // group hashes by chunkGroup for ease of use + for (const [ + staticQueryId, + webpackModules, + ] of webpackModulesByStaticQueryId) { + let chunkGroupsDerivedFromEntrypoints: Array = [] + + for (const webpackModule of webpackModules) { + for (const chunk of compilation.chunkGraph.getModuleChunksIterable( + webpackModule + )) { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup === appEntryPoint) { + chunkGroupsDerivedFromEntrypoints.push(chunkGroup) + } else { + chunkGroupsDerivedFromEntrypoints = + chunkGroupsDerivedFromEntrypoints.concat( + getChunkGroupsDerivedFromEntrypoint( + chunkGroup, + appEntryPoint + ) + ) + } + } + } + } - // group hashes by chunkGroup for ease of use - for (const [ - staticQueryId, - webpackModules, - ] of webpackModulesByStaticQueryId) { - let chunkGroupsDerivedFromEntrypoints: Array = [] + // loop over all component chunkGroups or global ones + chunkGroupsDerivedFromEntrypoints.forEach(chunkGroup => { + const staticQueryHashes = + staticQueriesByChunkGroup.get(chunkGroup) ?? [] + + staticQueryHashes.push( + ( + staticQueryComponents.get( + staticQueryId + ) as IGatsbyStaticQueryComponents + ).hash + ) - for (const webpackModule of webpackModules) { + staticQueriesByChunkGroup.set(chunkGroup, staticQueryHashes) + }) + } + + // group Slice usage by chunkGroup for ease of use + for (const { + slices, + module: webpackModule, + } of webpackModulesUsingSlices) { + let chunkGroupsDerivedFromEntrypoints: Array = [] for (const chunk of compilation.chunkGraph.getModuleChunksIterable( webpackModule )) { @@ -265,201 +320,172 @@ export class StaticQueryMapper { } } } - } - // loop over all component chunkGroups or global ones - chunkGroupsDerivedFromEntrypoints.forEach(chunkGroup => { - const staticQueryHashes = - staticQueriesByChunkGroup.get(chunkGroup) ?? [] - - staticQueryHashes.push( - ( - staticQueryComponents.get( - staticQueryId - ) as IGatsbyStaticQueryComponents - ).hash - ) - - staticQueriesByChunkGroup.set(chunkGroup, staticQueryHashes) - }) - } + // loop over all component chunkGroups or global ones + chunkGroupsDerivedFromEntrypoints.forEach(chunkGroup => { + pageSliceUsageByChunkGroup.set( + chunkGroup, + mergePreviouslyCollectedSlices( + slices, + pageSliceUsageByChunkGroup.get(chunkGroup) + ) + ) + }) + } - // group Slice usage by chunkGroup for ease of use - for (const { - slices, - module: webpackModule, - } of webpackModulesUsingSlices) { - let chunkGroupsDerivedFromEntrypoints: Array = [] - for (const chunk of compilation.chunkGraph.getModuleChunksIterable( - webpackModule - )) { - for (const chunkGroup of chunk.groupsIterable) { - if (chunkGroup === appEntryPoint) { - chunkGroupsDerivedFromEntrypoints.push(chunkGroup) - } else { - chunkGroupsDerivedFromEntrypoints = - chunkGroupsDerivedFromEntrypoints.concat( - getChunkGroupsDerivedFromEntrypoint(chunkGroup, appEntryPoint) - ) + // group chunkGroups by componentPaths for ease of use + for (const [ + componentPath, + webpackModules, + ] of webpackModulesByComponentId) { + for (const webpackModule of webpackModules) { + for (const chunk of compilation.chunkGraph.getModuleChunksIterable( + webpackModule + )) { + for (const chunkGroup of chunk.groupsIterable) { + // When it's a direct import from app entrypoint (async-requires) we know we have the correct chunkGroup + if ( + chunkGroup.name === generateComponentChunkName(componentPath) + ) { + chunkGroupsWithPageComponents.add(chunkGroup) + chunkGroupsByComponentPath.set(componentPath, chunkGroup) + } + } } } } - // loop over all component chunkGroups or global ones - chunkGroupsDerivedFromEntrypoints.forEach(chunkGroup => { - pageSliceUsageByChunkGroup.set( - chunkGroup, - mergePreviouslyCollectedSlices( + let globalStaticQueries: Array = [] + for (const [ + chunkGroup, + staticQueryHashes, + ] of staticQueriesByChunkGroup) { + // When a chunkgroup is not part of a pageComponent we know it's part of a global group. + if (!chunkGroupsWithPageComponents.has(chunkGroup)) { + globalStaticQueries = globalStaticQueries.concat(staticQueryHashes) + } + } + + let globalSliceUsage: Record = {} + for (const [chunkGroup, slices] of pageSliceUsageByChunkGroup) { + if ( + !chunkGroupsWithPageComponents.has(chunkGroup) && + !chunkGroup.name?.endsWith(`head`) + ) { + globalSliceUsage = mergePreviouslyCollectedSlices( slices, - pageSliceUsageByChunkGroup.get(chunkGroup) + globalSliceUsage ) - ) - }) - } + } + } - // group chunkGroups by componentPaths for ease of use - for (const [ - componentPath, - webpackModules, - ] of webpackModulesByComponentId) { - for (const webpackModule of webpackModules) { - for (const chunk of compilation.chunkGraph.getModuleChunksIterable( - webpackModule - )) { - for (const chunkGroup of chunk.groupsIterable) { - // When it's a direct import from app entrypoint (async-requires) we know we have the correct chunkGroup - if ( - chunkGroup.name === generateComponentChunkName(componentPath) - ) { - chunkGroupsWithPageComponents.add(chunkGroup) - chunkGroupsByComponentPath.set(componentPath, chunkGroup) + components.forEach(component => { + const allStaticQueries = new Set(globalStaticQueries) + // we only add global slices to pages, not other slices + let allSlices: Record = component.isSlice + ? {} + : cloneDeep(globalSliceUsage) + + if (chunkGroupsByComponentPath.has(component.componentPath)) { + const chunkGroup = chunkGroupsByComponentPath.get( + component.componentPath + ) + if (chunkGroup) { + const staticQueriesForChunkGroup = + staticQueriesByChunkGroup.get(chunkGroup) + + if (staticQueriesForChunkGroup) { + staticQueriesForChunkGroup.forEach(staticQuery => { + allStaticQueries.add(staticQuery) + }) + } + + const slicesForChunkGroup = + pageSliceUsageByChunkGroup.get(chunkGroup) + + if (slicesForChunkGroup) { + allSlices = mergePreviouslyCollectedSlices( + slicesForChunkGroup, + allSlices + ) } } } - } - } - let globalStaticQueries: Array = [] - for (const [chunkGroup, staticQueryHashes] of staticQueriesByChunkGroup) { - // When a chunkgroup is not part of a pageComponent we know it's part of a global group. - if (!chunkGroupsWithPageComponents.has(chunkGroup)) { - globalStaticQueries = globalStaticQueries.concat(staticQueryHashes) - } - } - - let globalSliceUsage: Record = {} - for (const [chunkGroup, slices] of pageSliceUsageByChunkGroup) { - if ( - !chunkGroupsWithPageComponents.has(chunkGroup) && - !chunkGroup.name?.endsWith(`head`) - ) { - globalSliceUsage = mergePreviouslyCollectedSlices( + // modules, chunks, chunkgroups can all have not-deterministic orders so + // just sort array of static queries we produced to ensure final result is deterministic + const staticQueryHashes = Array.from(allStaticQueries).sort() + const slices = Object.keys(allSlices) + .sort() + .reduce((obj, key) => { + obj[key] = allSlices[key] + return obj + }, {}) + + console.log(`[static-query-mapper.ts]`, { + componentPath: component.componentPath, + staticQueryHashes, slices, - globalSliceUsage - ) - } - } + }) - components.forEach(component => { - const allStaticQueries = new Set(globalStaticQueries) - // we only add global slices to pages, not other slices - let allSlices: Record = component.isSlice - ? {} - : cloneDeep(globalSliceUsage) + const didStaticQueriesChange = !isEqual( + this.store + .getState() + .staticQueriesByTemplate.get(component.componentPath), + staticQueryHashes + ) - if (chunkGroupsByComponentPath.has(component.componentPath)) { - const chunkGroup = chunkGroupsByComponentPath.get( - component.componentPath + const didSlicesChange = !isEqual( + this.store.getState().slicesByTemplate.get(component.componentPath), + slices ) - if (chunkGroup) { - const staticQueriesForChunkGroup = - staticQueriesByChunkGroup.get(chunkGroup) - if (staticQueriesForChunkGroup) { - staticQueriesForChunkGroup.forEach(staticQuery => { - allStaticQueries.add(staticQuery) + if (didStaticQueriesChange || didSlicesChange) { + if (component.isSlice) { + this.store.dispatch({ + type: `ADD_PENDING_SLICE_TEMPLATE_DATA_WRITE`, + payload: { + componentPath: component.componentPath, + sliceNames: component.pages, + }, + }) + } else { + this.store.dispatch({ + type: `ADD_PENDING_TEMPLATE_DATA_WRITE`, + payload: { + componentPath: component.componentPath, + pages: component.pages, + }, }) - } - - const slicesForChunkGroup = - pageSliceUsageByChunkGroup.get(chunkGroup) - - if (slicesForChunkGroup) { - allSlices = mergePreviouslyCollectedSlices( - slicesForChunkGroup, - allSlices - ) } } - } - - // modules, chunks, chunkgroups can all have not-deterministic orders so - // just sort array of static queries we produced to ensure final result is deterministic - const staticQueryHashes = Array.from(allStaticQueries).sort() - const slices = Object.keys(allSlices) - .sort() - .reduce((obj, key) => { - obj[key] = allSlices[key] - return obj - }, {}) - - const didStaticQueriesChange = !isEqual( - this.store - .getState() - .staticQueriesByTemplate.get(component.componentPath), - staticQueryHashes - ) - - const didSlicesChange = !isEqual( - this.store.getState().slicesByTemplate.get(component.componentPath), - slices - ) - if (didStaticQueriesChange || didSlicesChange) { - if (component.isSlice) { + if (didSlicesChange) { this.store.dispatch({ - type: `ADD_PENDING_SLICE_TEMPLATE_DATA_WRITE`, + type: `SET_SLICES_BY_TEMPLATE`, payload: { componentPath: component.componentPath, - sliceNames: component.pages, + slices, }, }) - } else { + } + + if (didStaticQueriesChange) { this.store.dispatch({ - type: `ADD_PENDING_TEMPLATE_DATA_WRITE`, + type: `SET_STATIC_QUERIES_BY_TEMPLATE`, payload: { componentPath: component.componentPath, - pages: component.pages, + staticQueryHashes, }, }) } - } - - if (didSlicesChange) { - this.store.dispatch({ - type: `SET_SLICES_BY_TEMPLATE`, - payload: { - componentPath: component.componentPath, - slices, - }, - }) - } + }) - if (didStaticQueriesChange) { - this.store.dispatch({ - type: `SET_STATIC_QUERIES_BY_TEMPLATE`, - payload: { - componentPath: component.componentPath, - staticQueryHashes, - }, - }) - } + // // In dev mode we want to write page-data when compilation succeeds + // if (compiler.watchMode) { + // enqueueFlush() + // } }) - - // In dev mode we want to write page-data when compilation succeeds - if (!stats.hasErrors() && compiler.watchMode) { - enqueueFlush() - } }) } }