arrow-left

All pages
gitbookPowered by GitBook
1 of 5

Loading...

Loading...

Loading...

Loading...

Loading...

Project Structure

hashtag
Introduction

hashtag
Packages as Projects

The codebase of the Salesforce org should be broken into multiple projects, this allows each unlocked package to be worked on independently.

hashtag
Package Structure

Project Configuration

Each unlocked package "project" needs to contain its own sfdx-project.json file which defines all the details about an unlocked package.

Project Details:

  • Filesystem Structure

  • SFDX Plugins

  • Namespaces

Loading Sequence

When you create a new scratch org, you need to install all of the dependencies into the scratch org first, then you push the data for the package. DX will recognize that it only needs to track the data of a certain package with the push/pull since the other data are part of other packages. This does require that the other packages are actually built into packages before working on this (using the force:package:version:create command).

If for example, you are a developer in , and you're working on for the project. Your Package2 could be dependent on , which is housed in a different , and controlled by a different developer.

hashtag
Configuring the sfdx-project.json File for Dependent Packages

You simply need to tell the Package2 that it depends on the Package1 in the file that defines the package2.

  1. Create Package2 in its project using sfdx:force:package:create command, and specify its path and settings assuming all of the code exists. List Package1 as a dependency.

  2. If you attempt to version, you'll get the following error: Package1 isn't defined in the sfdx-proect.json. Add it to the packageDirectories section and add the alias to packageAliases with its 0Ho ID.

  3. In the sfdx-project.json, create a Packagedirectory for Package1. Specify the path as a dummy path (such as force-app). Fill the versionName, and versionNumber fields with information found in step 2.

Even within a package, each programmer would create a branch of the VCS and then work on a section of code in their own scratch or. When they are ready, they can check the code in, and then merge it with any other changes (easier if each developer is working in different classes). The same thing applies to workflows, process builder, page layouts, etc. Create a branch, work in a scratch org, check in changes, merge, and repeat.

It's important to create a 'base' package that contains all of the things that will need to be shared across the other parts and the dependent packages on top of that(Package1). Each subsequent package would have its own repository. In the base package would be any custom objects that are needed and any custom fields for standard objects that relate to the widgets. Also, include permission sets that provide access to the data. Then you can build the Package2 and Package3 packages and define that they depend on the base package (since that is where the data is defined). In the Package2 and Package3, you would add any code, workflows, lightning applications, components, etc that are needed to provide service for widgets. This allows you to work on Package2 and Package3 independently and install/removed/update each in production as needed without working about stepping on each other's toes.

The great thing about Salesforce DX, is that packages are released independently, and are stored in the Org. Packages can be accessed and used by developers that don't have access to the source code.

hashtag
Parallel Development in Salesforce: A Modern Approach

hashtag
Resources

-- Valerie Belova

Package Errors

When working with package commands, it's not unlikely to run into errors and issues. Here is a compilation of common errors that may occur, along with solutions to those errors.

hashtag
Common Package Errors and Fixes

The package ID or Alias ID is invalid OR The subscriber version ID or package version ID isn't defined

  • The package version ids may be specific to a DevHub that does not allow them to be installed in another company's environments. This can happen on open source projects where the package IDs and version IDs are listed in the packageAliases section of open source SFDX projects

  • To fix this, you would need to remove all of the IDs of packages and versions you have not created, and re-package them for yourself. Add your own IDs to the local sfdx-project.json

"Package" isn't defined in the sfdx-project.json. Add it to the packagedirectories section and add the alias to packageAliases with its 0Ho ID.

  • Same problem as above. Your own DevHub doesn't recognize the packages that were created and versioned in another DevHub

It's possible that the package was created on a different Dev Hub. Authenticate to the Dev Hub org that owns the package, and reference that Dev Hub when running the command

  • Same as problems from above. You have to recreate all of the packages from your own DevHub, and reference those IDs only.

This Directory does not contain a valid Salesforce DX project

  • This happened if I tried to edit in a path that wasn't correct. Sometimes, when I opened a project, VSCode would open up the repo without the correct path. To fix this I just did "cd .\InsertFolderNameHere"

  • Always double check that you are working in the path where your SFDX project is located

Path must be a string, received null

  • It fixed itself when I edited the contents within the package directory folder, and then restarted VScode.I assume it's because a path is considered empty / doesn't have enough contents for a proper package.

Expected path

  • This error occurred when I tried to version a package, and the path I referred to was different than the path in the sfdx-project.json file. It has to be exactly the same. I refereed "./forceapp1" in my command, however, in the file, it was just "forceapp1" without the "./"

Package Root directory empty

  • This occurred when I created a package, and the folder for the package directory was empty. When I created an empty file inside of the directory and entered in a few random lines of cold, the error went away.

  • Navigate to your org's "Installed Packages" list, and find Package1. Jot down the versionName and versionNumber, and fill the those fields in the sfdx-project.json of Package1 Project.

  • Run sfdx:force:package:list to list all of the packages in your org from the CLI. Copy down the name, and '0Ho' ID of Package2, and enter it as a field in packageAliases.

  • You should now be able version your Package2 using sfdx:force:package:version:create with its dependencies linked to Package1.

  • Repo2arrow-up-right
    Package2arrow-up-right
    Package1arrow-up-right
    repoarrow-up-right
    sfdx-project.jsonarrow-up-right
    SFDX Package Development Model Trailarrow-up-right
    Package Dependency Visualization Toolarrow-up-right

    Introduction

    hashtag
    Introduction

    Unlocked Packages provide the ability to divide a Salesforce org into components that can be versioned and deployed independently. Unlocked packages include metadata (both code and configuration).

    Unlocked Packages enable "Source Code as the Source of Truth"

    There is a balance that needs to be defined between making package sizes small enough that changes can move quickly through the development process, but not so small that any change requires multiple packages to need to change.

    The following guidance details an approach to structure packages in a manner that best strikes this balance.

    hashtag
    Package Categorization

    Breaking up your "Happy Soup" The following provides guidance on how to organize the org into SFDX Packages:

    hashtag
    "Base" Packages

    Base packages can be thought of as holding custom objects and providing data that other packages may depend on. It's important to know that packages can have dependencies, so common functionality should be pushed downwards into these base packages to promote reuse.

    • Common interfaces

    • Standard Salesforce SObjects

    • object-level metadata

    hashtag
    Dependent Packages

    A package can be dependent on one or more packages. Normally, the more components you include in later packages, the more packages you would have to reference. For example, if you have a package whose code references 3 other packages, those would have to be listed as dependencies. In these types of packages, you can have components such as:

    • Apex Services

    • Shared Lightning Components

    • Custom Page Templates

    hashtag
    Package Decomposition

    hashtag
    Breaking Down Metadata Across Packages:

    • A group of related code and customization

    • Can be tested independently from other components in your org

    • Able to be released independently

    Things that don't work

    • Shared metadata

    • Shared Objects

    Note: Use dependencies instead, and reference back to the metadata and objects.

    For Questions and Collaboration:

    hashtag
    Resources

    Salesforce Trailhead:

    -- Valerie Belova

    UI Libraries (including common Lightning Components)
  • Custom objects

  • Page layouts

  • Custom list views

  • Custom or standard fields

  • Theme images
  • Tabs

  • Permission Sets

  • Source components can only live In one project at a time
  • Object-level metadata should be kept in a base class.

  • Make sure your base class doesn’t account for other shared metadata

  • You don’t have to break up data without a reason

  • If there are deeply intertwined dependencies, include those together.

  • If functionality would be useful to future apps or other parts of the org, maybe consider moving the metadata elsewhere

  • There is no objectively-right method for breaking up metadata

  • Very subjective, should match working styles of team

  • Chatter Pagearrow-up-right
    Quick Start: Unlocked Packagesarrow-up-right

    SFDX Package Development

    Creating Unlocked Packages

    hashtag
    Creating and Configuring Unlocked Package

    Managing packages in their sfdx-project.json file is a vital part of the development process. The process of involving dependencies, versioning, and installation can all become very confusing. This page breaks down the process in a digestible way, so that you can easily create, version, and install packages.

    Package Version Numbers:

    • NEXT: increment the build number to the next available for the package

    • LATEST: assign the latest version of the package

    Dependencies

    • By default, when referencing a certain Standard Object, field, or component type, you will generate a prerequisite dependency on your package

    Package Installation Key:

    • ensures the security of the metadata within the package. Authorized Users are then provided the key

    • Provide -k (installation key) when running sfdx force:package:version:create. This key must be supplied when installing the package in an org.

    • Installation keys can be changed by running sfdx force:package:version:update

    NameSpaces

    • Distinguishes your package and its contents from packages of other developers

    • Creating a "no namespace" package gives developers more control over how to organize and distribute parts of an application. Existing unpackaged metadata can be migrated only to an unlocked package with no namespace.

    hashtag
    Creating the Package

    Generate

    • sfdx force:package:create

    • Make sure you specify the -name, -packagetype, -path, and -description.

    • specify feature and org preferences for the metadata in your sfdx-project.json

    Release

    • sfdx force:package:version:create

    • Make sure you specify the -package, -installationkey, -wait, and any optional variables you wish to update

    • Use the "-b" flag to specify a build on a "logical branch". This flag allows you to keep experimental/development builds separate from the "main stream" builds that would be generated from your GIT MASTER branch

    Install

    • sfdx force:package:install

    • Make sure you specify the package version by running sfdx:force:package:version:list to find its 0Ho ID.

    • Install packages in order of dependencies

    hashtag
    Best Practices

    • Include the -tag option when you use the package:version:create and package:version:update commands. This option helps you keep your version-control system tags in sync with specific package versions.

    • Keep your sfdx-project.json populated with important information such as versions, name, build, aliases, etc. This is your source of truth for all packages.

    use -wait when creating package versions. This helps you avoid the process of having to run sfdx force:version:report:create in order to view your package's status.
  • Don't version every little feature or change. Your org has a maximum number of package commands you can run.

  • Avoid namespaces if you aren't accustomed to them

  • Specify PermissionSets within your packages

  • Refer to the when running sfdx commands

  • Refer to the when using Scratch Org

  • Adopt a robust .forceignore file to avoid pulling down unwanted metadata

  • Have developers religiously refer to the to avoid packaging metadata this is incompatible with packaging.

  • CLI Command Referencearrow-up-right
    Scratch Org and DevHub Referencearrow-up-right
    Metadata Coverage Reportarrow-up-right