Skip to content

Commit

Permalink
refactor: use graph data to parse bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
LingyuCoder committed Jan 13, 2025
1 parent dbfb84c commit 0a33fb9
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 65 deletions.
8 changes: 5 additions & 3 deletions packages/core/src/build-utils/build/chunks/assetsModules.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Plugin } from '@rsdoctor/types';
import {
getAssetsModulesData as transform,
ParsedModuleSizeData,
} from '@/build-utils/common/chunks';
import { parseBundle } from '../utils';
import { SDK } from '@rsdoctor/types';

export async function getAssetsModulesData(
bundleStats: Plugin.StatsCompilation,
moduleGraph: SDK.ModuleGraphInstance,
chunkGraph: SDK.ChunkGraphInstance,
bundleDir: string,
hasParseBundle = true,
): Promise<ParsedModuleSizeData | null> {
return transform(
bundleStats,
moduleGraph,
chunkGraph,
bundleDir,
hasParseBundle ? { parseBundle } : {},
);
Expand Down
12 changes: 3 additions & 9 deletions packages/core/src/build-utils/build/utils/parseBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { filesize } from 'filesize';
import { parser } from '@rsdoctor/utils/ruleUtils';
import { extname } from 'path';

import { Plugin } from '@rsdoctor/types';
import { SDK } from '@rsdoctor/types';
import { ParseBundle } from '@/types';
import { debug } from '@rsdoctor/utils/logger';

Expand All @@ -22,7 +22,7 @@ import { debug } from '@rsdoctor/utils/logger';
// TODO: optimize type
export const parseBundle: ParseBundle = (
bundlePath: string,
modulesData: Plugin.StatsModule[],
modulesData: Pick<SDK.ModuleInstance, 'renderId' | 'webpackId'>[],
) => {
if (bundlePath.indexOf('.worker.') > 0) {
return {};
Expand Down Expand Up @@ -253,13 +253,7 @@ export const parseBundle: ParseBundle = (

const moduleContent = modules[module];
const size = moduleContent && Buffer.byteLength(moduleContent);
const _filterModules = find(modulesData, {
id: Number(module),
}) as Plugin.StatsModule;
const identifier =
_filterModules?.identifier ||
find(modulesData, { id: module })?.identifier ||
'';
const identifier = find(modulesData, { renderId: module })?.webpackId || '';
modulesObj[identifier] = {
size,
sizeConvert: filesize(size || 0),
Expand Down
48 changes: 11 additions & 37 deletions packages/core/src/build-utils/common/chunks/assetsModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { isEmpty, pick } from 'lodash';
import path from 'path';

import { logger } from '@rsdoctor/utils/logger';
import { Plugin, SDK } from '@rsdoctor/types';
import { SDK } from '@rsdoctor/types';
import { ParseBundle } from '@/types';
import { getModulesFromArray } from '../module-graph';

export type ParsedModuleSizeData = {
[x: string]: { size: number; sizeConvert: string; content: string };
Expand All @@ -19,57 +18,32 @@ export type ParsedModuleSizeData = {
* https://github.com/webpack-contrib/webpack-bundle-analyzer/blob/44bd8d0f9aa3b098e271af220096ea70cc44bc9e/LICENSE
*/
export async function getAssetsModulesData(
bundleStats: Plugin.StatsCompilation,
moduleGraph: SDK.ModuleGraphInstance,
chunkGraph: SDK.ChunkGraphInstance,
bundleDir: string,
opts: {
parseBundle?: ParseBundle;
},
): Promise<ParsedModuleSizeData | null> {
const { parseBundle = () => ({}) as ReturnType<ParseBundle> } = opts || {};

// Sometimes all the information is located in `children` array (e.g. problem in #10)
if (isEmpty(bundleStats.assets) && !isEmpty(bundleStats.children)) {
const { children } = bundleStats;
const _bundleStats = children?.[0];
if (!children) {
return {};
}
for (let i = 1; i < children.length; i++) {
children[i]?.assets?.forEach((asset: Plugin.StatsAsset) => {
_bundleStats?.assets?.push(asset);
});
}
} else if (!isEmpty(bundleStats.children)) {
// Sometimes if there are additional child chunks produced add them as child assets
bundleStats?.children?.forEach((child: Plugin.StatsCompilation) => {
child?.assets?.forEach((asset: Plugin.StatsAsset) => {
bundleStats?.assets?.push(asset);
});
});
}
const assets = chunkGraph.getAssets();
const modules = moduleGraph.getModules();

// Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
let bundlesSources: Record<string, unknown> | null = null;
let parsedModules: ParsedModuleSizeData | null = null;

if (bundleDir && bundleStats?.assets) {
if (bundleDir && assets.length) {
bundlesSources = {};
parsedModules = {};

for (const statAsset of bundleStats.assets) {
const assetFile = path.join(bundleDir, statAsset.name);
for (const asset of assets) {
const assetFile = path.join(bundleDir, asset.path);
let bundleInfo: ReturnType<ParseBundle>;
const collectedModules: Plugin.StatsModule[] = [];

getModulesFromArray(bundleStats.modules ?? [], collectedModules);

// Add childCompiler's stats.modules
const childrenModules: Plugin.StatsModule[] =
bundleStats.children?.flatMap((c) => c.modules || []) || [];
collectedModules.push(...childrenModules);

try {
bundleInfo = await parseBundle(assetFile, collectedModules);
console.log(modules);
bundleInfo = parseBundle(assetFile, modules);
} catch (err: any) {
const { code = '', message } = err;
const msg = code === 'ENOENT' ? 'no such file' : message;
Expand All @@ -79,7 +53,7 @@ export async function getAssetsModulesData(
continue;
}

bundlesSources[statAsset.name] = pick(bundleInfo, 'src', 'runtimeSrc');
bundlesSources[asset.path] = pick(bundleInfo, 'src', 'runtimeSrc');
Object.assign(parsedModules, bundleInfo?.modules || {});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export function getModuleGraphByStats(
getGetModuleName(root, data),
data.depth === 0,
isConcatenated ? SDK.ModuleKind.Concatenation : SDK.ModuleKind.Normal,
data.id ? String(data.id) : undefined,
data.layer!,
);

Expand Down Expand Up @@ -132,6 +133,7 @@ export function getModuleGraphByStats(
getGetModuleName(root, normal),
normal.depth === 0,
SDK.ModuleKind.Normal,
normal.id ? String(normal.id) : undefined,
normal.layer,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ export async function transStats(json: Plugin.StatsCompilation) {
);
const moduleGraph = ModuleGraph.getModuleGraphByStats(json, '.', chunkGraph);
const assetsModuleMap =
(await Chunks.getAssetsModulesData(json, json.outputPath || '', {})) || {};
(await Chunks.getAssetsModulesData(
moduleGraph,
chunkGraph,
json.outputPath || '',
{},
)) || {};
Chunks.transformAssetsModulesData(assetsModuleMap, moduleGraph);
return { chunkGraph, moduleGraph };
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ export const ensureModulesChunksGraphFn = (

/** transform modules graph */
const shouldParseBundle = _this.options.supports.parseBundle !== false;
await getModulesInfosByStats(
await getModulesInfos(
compiler,
statsJson,
_this.modulesGraph,
_this.chunkGraph,
shouldParseBundle,
);

Expand Down Expand Up @@ -127,10 +127,10 @@ export const ensureModulesChunksGraphFn = (
* @return {*}
* @memberof RsdoctorWebpackPlugin
*/
async function getModulesInfosByStats(
async function getModulesInfos(
compiler: Plugin.BaseCompiler,
stats: Plugin.StatsCompilation,
moduleGraph: SDK.ModuleGraphInstance,
chunkGraph: SDK.ChunkGraphInstance,
parseBundle: boolean,
) {
if (!moduleGraph) {
Expand All @@ -139,7 +139,8 @@ async function getModulesInfosByStats(
try {
const parsedModulesData =
(await ChunksBuildUtils.getAssetsModulesData(
stats,
moduleGraph,
chunkGraph,
compiler.outputPath,
parseBundle,
)) || {};
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/types/chunks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Plugin } from '@rsdoctor/types';
import { Plugin, SDK } from '@rsdoctor/types';

export type AssetsModules = {
label?: string;
Expand All @@ -8,7 +8,7 @@ export type AssetsModules = {

export type ParseBundle = (
assetFile: string,
modules: Plugin.StatsModule[],
modules: Pick<SDK.ModuleInstance, 'renderId' | 'webpackId'>[],
) => {
modules?: Record<string, any>;
src?: string;
Expand Down
18 changes: 10 additions & 8 deletions packages/core/tests/build/utils/parseBundle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'fs';
import os from 'os';
import { describe, it, expect } from 'vitest';
import { parseBundle } from '@/build-utils/build/utils/parseBundle';
import { SDK } from '@rsdoctor/types';

const BUNDLES_DIR = `${__dirname}/bundles`;

Expand All @@ -21,13 +22,13 @@ describe('parseBundle', function () {
it(`should parse ${lowerCase(bundleName)}`, function () {
const bundleFile = `${BUNDLES_DIR}/${bundleName}.js`;
const modules = [
{ id: 0, identifier: '0' },
{ id: 1, identifier: '1' },
{ id: 2, identifier: '2' },
{ id: 3, identifier: '33' },
{ id: 5, identifier: '5' },
{ id: 6, identifier: '6' },
{ id: '/x1Yz5', identifier: '/x1Yz5' },
{ renderId: '0', webpackId: '0' },
{ renderId: '1', webpackId: '1' },
{ renderId: '2', webpackId: '2' },
{ renderId: '3', webpackId: '33' },
{ renderId: '5', webpackId: '5' },
{ renderId: '6', webpackId: '6' },
{ renderId: '/x1Yz5', webpackId: '/x1Yz5' },
];
const bundle = parseBundle(bundleFile, modules);

Expand All @@ -37,7 +38,8 @@ describe('parseBundle', function () {
}),
);
expect(bundle.src).toEqual(fs.readFileSync(bundleFile, 'utf8'));
os.EOL === '\n' && expect(bundle.modules).toEqual(expectedModules.modules);
os.EOL === '\n' &&
expect(bundle.modules).toEqual(expectedModules.modules);
});
});
});
1 change: 1 addition & 0 deletions packages/graph/src/graph/module-graph/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class ModuleGraph implements SDK.ModuleGraphInstance {
item.path,
item.isEntry,
item.kind,
item.renderId,
item.layer,
);
(module as any).id = item.id;
Expand Down
5 changes: 5 additions & 0 deletions packages/graph/src/graph/module-graph/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class Module implements SDK.ModuleInstance {

readonly id: number;

readonly renderId: string | undefined;

readonly webpackId: string;

readonly path: string;
Expand Down Expand Up @@ -66,13 +68,15 @@ export class Module implements SDK.ModuleInstance {
path: string,
isEntry = false,
kind = SDK.ModuleKind.Normal,
renderId: string | undefined = undefined,
layer = '',
) {
this.id = id++;
this.webpackId = webpackId;
this.path = path;
this.isEntry = isEntry;
this.kind = kind;
this.renderId = renderId;
this.layer = layer;
}

Expand Down Expand Up @@ -316,6 +320,7 @@ export class Module implements SDK.ModuleInstance {
const moduleName = getModuleName(this.webpackId);
const data: SDK.ModuleData = {
id: this.id,
renderId: this.renderId,
webpackId:
contextPath && moduleName.indexOf('.') > 0
? path.relative(contextPath, moduleName)
Expand Down
2 changes: 2 additions & 0 deletions packages/types/src/sdk/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ export enum ToDataType {
export interface ModuleInstance {
/** Module identifier */
readonly id: number;
/** webpack render identifier */
readonly renderId?: string;
/** webpack identifier */
readonly webpackId: string;
/** Module path */
Expand Down

0 comments on commit 0a33fb9

Please # to comment.