Swift Package Manager Series 02|Create the first Swift Package
What really matters is that for the first time, you organize your code by module boundaries rather than by folder thinking.
Many tutorials that talk about “creating your first Swift Package” focus on commands or Xcode actions.
Of course, these steps need to be known. But if you only know how to click “New Package”, you have actually only learned to “generate a template”, and you have not really understood the engineering significance of creating a Package.
Because it was the first time I created my own Swift Package, what really started to change was the way I thought about it:
- Is this code worthy of being separated into a module? -What interface should this module expose?
- Which implementation details should be hidden
- Who does it depend on and who should be relied on?
So what I want to talk about in this article is what judgments should be taken when creating a Package for the first time.
1. Don’t rush to build the Package first. First ask whether this code should continue to stay in the main project.
This is the step I care about most.
A common situation is to say: “Let’s modularize it.” But what’s really worth asking is:
Why should this code be separated from the current project context and become an independent module?
Common legitimate reasons include:
- It will be reused by multiple targets or multiple business modules
- It has formed a relatively stable field capability
- It should no longer depend on page or host project details
- It deserves separate testing boundaries
If you can’t name any of these reasons and just “feel like there are too many files”, it’s probably not time to build a package yet.
Package is not used to store files, it is used to express boundaries.
2. The most suitable thing to extract for the first time is usually small abilities with clear boundaries.
If a team is new to SPM, I usually don’t recommend tearing it down as the first step:
- Entire home page
- Entire account system
- Entire payment module
Because these modules are often deeply coupled with the host project, page layer, routing layer, and state layer, once the boundaries are not clearly designed, the first split will be easily frustrated.
Those that are more suitable for the first batch of Packages usually have these capabilities:
-Basic capabilities of the network layer
- Logging, monitoring, and hidden point packaging
- Image processing or caching tools
- A clear domain model library
- A set of relatively stable UI basic components
The common features of these modules are:
- Less dependence
- Single responsibility
- The boundaries are relatively clear
They are more suitable for helping the team establish a sense of “what is an independent module”.
3. When creating a Package for the first time, the most critical thing is the public interface
A common situation is that after building the first Package, you will immediately focus on how to arrange the directory. But from an engineering perspective, what’s really more important is:
- What does the module expose to the outside world?
- What is kept inside the module
You can think of creating a Package as a self-restraint:
- Which types are really worth exposing as
public - Which utility functions should only stay internal
- Which dependencies should not be known to the caller
If you just move everything in the original main project into one Package and then change it to public, then it will not really form a boundary.
Therefore, when making a Package for the first time, the most worthwhile practice is “defining the interface”.
4. One of the most common misunderstandings: Build the package first, then think about module responsibilities
It’s easy to go wrong with this sequence.
The correct order should usually be:
- First clarify the responsibilities of this ability
- Let’s see if it’s worthy of being an independent module.
- Finally host it in Package form
If the order is reversed, common consequences are:
- A Package wants to take care of everything
- Internal dependency confusion
- External interface is too large
- The host project still needs to know many implementation details
In other words, SPM cannot do module design for the team, it is just more suitable for carrying modules that have been clearly thought out.
5. The four issues I care about most when creating a Package for the first time
If I’m reviewing a team’s first package, the four questions I most often ask are:
1. Does this module have a clear single responsibility?
If a module handles network, cache, page status, and buried points at the same time, it’s probably not clear yet.
2. Whether its dependencies are few enough
When making a Package for the first time, the fewer dependencies, the easier it is to succeed. If there are too many dependencies, the boundaries will become blurred.
3. Is its public interface much smaller than its internal implementation?
If there are ten types in the module, eight of them will be exposed, indicating that the boundary control is not good enough.
4. Is it worth having independent testing?
Modules that are worthy of independent testing are usually more worthy of independent existence. If you can’t figure out how to test it in isolation, it’s probably still too tightly tied to the host context.
6. The criterion for success for the first time is “stable disassembly”
When many teams do modularization for the first time, they are most likely to pursue a “sense of results”, such as:
- Remove 10 modules in one go
- All public code goes into Package
- The main project lost a lot of weight immediately
But in real projects, the more important criteria for first-time success are usually:
- Have a module with clear boundaries
- External dependencies are healthy
- The team understands why it was split like this
- It didn’t come back quickly in the next few iterations
Because the biggest fear of modularity is that everyone’s confidence in this matter will be lost in the first step.
7. Conclusion: The first Swift Package truly teaches how to organize code according to boundaries.
To put it in shorter form, I would say:
The real meaning of creating the first Swift Package is to be forced to seriously answer for the first time “why this code deserves to be a standalone module”.
Once you start to look at the problem from this perspective, SPM is no longer just “can I use it”, but begins to truly enter the entrance to modular engineering thinking.
读完之后,下一步看什么
如果还想继续了解,可以从下面几个方向接着读。