This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.
Message originally sent by slack user U71N3KA8TMX
Hello, can anybody point me towards any resources or discussions about how packwerk interacts (or doesn’t) with Rails engines? My sense is that perhaps the consensus has moved away a bit from engines as the primary mechanism for modularity, but I wanted to test that sense. Thanks!
Hey Mark. Are you considering a refactor or for future development?
Packwerk is a dev environment tool that offers insight into the app’s modularity. In contrast, engines are for production, and they create hard boundaries and are much more than a tool for modularity.
When strictly considering modularity, I favor packwerk. It allows the team to work toward modularity in small steps and is a valuable tool that encourages and guides the team to respect boundaries.
By the way, every engine can be made a packwerk package.
By the way, every engine can be made a packwerk package.
Thanks for the plug, David!
And I have to echo your sentiment. Packages are superior for modularity work: Mainly it is because of the reduced overhead and the ability to act at the same strictness as engines (and more) but also to allow for more intermediate states.
For a while (after packages) I recommended using (unbuilt) engines if you think you’ll extract them as separate gems. While I don’t think that’s become untrue, there just aren’t a lot of situations people run into where they do this. If your real destination for such an engine is a separate Rails application…
Stick with packages, crank up all the protections over time, move it to a separate DB connection and then extract straight from package to app.
That’s an awesome approach that I expect to work well if you can keep the consistency and start like this. I should add as context to my comment: This is what I would say to folks who currently work in an existing largely non-design, ball-of-mud Rails app
I’m currently working mostly on a small Rails app, and occasionally on a medium/large Rails app. Neither app was greenfield when I joined the team. Both teams had read Stephan’s previous book (CBRA), and over break I read his new book as well, and that kind of forms the context for my question.
Both apps are currently segmented into engines and neither currently uses Packwerk. I know the small app better, and my sense after working with it for a while is that the engine boundaries may have been drawn somewhat prematurely, and this causes us development friction without providing a lot of benefits in terms of modularity. (This is my sense for the large app as well, for what it’s worth, but I don’t work in that codebase as often, so it’s more likely I am wrong in that case!)
Anyway, I’ve been toying with the idea of moving the smaller apps’ code out of engines and back into the root app, and then setting up Packwerk and looking to re-draw the package boundaries in a way that makes more sense for the current team and state of the application.
For the smaller application, I think it is very unlikely that any of the enginified-code will ever be extracted into a gem or a standalone application. The smaller application is itself already kind of an extracted specialist app.
I think the tricky part for us is that, for our large app, the codebase is big and mature enough that many changes are confined to one or at most two engines/gems, and so there is not a dev process cost to the modularity, even if the boundaries are not perfect
It is only in development and when we deploy it that it is an application (when it’s deployed, it is typically the only engine mounted, when it’s in development, we may mount additional engines that assist in development that would otherwise be “too” isolated).
Does this mean all communication between engines is over some non-Ruby mechanism (like http or redis or similar)? Even in development? One of the things I find odd about working with engines in these codebases is that I feel they are “mostly” just namespaces, and it feels like there are frequent cross-engine dependencies (although I have not felt like circular dependencies are a major problem)