Pedro Monjo’s reaction to my last post was to simply quote this bit: “Well, obviously, we build an Extension!”
My brain cannot stop thinking like that, and it’s all because I think encapsulating or hiding complexity behind a UI will help greatly in the long run.
I don’t even want to tell you how many of the things I have started writing so far. What you see on github is just part of it.
Anyway, during the last weeks and months, I have found out a couple of things that where not part of the “Make an Extension” mini-series.
In no particular order, here are 7 things I learned about making Extensions.
In the first installment, I suggested you should install a bunch of npm packages, namely I suggested to run:
npm -i --save-dev @adobe/reactor-scaffold @adobe/reactor-packager @adobe/reactor-uploader
In the update, I suggested you install none of those. You still definitely need all three, but you can run them without installing, like so:
The advantages of using
npx: no install needed, always uses latest version
The advantage of using
npm -i: faster, because no download needed every time you use a tool
So, now, I am using
npx for the scaffolder, since I only use it rarely, but I use
npm -i to install the packager once I’m that far in the development process, then start it locally.
I spend a lot of time on Swiss trains, and although there is 4G almost everywhere in Switzerland, downloading packager and uploader every time gets somewhat tedious.
But the use cases are limited. The only reason why you would use a main module would be if your Extension would inject something into all pages, no matter what.
You might say “cool! That’s just what I need! I want to inject some library everywhere”, but when you do it with a main module, you no longer have control over when your code is loaded and executed (always at library load time), nor can you use any Conditions to prevent it from loading.
Aaron also wrote about optimization through minimal inclusion, about how Launch only compiles those parts of code into the library that are actually needed. Keeping the library small is a good goal!
And so now I tend towards using
require, or even shared modules, as a better alternative, because both give me more control.
3. To scaffold, or not to scaffold?
Not to bore you to death with how I got there, so:
I only use the scaffolding tool once per Extension, namely when I first create it.
The only reason I do that is that I am too lazy to create the
extensions.json file by myself, and too sloppy to copy it from another Extension and actually change everything that has to be changed.
But once I’ve started working on the Extension, I almost always directly edit the file, rather than using the scaffolder. That includes when I decide to add an Action, Event, Condition, or Data Element Type.
It is just too simple to quickly go into the JSON and add what’s necessary.
4. Names and Numbers
This is a minor one, but even so.
At the very top of the
extension.json file, there are two entries that are usually made by the scaffolder: ‘name’ and ‘version’.
The ‘name’ attribute is unique across Launch!
When you create your Extension using the scaffolding tool, it’ll create a name for you based on the human-readable name you type in.
If you type “Constant Data Element” into the scaffolder, it’ll set the ‘name’ attribute to ‘constant-data-element’.
Please change the ‘name’ field!
It makes sense to prepend the generated name with something that is unique to you or your company.
As an example: a lot of my internal accounts start with “ags055”, and so that is what I now use for Extensions I write.
If your company builds an Extension (more below), you should preprend it, too. Call it “Useful Tools” as much as you like, the ‘name’ should be “acme-useful-tools”.
And on the versions: I used to increase it every time I uploaded. I stopped doing that.
There are guidelines for the version number format used by Extensions. It’s called Semantic Versioning, and it clearly defines when to increment which part of the version string.
The way I read it now is that I only increment when I release, i.e. not when I upload, but only when I run the script that makes it private or updates an existing Extension.
They also have a nice FAQ.
5. You should have (an) Extension(s)
If you are an Adobe customer, you should have an Extension. If you are a Consultant, Adobe or not, you should build an Extension for your customer.
Above and beyond my opinion that you should avoid custom code wherever possible, I also think that anyone develops their very own, specific, but supremely useful little tools, tricks, and gimmicks.
Those belong into an Extension.
Trust me on this one.
6. Make an upload script!
The most annoying part of making an Extension, right now, is the part where you upload it to Launch. At least if you follow some of the documentation (including my own article).
Apparently, that’ll change.
Until then, create an
upload.cmd file, and simply run that!
Here is what has to be inside that file.
#!/bin/sh npx @adobe/reactor-uploader --environment=production --private-key=/[PATH/TO/YOUR]/reactor_private.key --org-id=[YOUR ORG ID]@AdobeOrg --tech-account-id=[YOUR TECH ACCOUNT ID]@techacct.adobe.com --api-key=[YOUR API KEY] --client-secret=[YOUR CLIENT SECRET]
And for Windows:
@echo off npx @adobe/reactor-uploader --environment=production --private-key=/[PATH/TO/YOUR]/reactor_private.key --org-id=[YOUR ORG ID]@AdobeOrg --tech-account-id=[YOUR TECH ACCOUNT ID]@techacct.adobe.com --api-key=[YOUR API KEY] --client-secret=[YOUR CLIENT SECRET]
From now on, uploading a new version of your Extension is as simple as running
upload and choosing the latest zip file.
And yes: forward-slashes (
/) on Windows, too! Also:
~/ won’t work on Mac.
Alternatively, do what Aaron says.
But… isn’t all of that also available as part of the
Nope, not all of it!
And according to Aaron Hardy, you really should use
turbine in your Extension code.
As an example, the output from
turbine.logger.info is better than the output from
The output from
turbine.logger.info includes the Extension name, which obviously sparks joy.