Loading...
Loading...
Analyze Rspack/Webpack bundles from local Rsdoctor build data without MCP. Zero-dependency JS CLI for chunk/module/package/loader insights.
npx skill4agent add rstackjs/agent-skills rsdoctor-analysisrsdoctor-data.jsoninstall@rsdoctor/rspack-plugin@rsdoctor/webpack-pluginpackage.jsonconfigrspack.config.jswebpack.config.jsrsbuild.config.tsmodern.config.tschunks listchunks by-idchunks largepackages listpackages by-namepackages dependenciespackages duplicatespackages similarmodules by-idmodules by-pathmodules issuermodules exportsmodules side-effectsassets listassets diffassets medialoaders hot-filesloaders directoriesbuild summarybuild entrypointsbuild configbundle optimizeerrors listerrors by-codeerrors by-levelrules listnode ${ROOT}/skills/rsdoctor/scripts/rsdoctor.js <group> <subcommand> [options]<group> <subcommand> [--option value] [--data-file <path>] [--compact]--data-file <path>--compact@rsdoctor/rspack-plugin >= 1.1.2@rsdoctor/webpack-plugin >= 1.1.2@rsdoctor/rspack-pluginpackage.jsondevDependencies@rsdoctor/webpack-pluginpackage.jsondevDependenciespnpm add @rsdoctor/rspack-plugin -Dpnpm add @rsdoctor/webpack-plugin -Drsdoctor-data.jsonrsdoctor-data.jsonrsdoctor-data.jsondist/rsdoctor-data.jsonoutput/rsdoctor-data.jsonstatic/rsdoctor-data.json.rsdoctor/rsdoctor-data.jsonrsdoctor-data.jsonpnpm add @rsdoctor/rspack-plugin -Dpnpm add @rsdoctor/webpack-plugin -D// rspack.config.js
const { RsdoctorRspackPlugin } = require('@rsdoctor/rspack-plugin');
module.exports = {
// ... existing config
plugins: [
// ... existing plugins
// Only register plugin when RSDOCTOR is true, as plugin will increase build time
process.env.RSDOCTOR &&
new RsdoctorRspackPlugin({
disableClientServer: true, // Must be true, otherwise local server will start and block LLM execution
output: {
mode: 'brief', // Required: Use brief mode
options: {
type: ['json'], // Must include 'json' to generate rsdoctor-data.json
},
},
}),
].filter(Boolean),
};// webpack.config.js
const { RsdoctorWebpackPlugin } = require('@rsdoctor/webpack-plugin');
module.exports = {
// ... existing config
plugins: [
// ... existing plugins
// Only register plugin when RSDOCTOR is true, as plugin will increase build time
process.env.RSDOCTOR &&
new RsdoctorWebpackPlugin({
disableClientServer: true, // Must be true, otherwise local server will start and block LLM execution
output: {
mode: 'brief', // Required: Use brief mode
options: {
type: ['json'], // Must include 'json' to generate rsdoctor-data.json
},
},
}),
].filter(Boolean),
};# Set RSDOCTOR environment variable and execute build
RSDOCTOR=true npm run build
# Or use pnpm
RSDOCTOR=true pnpm run build
# Or use yarn
RSDOCTOR=true yarn buildrsdoctor-data.jsondist/rsdoctor-data.jsonoutput/rsdoctor-data.jsonstatic/rsdoctor-data.json--data-file <path>rsdoctor-data.json# Analyze chunks
node scripts/rsdoctor.js chunks list --data-file ./dist/rsdoctor-data.json
# Analyze packages
node scripts/rsdoctor.js packages list --data-file ./dist/rsdoctor-data.json
# Compare asset differences between two rsdoctor data files
node scripts/rsdoctor.js assets diff --baseline ./dist/rsdoctor-data.json --current ./dist/rsdoctor-data-after.jsondist/node ${ROOT}/skills/rsdoctor/scripts/rsdoctor.js <group> <subcommand> [options] [--data-file <path>] [--compact]<group> <subcommand> [--option value]--data-file <path>--compact# View all chunks (calls listChunks() function)
node scripts/rsdoctor.js chunks list --data-file ./dist/rsdoctor-data.json
# View specific chunk details (calls getChunkById() function)
node scripts/rsdoctor.js chunks by-id --id 0 --data-file ./dist/rsdoctor-data.json
# Find module (calls getModuleByPath() function)
node scripts/rsdoctor.js modules by-path --path "src/index.tsx" --data-file ./dist/rsdoctor-data.json
# Analyze large chunks (calls findLargeChunks() function, finds chunks >30% over median and >= 1MB)
node scripts/rsdoctor.js chunks large --data-file ./dist/rsdoctor-data.json
# View duplicate packages (calls detectDuplicatePackages() function)
node scripts/rsdoctor.js packages duplicates --data-file ./dist/rsdoctor-data.json
# Comprehensive optimization recommendations (calls optimizeBundle() function)
node scripts/rsdoctor.js bundle optimize --data-file ./dist/rsdoctor-data.json
# Get build summary (build time analysis, calls getSummary() function)
node scripts/rsdoctor.js build summary --data-file ./dist/rsdoctor-data.json
# List all assets (calls listAssets() function)
node scripts/rsdoctor.js assets list --data-file ./dist/rsdoctor-data.json
# Get all errors and warnings (calls listErrors() function)
node scripts/rsdoctor.js errors list --data-file ./dist/rsdoctor-data.json
# Filter by error code (e.g., E1001 duplicate package error, calls getErrorsByCode() function)
node scripts/rsdoctor.js errors by-code --code E1001 --data-file ./dist/rsdoctor-data.json
# Get modules with side effects (cannot be tree-shaken, calls getSideEffects() function)
node scripts/rsdoctor.js modules side-effects --data-file ./dist/rsdoctor-data.json
# Get build configuration (calls getConfig() function)
node scripts/rsdoctor.js build config --data-file ./dist/rsdoctor-data.json<group> <subcommand> [options]modules by-path --path "<path>"getModuleByPath()modules by-id --id <id>getModuleById()<group> <subcommand>--data-file <path>chunks listlistChunks()--page-number <pageNumber>--page-size <pageSize># Default: return page 1, 100 items per page
node scripts/rsdoctor.js chunks list --data-file ./dist/rsdoctor-data.json
# Return page 2, 50 items per page
node scripts/rsdoctor.js chunks list --page-number 2 --page-size 50 --data-file ./dist/rsdoctor-data.jsonchunks by-id --id <n>getChunkById()chunks largefindLargeChunks()modules by-id --id <id>getModuleById()modules by-path --path "<path>"getModuleByPath()modules by-id --id <id>modules issuer --id <id>getModuleIssuerPath()modules exportsgetModuleExports()modules side-effectsgetSideEffects()module.bailoutReasonrsdoctor-data.jsonbailoutReasonrsdoctor-data.jsonbailoutReason"side effects""dynamic import""unknown exports""re-export"bailoutReason--page-number <pageNumber>--page-size <pageSize># Default: return page 1, 100 items per page
node scripts/rsdoctor.js modules side-effects --data-file ./dist/rsdoctor-data.json
# Return page 2, 200 items per page
node scripts/rsdoctor.js modules side-effects --page-number 2 --page-size 200 --data-file ./dist/rsdoctor-data.jsonpackages listlistPackages()packages by-name --name <pkg>getPackageByName()packages dependenciesgetPackageDependencies()--page-number <pageNumber>--page-size <pageSize># Default: return page 1, 100 items per page
node scripts/rsdoctor.js packages dependencies --data-file ./dist/rsdoctor-data.json
# Return page 2, 200 items per page
node scripts/rsdoctor.js packages dependencies --page-number 2 --page-size 200 --data-file ./dist/rsdoctor-data.jsonpackages duplicatesdetectDuplicatePackages()packages similardetectSimilarPackages()assets listlistAssets()assets diff --baseline <path> --current <path>diffAssets()assets mediagetMediaAssets()loaders hot-filesgetHotFiles()--page-number <pageNumber>--page-size <pageSize>--min-costs <minCosts># Default: return page 1, 100 items per page
node scripts/rsdoctor.js loaders hot-files --data-file ./dist/rsdoctor-data.json
# Return page 2, 50 items per page, and only show items with cost >= 100ms
node scripts/rsdoctor.js loaders hot-files --page-number 2 --page-size 50 --min-costs 100 --data-file ./dist/rsdoctor-data.jsonloaders directoriesgetDirectories()--page-number <pageNumber>--page-size <pageSize>--min-total-costs <minTotalCosts># Default: return page 1, 100 items per page
node scripts/rsdoctor.js loaders directories --data-file ./dist/rsdoctor-data.json
# Return page 1, 200 items per page, and only show directories with total cost >= 500ms
node scripts/rsdoctor.js loaders directories --page-size 200 --min-total-costs 500 --data-file ./dist/rsdoctor-data.jsonbuild summarygetSummary()build entrypointslistEntrypoints()build configgetConfig()bundle optimizeoptimizeBundle()--step <step>--side-effects-page-number <pageNumber>--side-effects-page-size <pageSize># Step 1: Execute basic analysis (duplicates/similar/media/large chunks)
node scripts/rsdoctor.js bundle optimize --step 1 --data-file ./dist/rsdoctor-data.json
# Step 2: Execute side effects modules analysis (paginated)
node scripts/rsdoctor.js bundle optimize --step 2 --side-effects-page-number 1 --side-effects-page-size 100 --data-file ./dist/rsdoctor-data.json
# Default: Execute all steps (backward compatible)
node scripts/rsdoctor.js bundle optimize --data-file ./dist/rsdoctor-data.jsonerrors listlistErrors()errors by-code --code <code>getErrorsByCode()errors by-level --level <level>getErrorsByLevel()rules listlistRules()server portgetPort()packages duplicatesdetectDuplicatePackages()packages similardetectSimilarPackages()assets mediagetMediaAssets()chunks largefindLargeChunks()modules side-effectsgetSideEffects()module.bailoutReasonrsdoctor-data.jsonbailoutReasonmoduleGraph.modulesrsdoctor-data.jsonbailoutReasonbailoutReason"side effects""dynamic import""unknown exports""re-export"rsdoctor-data.jsonbailoutReason--page-number <pageNumber>--page-size <pageSize># Default: return page 1, 100 items per page
node scripts/rsdoctor.js modules side-effects --data-file ./dist/rsdoctor-data.json
# Return page 2, 200 items per page
node scripts/rsdoctor.js modules side-effects --page-number 2 --page-size 200 --data-file ./dist/rsdoctor-data.jsonbundle optimizeoptimizeBundle()--compactinstallconfigconfig<group> <subcommand>modules side-effects<group>:<subcommand>modules:side-effectsmodules side-effectsgetSideEffects()bailoutReasonrsdoctor-data.jsonbailoutReasonmoduleGraph.modulesrsdoctor-data.jsonbailoutReason"side effects""dynamic import""unknown exports""re-export"bailoutReasonbailoutReason"side effects"bailoutReason"dynamic import"bailoutReason"unknown exports"rsdoctor-data.jsonbailoutReasonRSDOCTOR=truersdoctor-data.jsondist/output/static/--data-fileserver portgetPort()@rsdoctor/rspack-plugin@rsdoctor/webpack-pluginpnpm add @rsdoctor/rspack-plugin -Dpnpm add @rsdoctor/webpack-plugin -D@rsdoctor/rspack-plugin >= 1.1.2@rsdoctor/webpack-plugin >= 1.1.2assets mediagetMediaAssets()bundle optimizeoptimizeBundle()--compact--data-file--data-file <path><group> <subcommand>chunks list<group>:<subcommand>chunks:list