4

I have a managed package that is created from our "release org" to which the namespace has been assigned.

I have developed some Lightning components for use via Lightning Out in a Visualforce page. Whilst developing these components, all was well using the "c" placeholder namespace prefix. All was also well when adding these components to the managed package and uploading it.

However, when I install the package on an org and try to access the Visualforce pages that use these components, the pages fail to render completely (the parts of the page using the lightning components are missing) and shows a "server side error" message in the bottom left corner.

The Visualforce page uses pretty much the boilerplate 3 step integration:

  1. Add apex:includeLightning to the page
  2. Insert a placeholder element(s) for the component(s) in the page structure
  3. Use the Lightning App (referencing the key components) in the page and explicitly create the component(s) required

My dev org has this like:

<apex:page ...>
    <apex:includeLightning/>
    <script>
        $Lightning.use("c:myLightningApp", function() {
            $Lightning.createComponent("c:filter",
                {},
                "lightning",
                function(component) {
                });
        });
    </script>
    ...
    <div id="lightning"/>
    ...
</apex:page>

I find this works fine on the dev org (no namespace) and I can successfully deploy this to my release org (with namespace) where I build the package.

The issue is that the "c:" namespace prefix for the lightning app is not recognized on an org where the package is installed, so the page fails to load.

I have tried updating the component/app references on my dev org to use the namespace for my release org, but I cannot - the namespaces doesn't exist and so the updates cannot be deployed.

Without switching to SalesforceDX, can anyone suggest what I can do to enable me to build, package and install my lightning components so they will actually work in my dev org, my release org and in the package installed on a customer org?

  • By the way, I also have c: usages in the body of the component, since I have components that reference components. – Phil W Apr 3 '18 at 17:37
3

When using Salesforce DX, you register your namespace with the Dev Hub. From there, you can create Scratch Orgs that use the namespace by using the namespace attribute in your scratch org definition file. At this point, you will always use your namespace instead of c to reference your components.

  • Hi Brian, Thanks for the suggestion. As I mentioned at the end of the question, I'm trying to do this without switching to DX - this move is one we do intend to make but right now is too big a change for us. Of course, if there's no other option we might HAVE to make the leap... I know that a search/replace of "c:" with the correct namespace prefix before deploying to our release org makes everything work again, though I don't know of a way to automate this for the release org. Phil – Phil W Apr 4 '18 at 7:04
  • @PhilW ISVs have been struggling with the "namespace problem" ever since the introduction of the AppExchange late last decade. DX is the solution to this decade-old problem. I understand that it's a shift, and it takes effort to get there, but if you want to finally get out of the Dark Ages of Salesforce Development, DX is the way to go. Before this feature, there was no good way to migrate code between non-namespace orgs and the namespace org, find-replace was by far the most common tool we would use. – sfdcfox Apr 4 '18 at 10:30
1

Recently faced this problem as well, and what I did was to obtain the namespace from Apex and create the string with namespace+":lightningComponentName" and pass that to $Lightning.use().

The relevant part of the code is below.

myCustomVFPage.page

<apex:page showHeader="true" sidebar="true" standardController="CustomObject__c" extensions="NamespaceHelperControllerExtension">

<apex:includeLightning />
<div id="lexContainer" />

<script>
    let ns = "{!ns}";
    let appName = ns+":MyLightningApp";
    let componentName = ns+":MyLightning";

    let paramVal = '{!CustomObject__c.id}';
    let myUserContext = "{!$User.UITheme}";
    $Lightning.use(appName, function() {
    $Lightning.createComponent(componentName,
    {
        recordId : paramVal
    },
    "lexContainer",
        function(cmp) {
        });
    });
</script>


</apex:page>

NamespaceHelperControllerExtension.cls

public class NamespaceHelperControllerExtension {

    public sObject mysObject;
    public String ns {
        get{
            return NamespaceHelperControllerExtension.class.getName().substringBefore('NamespaceHelperControllerExtension').substringBefore('.');
        }
    }
    public NamespaceHelperControllerExtension(ApexPages.StandardController stdController) {
        this.mysObject = (sObject)stdController.getRecord();
    }

}

You can use this extension in all of the VF pages that require the namespace for the Lightning component.

0

In the end I wrote the code with namespace prefixes correct for the release org and relied on an IDE feature (I use IntelliJ IDEA with Illuminated Cloud) that allows remapping of the namespace. I simply then set a namespace on my dev org. When deploying, the IDE maps the release org namespace to my dev org's namespace.

Still not migrated to DX - but still very much on the wish-list!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.