Organize Your Metadata
Learning Objectives
- List the key strategies for organizing unpackaged metadata into packages.
- Identify how unlocked packages can be interdependent.
- Describe the 3 package development models, and when to use each.
Put the Principles of Package Development into Practice
Congratulations! In the prior unit, you created a package and installed the DreamHouse app in your Trailhead Playground. Now we’re going to show you how to put some of the key principles of package development into practice. Remember, it’s okay to start small and build upon your successes.
Organizing your metadata into packages:
- Is often an iterative process.
- Isn’t an all-or-nothing proposition.
Organize Metadata for a New or Existing Custom App
DreamHouse LWC is a great example of how to build a new app from the ground up and package it in an unlocked package so you can introduce the app in your org and manage future customizations. But you can also follow this same process when updating new features or functionality for an existing custom app.
To summarize, we created DreamHouse to show how to:
- Integrate the Salesforce CLI, projects, and unlocked packages into your application lifecycle.
- Adopt best practices on organizing metadata and creating package boundaries.
- Implement unlocked packages when you’re building a new app.
What can you do now that you’ve created an unlocked package for DreamHouse LWC?
- Test and deploy source for the application independently.
- Isolate the app schema (custom objects) from other metadata.
- Continue to make enhancements to the app by repeating the process and adding new features.
- Version the app.
- Install a second version as an upgrade to an existing version.
DreamHouse Metadata
Metadata | Description |
---|---|
Schema | Includes custom objects for Broker, Property, and Favorite. Examples: Broker__c, Property__c, Favorite__c |
Lightning applications and components | Explore properties and see property details. Examples: Property_Explorer.flexipage-meta.xml, Property_Record_Page.flexipage-meta.xml |
Processes (flows) | Send notifications when new properties are added, or the price has changed. Examples: Advertise_New_Property-2.flow-meta.xml, Price_Change_Push_Notification-1.flow-meta.xml |
Einstein services | Apply image processing to automatically discern home details from images that are uploaded. Example: EinsteinVisionController.cls |
Bots | Allow customers to engage via Facebook Messenger, Slack, or Alexa to search for properties. Example: HandlerFindProperties.cls |
Break Up Your Org’s Existing Metadata
As you can see, using the package development lifecycle for new projects makes a lot of sense. However, we know that existing customers, who have been using change set development over a period of releases or even years, are clamoring for guidance regarding where to begin. Just how do you untangle the contents of you org into separate projects, and ultimately package directories?
Although we’d love to give you the recipe to the secret sauce, there’s no one prescriptive action plan. How you approach breaking up the unpackaged metadata is one part science and one part art. You’re the best judge for determining which pieces of metadata fit into which Salesforce DX projects.
To get started, answer these questions:
- Would you like your development teams to be able to release apps, new features, and customizations independently?
- Can you identify metadata that represents an app?
- Can you organize your metadata into modules for distinct features?
- When you create an unmanaged package for this feature or app, what dependencies are you seeing?
If you have multiple apps and customizations in your org, expect to see some dependencies among Salesforce DX projects.
Three Models for Untangling Your Metadata
In real-life scenarios, you’re likely to adopt a combination of these strategies and tweak them to best suit your business needs.
Model | Description |
---|---|
App-based | Identify metadata that represents an app. This approach is similar to creating a package for the DreamHouse app with the exception that the metadata already exists in your org. |
Customizations-based | Organize unpackaged metadata for customizations and functionality changes in your production org, such as customizations to Sales Cloud, Service Cloud, or an AppExchange app. |
Shared library | When interdependencies exist, use a common Salesforce DX package to organize a set of Apex classes or commonly used custom objects. Other packages that you construct can depend on this common package. |
Use an Unmanaged Package as a Starting Point
Here’s a good starting workflow to organize your unmanaged metadata into multiple packages:
- Select a small set of unpackaged, self-contained metadata from your production org. Select metadata that represents an app, a customization to an existing app, a feature or functional unit, or customizations to standard objects.
- Create an unmanaged package to isolate the metadata you’ve identified from the overall collection of org metadata. As you add metadata to it, see which dependent metadata is automatically pulled in by the system. This step helps in unearthing some not-so-obvious dependencies among your metadata.
- Retrieve the source from your unmanaged package using project retrieve start.
- Set up a Salesforce DX project and a git repository to manage the package metadata.
- Push this metadata to a scratch org using project deploy start and validate that this is the metadata that you want to be part of an unlocked package.
- Create an unlocked package using the --no-namespace flag.
- Test and deploy the unlocked package.
- Once the unlocked package has passed all CI runs and UAT on sandboxes, promote the package version.
- Install the unlocked package in the production org.
Once you create a package for that metadata, it gets moved into the package automatically. Since the full name of the entity identifies the metadata in the org and in the package, we overwrite the metadata already in the org and update internal references to show that it is now contained by the package.
About Package Dependencies
A key value of unlocked packages is that you can develop and maintain a set of interdependent packages.
- An unlocked package can depend on an AppExchange package. If you are using an AppExchange package, you can put your own customization for that package in an unlocked package. When you install the unlocked package the AppExchange package must be present.
- An unlocked package can depend on another unlocked package. Let’s say you’re creating a new app that employees can use to submit expense reports. It shares some backend integration functionality with your existing Payroll app. In this scenario, the expense report unlocked package will depend on the Payroll app unlocked package.
- An unlocked package can depend on another unlocked package, and that unlocked package can, in turn, depend on a different unlocked package. Multiple levels of dependencies are supported.
You express dependencies in the packageDirectories section of the sfdx-project.json file. By supporting dependencies, unlocked packages promote modular development with a rich dependency framework. See the Salesforce DX Developer Guide for information on the project configuration file.