Vscode: [suggestion] Support for JavaScript Environments: Adobe ExtendScript

Created on 9 Jun 2017  路  15Comments  路  Source: microsoft/vscode

Per my conversion with vscode on twitter, I'll like to drop a request for/start a conversation around language support for Adobe ExtendScript.

The print industry (where I work) is incorporating more tech & automation, which often means scripting Adobe products like InDesign, Illustrator, & Photoshop. There is a dirth of support & tooling for Adobe's archaic version of javascript, ExtendScript, both from the community & Adobe itself. Right off the bat, their preferred .jsx extension gets confused with React/JSX.

Currently, the largest body of open source development in this space seems to be centered around this github org: https://github.com/ExtendScript/. Notable contributions from users like Fabian Mor贸n Zirfas & bastienEichenberger.

As someone just starting to dive in, I find Adobe's stock resources very difficult to consume. I've been hoping for a collection of official TypeScript typings for each environment so I could have intellisense autocompletion around the different environment globals and insight into the native object types. It's also very hard to go from writing esNEXT to the ExtendScript base of es3.

Does vscode have any language facilities for upgrading/downgrading a project/code window's referenced version of javascript? In other words, on a vscode window by window basis, can one switch from es2015 to es3? Or switch /.jsx?$/ environments from browser (ECMAscript), to server (Node), to some other document type (Adobe ExtendScript, Google Docs scripting, etc.)?

In my opinion, Adobe needs to take the first steps towards enabling good DX and modern tooling. Perhaps issues like this & toolmakers like Microsoft can inspire some conversation or even break contact with Adobe?

TL;DR;

  • Adobe ExtendScript is ancient. It's based on es3 and has entirely different globals
  • Can vscode do anything to make the ExtendScript authoring experience better?

    • Language environment switching for language version & env globals

    • TypeScript typings for intellisense

    • .jsx grammar (not React-style JSX)

  • Shot in the dark: can Microsoft use their voice to push Adobe to improve their automation tooling?
*extension-candidate feature-request javascript

Most helpful comment

I hope some good news comes out of that meeting! Tech is invading the world of print, so it's only a matter of time before voices like mine increase in volume (both in numbers and decibels).

The meeting went very well. They seem really interested in what TypeScript-enabled environments like VSCode can do for users working on extensions. To that end, they're even open to pull requests and it sounds as though they're interested in helping improve a base set of declaration files.

To be clear: I showed them an environment we'd set up with the hopes that they would be interested in supporting it as its _already_ proven to be extremely powerful/helpful, incomplete though it may be and they responded with "We'd be happy to help! Want to add it to the repo?"

I only just issued the Pull Request so it may be a little premature to celebrate, but I am cautiously optimistic.

Either way, some of those type declaration files and the project setup in the public Pull Request will probably be useful to someone ;)

All 15 comments

I'm not familiar with ExtendScript but I believe that we may already offer some functionality to support this. It sounds like there's also an opportunity for an ExtendScript extension for vscode.

How different is ExtendScript syntax from normal es3? If they are compatible, TypeScript should be able to provide intellisense for ExtendScript. If they are no compatible, unfortunately you'll probable have to write a custom language server that understands ExtendScript

For working with es3 code, TypeScript currently doesn't include typing definitions for the es3 standard library but there's an issue tracking this https://github.com/Microsoft/TypeScript/issues/2410 and a PR to add one: https://github.com/Microsoft/TypeScript/pull/16077 You can disable the standard es6 based suggestions by creating a jsconfig.json in the root of your project with the contents:

{
    "compilerOptions": {
        "target": "es3",
        "lib": []
    }
}

You can also include additional typings in your workspace using typeAcquision:

{
    "compilerOptions": {
        "target": "es3",
        "lib": []
    },
    "typeAcquisition": {
        "include": [
            "node"
        ]
    }
}

These typings come from definitely typed. If an es3 library d.ts exists, you should be able to include it using typeAcquisition.

You can also author your own d.ts files to improve intellisense for working with Adobe APIs: https://blogs.msdn.microsoft.com/typescript/2016/12/14/writing-dts-files-for-types/

My familiarity with ExtendScript is basically nil. I usually deal with es6, but I'm starting to work more closely with our company's adobe automation developer. I'm quickly learning that most of the language features I use on a daily basis are gone. The environment globals are very different. Found some good community documentation here: http://javascript-tools-guide.readthedocs.io/en/latest/index.html

I will definitely take a look at the guide to authoring d.ts files _(something I've been curious to get more into anyways)_, and I'll see how far I can get with understanding the language service in vscode. Do you have any links for starting down that path?

Yes, try seeing if the existing JS tooling will work with ExtendScript first. d.ts files and the right project configuration may provide most of what you are after. Writing a language server would be a pretty major investment and hopefully will not be necessary.

If ExtendScript augments JavaScript or just uses JavaScript patterns that our current tooling does not understand, you can also try looking into writing a typescript language service plugin: https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin

Here's our documentation on creating a language server: https://code.visualstudio.com/docs/extensions/example-language-server Before starting down this path, please let me know what problems you run into with our existing JavaScript support though

ExtendScript is basically ECMAScript 3rd Edition + API Extensions. See (emphasis mine):

Adobe provides an extended implementation of JavaScript, called ExtendScript, that is used by many Adobe applications that provide a scripting interface. In addition to implementing the JavaScript language according to the ECMA JavaScript specification, ExtendScript provides certain additional features and utilities.

As such, VSCode (powered by TypeScript) is _almost_ capable of handling the language with a few configuration changes. In fact, due to the nature of how TypeScript works with tsconfig.json files, you can set up an Adobe CEP Extension environment _within a single VSCode project window_. Let's tackle what's needed:

JSX Files Should Be Treated As JavaScript

This one's pretty easy. You can override the setting for .jsx files in the VSCode settings.json. See here for information on how to do this.

Core JavaScript API Support

While ExtendScript is based on ECMAScript 3, it is possible to "approximate" the experience by using the ECMAScript 5 typings. You'll get "type resolution" for a few APIs that wouldn't be supported. Unfortunately, at time of writing, the es5 typings are actually polluted with some typings from _es6_. While this will hopefully be addressed sometime in the near future, you should get the vast majority of what you need with the base es5 typings. To do that, you provide a tsconfig.json with the following settings:

{
    "compilerOptions": {
        "lib": [         // Specifying "lib" overwrites defaults (stops import of HTML DOM stuff).
            "es5"
        ],
        "target": "es3"  // In case TypeScript is used, this will compile to ECMAScript 3 (ExtendScript!) compatible code.
    }
}

Core ExtendScript API Support

This effectively requires a lib.extendscript.d.ts file. I have an active request with Adobe for them to support this directly as it would be extremely helpful. In the meanwhile, it is not difficult to create your own typings file by using the ExtendScript Toolkit's Object Model Viewer to get copy-pastable documentation for the ExtendScript APIs. I have done this with the base Helper class, myself, and it works great.

Adobe Application API Support

Each Adobe Application _also_ provides its own Application-specific ExtendScript APIs. They have varying degrees of documentation, mainly provided through samples, though _some_ provide other resources (e.g. Premiere Pro).

Here again I have an active request with Adobe for them to support this directly. Some documentation appears to be included with the ExtendScript Toolkit Object Model Viewer, but it tends to be incomplete. Support for files like PremierePro.2015.d.ts, PremierePro.2017.d.ts, AfterEffects.2017.d.ts, AfterEffects.2017.1.d.ts etc. would be _very_ welcome, but would best come from Adobe as certain APIs are simply undocumented outside of that company.

A Single Environment In VSCode That Supports CEP Development

Provided you have a "root" folder for each JavaScript context your CEP project, you can add "root"-specific tsconfig.json files to specify how you want the JavaScript types to be matched. This means that you can support the ExtendScript DOM in the same project as the HTML DOM used by the panel interface. To do this you would add one folder for each context, say: dom_app for ExtendScript and dom_html for the Panel. In dom_app/tsconfig.json you would add the settings shown above. For the dom_html/tsconfig.json, you would add settings akin to the following:

{
    "compilerOptions": {
        "lib": [        // This could probably be left out, but this way you can specify supported features.
            "dom",
            "es5",
            "es2015.promise"
        ],
       "target": "es5"  // Chrome 41 supports much of ECMAScript 5. However, this may need to be changed to ES3 to be safe.
    }
}

The "Chrome 41" note is related to the fact that recent versions of CEP (6.1 and 7.0) are based on nw.js 0.12.1, which incorporated a version of the Chromium Embedded Framework that equates to Chrome 41.

TL;DR

Quick responses to your [non MS-specific] bullet-list items:

Adobe ExtendScript is ancient. It's based on es3 and has entirely different globals

ExtendScript has _additional_ globals. Everything defined in the ECMA-262, 3rd Edition Standard is _also_ available in ExtendScript. The DOM is what differs - it's not the HTML DOM but the ExtendScript DOM.

Language environment switching for language version & env globals

Yes. This is outlined in detail above, but the basics are: set up a tsconfig.json file to only use the es5 typings (or [future] [es3](https://github.com/Microsoft/TypeScript/pull/16077)) and specify your own (or [future?] Adobe-provided) ExtendScript typings.

TypeScript typings for intellisense

This would be best handled by Adobe, but you could get a good deal of it done on your own with the help of the ExtendScript Toolkit's Object Model Viewer to provide the necessary documentation rundown.

.jsx grammar (not React-style JSX)

There are two additions to the ECMAScript 3 grammar:
1) Preprocessor Directives - There are functional workarounds for all three defined directives.
1) Operator Overloads - The syntax for this aligns with standard ECMAScript 3 syntax and therefore "just works".

Beyond these additions, ExtendScript grammar/syntax _is_ ECMAScript 3 grammar/syntax. As a result, you can just overwrite the default .jsx extension's language assignment in your project.

In summation, a good deal of what you're looking for is already doable with a bit of setup!

Thank you so much, @ericdrobinson!!! 馃帀 馃帀 馃帀 I'm helping my company's Adobe automation developer with his work, so I'm a bit of a middle-man here. I've been getting into using TypeScript more lately since I switched to using vscode (and code makes using TS a breeze).

There are a lot of really big config wins laid out here! I will check out the OMV (and that doc page you referenced was a huge help for me the other week鈥擜dobe's docs are not easily digested).

I would be supremely excited if Adobe released official typings of their scripting API's!!! Where can I put my ear to the ground for news on that?

I would be supremely excited if Adobe released official typings of their scripting API's!!! Where can I put my ear to the ground for news on that?

Honestly, I'm not 100% sure. I have a meeting with someone at Adobe about this very thing later today. I'll ask after this and see where the best place to get updates would be.

I've been getting into using TypeScript more lately since I switched to using vscode (and code makes using TS a breeze).

It sure does! If you're using TypeScript in your Adobe CEP projects, the more complete tsconfig.json files would look more like the following:

dom_app/tsconfig.json:

{
    "compilerOptions": {
        "allowJs": true,            // Allows JavaScript files to be compiled.
        "lib": [                    // Specifying "lib" overwrites defaults (stops import of HTML DOM stuff).
            "es5"
        ],
        "strict": true,             // Shorthand for the following four options:
        // "noImplicitAny": true,
        // "noImplicitThis": true,
        // "alwaysStrict": true,
        // "strictNullChecks": true,
        "target": "es3"             // In case TypeScript is used, this will compile to ECMAScript 3 (ExtendScript!) compatible code.
    }
}

dom_html/tsconfig.json:

{
    "compilerOptions": {
        "allowJs": true,            // Allows JavaScript files to be compiled.
        "lib": [                    // This could probably be left out, but this way you can specify supported features.
            "dom",
            "es5",
            "es2015.promise"
        ],
        "strict": true,             // Shorthand for the following four options:
        // "noImplicitAny": true,
        // "noImplicitThis": true,
        // "alwaysStrict": true,
        // "strictNullChecks": true,
        "target": "es5"             // Chrome 41 supports much of ECMAScript 5. However, this may need to be changed to ES3 to be safe.
    }
}

In addition, if you have certain scripts that you would like to use in both contexts, you can add a _third_ root directory called shared that sits next to dom_app and dom_html. You would place your .js or .ts files in there and add the following to _both_ tsconfig.json files:

{
    "compilerOptions": {
        // ...
    },
    "include": [                    // Custom include to get the shared folder.
        "./**/*",
        "../shared/**/*"
    ]
}

This is useful if you have some useful utility functions that you like to use everywhere.

Note that you will probably want to add a separate tsconfig.json file to the shared directory with the "lowest common denominator" of typings supported (read: es3 or es5). When actually compiling your shared TypeScript, the output generated for each "context" will match that specified in the tsconfig.json for that context (ExtendScript context would get compiled to ES3, HTML context would get compiled to ES5 [with the above settings]). TypeScript really is neat.

Oh. I should also point out that there's nothing-at-all sacred about the .jsx extension with ExtendScript. Adobe applications will _happily_ load your scripts with whatever extension you give them, including .js. If that's easier than setting up the custom file association (or you use JavaScript React in your project), then you can simply name your ExtendScript files *.jsx or even something like *.es/*.esx.

I hope some good news comes out of that meeting! Tech is invading the world of print, so it's only a matter of time before voices like mine increase in volume (both in numbers and decibels).

And I'm already using the plain .js extension (syntax highlighting and autocompletion is important!). I really like the idea of writing TS files with an es3 target though. I've been mentally attempting to keep track of all the polyfills I need when helping out with the scripting (as a newer developer, I'm a heavy user of es6 and beyond via build tooling).

I'm a heavy user of es6 and beyond via build tooling

If you're using Webpack, take a look at this post in the Adobe forums. Polyfills can really sneak up on you pretty easily with modern tooling!

Interesting. I've only used Webpack in a dev-for-web context, so I can see how I haven't run into this yet. This is a great heads up!

I've only used Webpack in a dev-for-web context

Adobe CEP extension development effectively _is_ web development. You just have a fixed browser target (Chrome 41 equivalent for recent versions).

I hope some good news comes out of that meeting! Tech is invading the world of print, so it's only a matter of time before voices like mine increase in volume (both in numbers and decibels).

The meeting went very well. They seem really interested in what TypeScript-enabled environments like VSCode can do for users working on extensions. To that end, they're even open to pull requests and it sounds as though they're interested in helping improve a base set of declaration files.

To be clear: I showed them an environment we'd set up with the hopes that they would be interested in supporting it as its _already_ proven to be extremely powerful/helpful, incomplete though it may be and they responded with "We'd be happy to help! Want to add it to the repo?"

I only just issued the Pull Request so it may be a little premature to celebrate, but I am cautiously optimistic.

Either way, some of those type declaration files and the project setup in the public Pull Request will probably be useful to someone ;)

That was fast... the PR was accepted and is now part of the CEP/Samples repository. Hopefully things will continue to improve along these lines!

This is awesome news! You're quite a few steps ahead of me with regards to development on the Adobe platform, but a base set of declaration files would really pave the way for developers like me to build. It's the ability to intelligently hack away versus laboriously study docs & slowly write code鈥攁nd that difference is huge to me.

Closing this out since support can be provided by an extension and would not be included in core VS Code

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lukehoban picture lukehoban  路  3Comments

vsccarl picture vsccarl  路  3Comments

villiv picture villiv  路  3Comments

mrkiley picture mrkiley  路  3Comments

biij5698 picture biij5698  路  3Comments