rsnext/packages/next/build/webpack/plugins/build-stats-plugin.ts
Tim Neutkens 6387f368dc
Update reasons array to use module id instead of identifier (#21895)
Missed this then changing the modules array to rely on `module.id`
2021-02-05 16:39:46 +00:00

123 lines
3.2 KiB
TypeScript

import fs from 'fs'
import path from 'path'
// @ts-ignore no types package
import bfj from 'next/dist/compiled/bfj'
import { spans } from './profiling-plugin'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { tracer, traceAsyncFn } from '../../tracer'
const STATS_VERSION = 0
function reduceSize(stats: any) {
const modules = new Map()
stats.chunks = stats.chunks.map((chunk: any) => {
const reducedChunk: any = {
id: chunk.id,
files: chunk.files,
size: chunk.size,
}
for (const module of chunk.modules) {
if (!module.name) {
continue
}
const reducedModule: any = {
type: module.type,
moduleType: module.moduleType,
size: module.size,
name: module.name,
}
if (module.reasons) {
for (const reason of module.reasons) {
if (!reason.name) {
continue
}
if (!reducedModule.reasons) {
reducedModule.reasons = []
}
reducedModule.reasons.push({
id: reason.id,
})
}
}
modules.set(module.id, reducedModule)
if (!reducedChunk.modules) {
reducedChunk.modules = []
}
reducedChunk.modules.push(module.id)
}
return reducedChunk
})
stats.modules = [...modules.entries()]
for (const entrypointName in stats.entrypoints) {
delete stats.entrypoints[entrypointName].assets
}
return stats
}
// This plugin creates a stats.json for a build when enabled
export default class BuildStatsPlugin {
private distDir: string
constructor(options: { distDir: string }) {
this.distDir = options.distDir
}
apply(compiler: webpack.Compiler) {
compiler.hooks.done.tapAsync(
'NextJsBuildStats',
async (stats, callback) => {
tracer.withSpan(spans.get(compiler), async () => {
try {
const writeStatsSpan = tracer.startSpan('NextJsBuildStats')
await traceAsyncFn(writeStatsSpan, () => {
return new Promise((resolve, reject) => {
const statsJson = reduceSize(
stats.toJson({
all: false,
cached: true,
reasons: true,
entrypoints: true,
chunks: true,
errors: false,
warnings: false,
maxModules: Infinity,
chunkModules: true,
// @ts-ignore this option exists
ids: true,
})
)
const fileStream = fs.createWriteStream(
path.join(this.distDir, 'next-stats.json')
)
const jsonStream = bfj.streamify({
version: STATS_VERSION,
stats: statsJson,
})
jsonStream.pipe(fileStream)
jsonStream.on('error', reject)
fileStream.on('error', reject)
jsonStream.on('dataError', reject)
fileStream.on('close', resolve)
})
})
callback()
} catch (err) {
callback(err)
}
})
}
)
}
}