Top 10 Latvia-Based Software Development Companies
Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.
Humans find it difficult to see the big picture of a problem without devoting a lot of time and effort. This happens especially while working with large and complex applications. What are the side effects of my changes? Why is this line here affecting the tests of a remote part of the codebase? A perfect or complete solution does not exist, but Shopify came out with a tool that will probably help you and your team.
In order to talk about Packwerk, we need to introduce a few concepts first.
As we know, Ruby doesn’t provide a good solution to enforce code boundaries. We can specify the visibility but all the dependencies will be loaded into the global namespace. In large or monolith applications, this lack of boundaries produces the following problems.
In an attempt to modularize Shopify’s monolith and enforce boundaries, they tried different solutions without achieving the expected results:
– Setting private constants,
– Establishing boundaries through gems,
– Using tests to prevent cross-component associations,
– Using Ruby‘s Modulation gem,
– Creating microservices.
With all the knowledge from previous attempts, they decided to create their own tool: Packwerk.
Packwerk is a static analysis tool used to enforce boundaries between groups of Ruby files called packages.
A package is a folder containing autoloaded code. Shopify’s team encourages to use the best design practices while creating packages.
– We should pack together things that have high functional cohesion,
We can enforce privacy and dependency boundaries, check violations of the boundaries and cyclic dependencies.
There is not a single specific way to structure or re-structure your application while creating packages. In this article, we are going to follow the approach suggested by
Stephan Hagemann in Gradual Modularization for Ruby on Rails.
You can create a new project or choose one of your projects. I decided to use an open-source project called CodeTriage. It is important to mention that we need a Rails 6 application since Packwerk uses Zeitwerk.
First, we need to add the gem to our Gemfile like gem 'packwerk'
and then run bundle
in the console. Then we are ready to initialize the gem running packwerk init
.
After that, we notice that Packwerk generated three files for us:
packwerk.yml
package.yml
inflections.yml
packwerk.yml is the configuration file of Packwerk where we will define included and excluded files, list the load paths, define the inflections file, among other things;
package.yml is the configuration file of a package. In this file, we will add the configuration for the boundaries of our package. Any folder with package.yml will be recognized as a package by Packwerk. That’s it, Packwerk created our first
package and we call it the root package.
inflections.yml is where we will place our custom inflections and acronyms in case we are using them.
You can find more about the files and their configuration in
Packwerk.
For modularization to work we need three basic properties: a named container, its content, and explicit dependencies on other containers. So let’s define those properties in Packwerk:
Name: The name of a package is its relative path from the root of the
application.
Content: When we place a package.yml into a folder, all the files in the folder are now the content of the package.
Dependencies: We can define dependencies on other packages adding dependencies key to the package.yml.
Another file that’s not included by default but is recommended is README. It is important to provide information about the usage of the package.
The End of Episode I
Read More
GraphQL Ruby. What about performance?