rspack icon indicating copy to clipboard operation
rspack copied to clipboard

[Feature]: Support circular-dependency-plugin

Open ska-kialo opened this issue 11 months ago • 12 comments

What problem does this feature solve?

While the optimizeModules hook was added in #2758 to support circular-dependency-plugin. The Module interface does not include the dependencies property the plugin uses to iterate through the dependencies of the module. Additionally the Compilation interface does not include the moduleGraph property the plugin uses.

What does the proposed API of configuration look like?

compilation.hooks.optimizeModules.tap('PluginName', (modules) => {
    const seenModules = {};
    for (const module of modules) {
        seenModules[module.debugId] = true;

        for (const dependency of module.dependencies) {
            if (
                dependency.constructor &&
                dependency.constructor.name === 'CommonJsSelfReferenceDependency'
            ) {
                continue;
            }

            const depModule = compilation.moduleGraph.getModule(dependency);

            // Check things on depModule
        }
    }
});

The plugin uses the following properties:

  • Module.dependencies: in Webpack this is an array of HarmonyImportSideEffectDependency
  • Module.debugId: a number
  • Compilation.moduleGraph.getModule(dependency: HarmonyImportSideEffectDependency): Module: a method on the module graph that resolves a dependency to its Module

ska-kialo avatar Mar 27 '24 17:03 ska-kialo

We're not intended to expose complex data structures like ModuleGraph, Dependency, ChunkGrpah, etc. You may port this plugin to Rust instead.

h-a-n-a avatar Apr 01 '24 04:04 h-a-n-a

this proved to be a very important plugin in webpack recently i faced a issue because of circular dependency which took lot of time will be good to have feature in rspack also

saifislamrepos avatar May 06 '24 05:05 saifislamrepos

this plugin can actually be implemented using stats.json,someone want to give it a try?

hardfist avatar May 06 '24 06:05 hardfist

I implemented a very basic version using the stats at https://github.com/kialo/rspack-circular-dependency-plugin.

For our use case it works, but note that the tests that came with the original plugin do not pass, as I haven't found the time to fix them yet. Therefore it also doesn't have an official release. I'm happy to take contributions.

ska-kialo avatar May 06 '24 08:05 ska-kialo

thanks @ska-kialo worked for me but was returning ids instead of readable names/path extracted modulesById[currentModule].name and resonModule.name working as expected now

saifislamrepos avatar May 06 '24 13:05 saifislamrepos

@saifislamrepos ah yes, I assume you're running in production mode? I hadn't considered that when implementing it.

ska-kialo avatar May 06 '24 14:05 ska-kialo

@ska-kialo yes as in production it takes moduleids as deterministic i guess

saifislamrepos avatar May 06 '24 15:05 saifislamrepos

this will cause performance issue for rspack and we suggest do this check in lint tools like eslint | biome

hardfist avatar Jul 12 '24 02:07 hardfist

I disagree with this choice. The bundler is what actually generates runtime code, and therefore, is the safest and most accurate place to check for cycles—which can cause crashes.

Additionally, how will it harm performance? Checking for cycles is O(V+E), so will scale ~roughly linearly in practice with the number of modules. If one throws a quick check after module resolution and before prod bundling, will that really take that much time?

I would ask that y'all reconsider this :) I think it would be valuable and can be done performantly.

stevenpetryk avatar Jul 15 '24 18:07 stevenpetryk

I disagree with this choice. The bundler is what actually generates runtime code, and therefore, is the safest and most accurate place to check for cycles—which can cause crashes.

Additionally, how will it harm performance? Checking for cycles is O(V+E), so will scale ~roughly linearly in practice with the number of modules. If one throws a quick check after module resolution and before prod bundling, will that really take that much time?

I would ask that y'all reconsider this :) I think it would be valuable and can be done performantly.

if it's implemented in rust side it could be done performantly, but if it need to be done in js side it will cause huge module graph communication which will hurt performance

hardfist avatar Jul 16 '24 03:07 hardfist

Ah, I see. I think the general question of "should we support cyclic dependency checking" is worth considering.

Would the rspack team be open to that being a feature of rspack, even though it is not one of webpack? Or would the recommendation be to build this as a rust-based plugin ourselves? (For more clarity: we at Discord really want cycle checking).

stevenpetryk avatar Jul 16 '24 18:07 stevenpetryk

we will reconsider what is the best way to do it

hardfist avatar Jul 23 '24 09:07 hardfist