diff --git a/packages/sonda/src/bundlers/rspack.ts b/packages/sonda/src/bundlers/rspack.ts deleted file mode 100644 index fb7cd74..0000000 --- a/packages/sonda/src/bundlers/rspack.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { join } from 'path'; -import { normalizeOptions, normalizePath } from '../utils'; -import { generateReportFromAssets } from '../report/generate'; -import type { Compiler, StatsModule } from '@rspack/core'; -import type { Options, ModuleFormat, JsonReport } from '../types'; - -const jsRegexp = /\.[c|m]?[t|j]s[x]?$/; - -export class SondaRspackPlugin { - options: Partial; - - constructor ( options?: Partial ) { - this.options = options || {}; - } - - apply( compiler: Compiler ): void { - compiler.options.output.devtoolModuleFilenameTemplate = '[absolute-resource-path]'; - - compiler.hooks.afterEmit.tapPromise( 'SondaRspackPlugin', compilation => { - const inputs: JsonReport[ 'inputs' ] = {}; - const outputPath = compiler.options.output.path || compiler.outputPath || process.cwd(); - const stats = compilation.getStats().toJson( { modules: true } ); - - const modules = stats.modules - ?.filter( mod => !mod.codeGenerated ) - .filter( mod => mod.nameForCondition ) - || []; - - modules.forEach( module => { - const imports = modules.reduce( ( acc, { nameForCondition, issuerName, reasons } ) => { - if ( !nameForCondition ) { - return acc; - } - - if ( issuerName === module.name || reasons?.some( reason => reason.resolvedModule === module.name ) ) { - acc.push( normalizePath( nameForCondition ) ); - } - - return acc; - }, [] as Array ); - - inputs[ normalizePath( module.nameForCondition! ) ] = { - bytes: module.size, - format: getFormat( module ), - imports, - belongsTo: null - }; - } ); - - return generateReportFromAssets( - stats.assets?.map( asset => join( outputPath, asset.name ) ) || [], - inputs, - normalizeOptions( this.options ) - ); - } ); - } -} - -function getFormat( module: StatsModule ): ModuleFormat { - if ( !jsRegexp.test( module.nameForCondition! ) ) { - return 'unknown'; - } - - if ( module.moduleType === 'javascript/esm' ) { - return 'esm'; - } - - return 'cjs'; -} diff --git a/packages/sonda/src/bundlers/webpack.ts b/packages/sonda/src/bundlers/webpack.ts index 678ff1a..95eb718 100644 --- a/packages/sonda/src/bundlers/webpack.ts +++ b/packages/sonda/src/bundlers/webpack.ts @@ -1,78 +1,69 @@ import { join } from 'path'; import { normalizeOptions, normalizePath } from '../utils'; import { generateReportFromAssets } from '../report/generate'; +import type { Compiler, StatsModule } from 'webpack'; import type { Options, ModuleFormat, JsonReport } from '../types'; -import { NormalModule, type Compiler, type Module } from 'webpack'; const jsRegexp = /\.[c|m]?[t|j]s[x]?$/; export class SondaWebpackPlugin { options: Partial; - inputs: JsonReport[ 'inputs' ]; constructor ( options?: Partial ) { this.options = options || {}; - this.inputs = {}; } apply( compiler: Compiler ): void { compiler.options.output.devtoolModuleFilenameTemplate = '[absolute-resource-path]'; - compiler.hooks.compilation.tap( 'SondaWebpackPlugin', ( compilation ) => { - compilation.hooks.optimizeModules.tap( 'SondaWebpackPlugin', ( modules ) => { - Array - .from( modules ) - .forEach( module => { - if ( !isNormalModule( module ) ) { - return; - } + compiler.hooks.afterEmit.tapPromise( 'SondaWebpackPlugin', compilation => { + const inputs: JsonReport[ 'inputs' ] = {}; + const stats = compilation.getStats().toJson( { + modules: true, + providedExports: true + } ); - const imports = module.dependencies.reduce( ( acc, dependency ) => { - const module = compilation.moduleGraph.getModule( dependency ); + const outputPath = stats.outputPath || compiler.outputPath; + const modules = stats.modules?.filter( mod => mod.nameForCondition && mod.moduleType !== 'asset/inline' ) || []; - if ( isNormalModule( module ) ) { - acc.push( normalizePath( module.resource ) ); - } + modules.forEach( module => { + const imports = modules.reduce( ( acc, { nameForCondition, issuerName, reasons } ) => { + if ( issuerName === module.name || reasons?.some( reason => reason.resolvedModule === module.name ) ) { + acc.push( normalizePath( nameForCondition! ) ); + } - return acc; - }, [] as Array ); + return acc; + }, [] as Array ); - this.inputs[ normalizePath( module.resource ) ] = { - bytes: module.size(), - format: getFormat( module ), - imports, - belongsTo: null, - }; - } ); + inputs[ normalizePath( module.nameForCondition! ) ] = { + bytes: module.size || 0, + format: getFormat( module ), + imports, + belongsTo: null + }; } ); - } ); - compiler.hooks.emit.tapAsync( 'SondaWebpackPlugin', ( compilation, callback ) => { - const outputPath = compiler.options.output.path || compiler.outputPath || process.cwd(); - const assets = Object.keys( compilation.assets ).map( name => join( outputPath, name ) ); - - generateReportFromAssets( - assets, - this.inputs, + return generateReportFromAssets( + stats.assets?.map( asset => join( outputPath, asset.name ) ) || [], + inputs, normalizeOptions( this.options ) - ) - .then(() => callback()); + ); } ); } } -function getFormat( module: NormalModule ): ModuleFormat { - if ( !jsRegexp.test( module.resource ) ) { +function getFormat( module: StatsModule ): ModuleFormat { + if ( !jsRegexp.test( module.nameForCondition! ) ) { return 'unknown'; } - if ( module.type === 'javascript/esm' || module.buildMeta?.exportsType === 'namespace' ) { + if ( module.moduleType === 'javascript/esm' ) { return 'esm'; } - return 'cjs'; -} + if ( Array.isArray( module.providedExports ) && module.providedExports.length > 0 ) { + return 'esm'; + } -function isNormalModule( module: Module | NormalModule | null ): module is NormalModule { - return module !== null && 'resource' in module; + return 'cjs'; } diff --git a/packages/sonda/src/index.ts b/packages/sonda/src/index.ts index b1f632f..7ac7ef6 100644 --- a/packages/sonda/src/index.ts +++ b/packages/sonda/src/index.ts @@ -1,6 +1,5 @@ export { SondaEsbuildPlugin } from './bundlers/esbuild.js'; export { SondaRollupPlugin } from './bundlers/rollup.js'; -export { SondaRspackPlugin } from './bundlers/rspack.js'; export { SondaWebpackPlugin } from './bundlers/webpack.js'; export type { diff --git a/playground/rspack/rsbuild.config.mjs b/playground/rspack/rsbuild.config.mjs index f16ef01..c3be632 100644 --- a/playground/rspack/rsbuild.config.mjs +++ b/playground/rspack/rsbuild.config.mjs @@ -1,12 +1,12 @@ import { defineConfig } from '@rsbuild/core'; -import { SondaRspackPlugin } from 'sonda'; +import { SondaWebpackPlugin } from 'sonda'; export default defineConfig( { tools: { rspack: { devtool: 'source-map', plugins: [ - new SondaRspackPlugin( { + new SondaWebpackPlugin( { gzip: true, brotli: true, detailed: true