Copy link to clipboard
Copied
Earlier this week, Bruce Bullis integrated a pull request into the CEP Samples repository that included a new Sample called TypeScript. TypeScript is a language that "transpiles" into JavaScript and JavaScript-based languages (e.g. ExtendScript). It can also be configured in certain environments (e.g. Visual Studio Code) to provide normal JavaScript (and, it turns out, ExtendScript) development with helpful type checking and IntelliSense/autocompletion support. Here's an example:
Open the PProPanel-vscode folder in Visual Studio Code (or other TypeScript-aware IDEs?), open up the Premiere.jsx file, and simply begin typing. The environment is already set up to provide rich IntelliSense support.
The environment has to get information about the types from somewhere, right? The type information is identified by the TypeScript system in the following ways:
Beyond this, TypeScript is capable of type inference (set var x = 5; and the IDE will infer that x is a number). For more on how TypeScript does all of this, see this document.
The declaration files included in the sample are currently incomplete, but Bruce Bullis has indicated interest in helping to fill in the blanks. These files are an improvement over the current documentation in that they can be [more] easily read on the web (don't need to be downloaded and opened in a browser) and also power in-line documentation and suggestions (as in the above gif)!
As configured, the sample does not actually assume that you will be writing in TypeScript and transpiling to JavaScript, but that you are simply writing JavaScript/ExtendScript. If you wish to use this feature, you will have to configure your IDE to do so (Visual Studio Code, Webstorm, Sublime Text, etc.).
It should also be noted that TypeScript can transpile from new JavaScript to old JavaScript. This may not seem all that interesting except that you could use the latest ES6 features to write code for both your panel JavaScript or your app ExtendScript. These would be transpiled into platform-compatible versions: target: "es5" for panel and target: "es3" for ExtendScript!
As with TypeScript, this use-case would require setting up the TypeScript compiler.
This sample also contains configuration settings to allow debugging of the panel (HTML) environment directly in Visual Studio Code, rather than through a Chrome browser. See:
Questions? Comments? Ask/post away!
Sturm359 wrote
For reference, I am using PHPStorm (since other projects I work on use Laravel and PHPStorm appears to handle front-end development just fine, I see no need to also purchase WebStorm).
If you haven't checked it out yet, I would highly recommend giving Visual Studio Code a test run. It is fully integrated with TypeScript out of the box and makes working with the language a breeze.
Sturm359 wrote
Since developing an Adobe CEP extension requires two separate JS environments
Technically
...Copy link to clipboard
Copied
Very interesting stuff! Thanks Bruce Bullis for the work and sberic for the announcement. Will definitely send feedback (or even submit a pull request) when working with this.
Copy link to clipboard
Copied
[All work = Eric]
Copy link to clipboard
Copied
I have created guide how to start using TypeScript with Adobe ExtendScript.
It works with Visual Studio Code too.
Copy link to clipboard
Copied
pqiorpa wrote
I have created guide how to start using TypeScript with Adobe ExtendScript.
It works with Visual Studio Code too.
Any thoughts on potentially integrating this into the Adobe CEP TypeScript example?
I see that you followed the naming convention used by the ExtendScript Toolkit (instead of "ExtendScript APIs" it's "JavaScript APIs"). Did you perhaps use a script to automate conversion of the XML documentation (installed with the toolkit) to TypeScript typings format?
Either way, I think it would be excellent to get these combined and added to the repo. The goal for the TypeScript example folder was always to expand it's contents beyond the minimal setup it's at now and into a full-fledged ExtendScript environment with proper per-application support (which it seems you've mostly nailed!).
One further question: are the "JavaScript" typings are feature-complete enough to cover all of the ECMAScript 3 intricacies or not? I notice that you have Object as a class. This is very different from the version provided in TypeScript for ECMAScript 5 (and 3, whenever it gets through review), where Object is an interface (for some important reasons).
Copy link to clipboard
Copied
Now the definition files are ECMAScript 3 compatible. I have converted Object and other core objects into interfaces.
Yes I had used convertor to convert XML documentation into TypeScript. You can find it here:
GitHub - pravdomil/extendscript-xml-to-typescript: ExtendScript XML documentation to TypeScript conv... https://github.com/pravdomil/extendscript-xml-to-typescript
About joining with Adobe-CEP example repo: I want to create separate repo for declaration files as it should be (check DefinitelyTyped).
Then you can use npm package manager from Node.js to install declaration files from my repository.
On top of that, npm will ensure that you have the latest version.
I updated readme file, there is now small guide how to create first script for Adobe Illustrator.
https://github.com/pravdomil/types-for-adobe/blob/master/README.md
BTW: is there any CreativeCloud plans for developers?
Copy link to clipboard
Copied
pqiorpa wrote
Now the definition files are ECMAScript 3 compatible. I have converted Object and other core objects into interfaces.
Awesome!
pqiorpa wrote
Yes I had used convertor to convert XML documentation into TypeScript. You can find it here:
GitHub - pravdomil/extendscript-xml-to-typescript: ExtendScript XML documentation to TypeScript conv... https://github.com/pravdomil/extendscript-xml-to-typescript
That's great! Thanks for sharing it!
pqiorpa wrote
About joining with Adobe-CEP example repo: I want to create separate repo for declaration files as it should be (check DefinitelyTyped).
Then you can use npm package manager from Node.js to install declaration files from my repository.
On top of that, npm will ensure that you have the latest version.
Hmm... I'd need to look into the requirements for contributing to DefinitelyTyped to speak more about this. One thing that I've discussed with Bruce Bullis is the need for keeping Adobe application version-specific typings available. As you're well aware, different versions of Adobe have different amounts of ExtendScript API support (typically they add more APIs). If you're working on a panel that you'd wish to be compatible back to a certain version, then it would be helpful to specify that version. Does your current setup allow for versioning that matches the Adobe application version? Any thoughts here?
Having the entire ExtendScript environment (JavaScript, app-specific libraries, extra features [e.g. ScriptUI], etc.) on npm such that a single well-configured package.json is all that's required for getting up and running with a panel dev-environment would be amazing.
pqiorpa wrote
BTW: is there any CreativeCloud plans for developers?
This would be more of a question for Bruce Bullis.
Copy link to clipboard
Copied
Now you can choose what version you want to use, check:
Any other versions can be easily added by converting xml documentation to index.d.ts with that convertor I mentioned.
Copy link to clipboard
Copied
pqiorpa wrote
Any other versions can be easily added by converting xml documentation to index.d.ts with that convertor I mentioned.
A few questions for you about this:
I've not published any typings to DT myself, though I've spent some time digging into it a bit to better understand the system. Does this all make sense? Would love to hear any insight you may have!
Thoughts?
Copy link to clipboard
Copied
Well, I have no more plans to publish those types into Definitely Typed. Instead I will keep it i my repo.
Copy link to clipboard
Copied
pqiorpa wrote
Well, I have no more plans to publish those types into Definitely Typed. Instead I will keep it i my repo.
Understood! Thanks for the contributions, regardless. Great work with this!
Perhaps Adobe themselves could pick up the ball and run with it. It would be a real nice way to enhance the development environment, especially given how ExtendScript Toolkit may no longer work on macOS once High Sierra ships... Bruce Bullis, any thoughts on this?
Copy link to clipboard
Copied
In response to:
Having the entire ExtendScript environment (JavaScript, app-specific libraries, extra features [e.g. ScriptUI], etc.) on npm such that a single well-configured package.json is all that's required for getting up and running with a panel dev-environment would be amazing.
This is my dream as well and I have been working on a bundler / packager with TypeScript support and Live Reload / HMR, for CEP and ScriptUI extensions.
Announcing Bundlers for CEP and ScriptUI extensions with live reload capabilities
I am also really glad that pqiorpa / pravdomil has created the typings for us, thanks a lot! it's really helpful!
Copy link to clipboard
Copied
Thank you very much for sharing your code.
I went through your code.
I'm new to TypeScript.
I have been developing CEP plugin about half year and got task to convert
semi-large CEP project (multiple Adobe apps support) to TypeScript.
Is there any sample CEP project does "transpiles" with multiple Adobe app support?
ex) alert(app.version)
Thank you,
Naoki
Copy link to clipboard
Copied
Naoki-Hada wrote
I'm new to TypeScript.
I have been developing CEP plugin about half year and got task to convert
semi-large CEP project (multiple Adobe apps support) to TypeScript.
That sounds like fun! Which apps do you specifically need to convert?
TypeScript is very easy configure for CEP development. You only need to set up a TypeScript context for each of the two separate script domains in the CEP environment:
In the tsconfig.json files you need to be aware of the lib and target options.
The lib option allows you to define the ECMAScript environment that your code will be running in. It tells TypeScript which ECMAScript (JavaScript/ExtendScript) functions are available. In the panel (HTML) side, you will have "es5" and some other options because the code is a web browser (Chrome/Chromium). In the app (ExtendScript) side, you will have "es5" because there currently is no option for "es3". Alternatively, you could use pqiorpa's setup with the noLib option instead of lib. Then you use the types option in the tsconfig.json file to specify which apps you want to support (his command line example sets this up).
The target option allows you to define which ECMAScript version the TypeScript compiler should output. For the panel (HTML) side, you should be okay with "es5" because the more recent versions of Chromium at the base of CEP extensions have support for most of those features. ExtendScript is based on ECMAScript 3 so the app (ExtendScript) side will use "es3".
This is how the sample project is setup. You can see those settings in the project here.
Naoki-Hada wrote
Is there any sample CEP project does "transpiles" with multiple Adobe app support?
ex) alert(app.version)
Not that I am aware of, no. It would not be hard with pqiorpa's types, though! You could either include all the typings (.d.ts files) within the Sample Premiere Pro project or simply combine the Sample Premiere Pro project with those typings and adjust the app-side tsconfig.json to use the specific types option. It shouldn't be difficult!
Copy link to clipboard
Copied
sberic,
Thank you very much for detail explanation.
I think I can do rocket start
The working CEP plugin is targeting Photoshop, Illustrator, InDesign and Premiere Pro.
As project became larger, it got more issues especially around CSInferface.evalScript().
I was using WebStorm for IDE.
I'll check with VS Code as well.
Thank you,
Naoki
Copy link to clipboard
Copied
Naoki-Hada wrote
The working CEP plugin is targeting Photoshop, Illustrator, InDesign and Premiere Pro.
As project became larger, it got more issues especially around CSInferface.evalScript().
Understood. The Premiere Pro typings were created by myself. You will want to mix those with the typings created by pqiorpa. The two were generated using different methods (the Premiere Pro ones were compiled manually from multiple sources, the others were automated). Please don't hesitate to ask questions if/when you run into issues with the environment!
Naoki-Hada wrote
I was using WebStorm for IDE.
I'll check with VS Code as well.
WebStorm has support for TypeScript so you could probably get it working there! One of the benefits of VSCode is that debugging of the HTML Panel code (at least) works within the IDE!
Copy link to clipboard
Copied
I'm only a beginner (CEP integration wise and TypeScript wise), there're some basics that I'm aware that I'm lacking.
My question is just to help me get started with TypeScript for the HTML layer and specifically to integrate UI libraries (like https://www.primefaces.org/primeng/#/ for angular environment).
Where is my new TypeScript code should be located and how do I instruct node.js to compile it with the third party libraries (NPM??)?
The sample provided has only .js files - are those the output javascript which generated after node compilation?
Copy link to clipboard
Copied
eyali.av wrote
The sample provided has only .js files - are those the output javascript which generated after node compilation?
The TypeScript Sample shows how you can use a TypeScript-enabled environment to enhance the CEP development experience. CEP development is primarily a JavaScript/ExtendScript-based affair. What the Sample does is sets everything up so that you get IntelliSense support and errors/warnings for JavaScript/ExtendScript files. All of the *.js files in the sample remain unchanged from the main PPro folder from which they were ported (at the time they were ported, at least).
As such, the TypeScript compiler is not actually used to compile/transpile any TypeScript code in the Sample. In fact, the only *.ts files in the sample are type declaration files (aka "typings"). These provide the TypeScript services with the information necessary to provide the type information to the environment!
eyali.av wrote
Where is my new TypeScript code should be located and how do I instruct node.js to compile it with the third party libraries (NPM??)?
I guess that it's possible to set up the CEP environment to transpile the TypeScript code to JavaScript inside the plugin, but you'd be doing a lot of work for very little, I think. Without understanding your goal (or very much about Angular+Primeng), I would suggest that you only write in TypeScript locally and "ship" your plugin as JavaScript. This would mean writing in TypeScript, committing a "build", and then ensuring that only the JavaScript files ended up in the final package. The JavaScript files (in concert with HTML/CSS) are what drive the UI anyway.
As an example, we have a Premiere Pro CEP project that is built using TypeScript for the HTML side (we currently still use TypeScript-service-assisted raw ExtendScript for the app side). The source files are a mixture of JavaScript files (libraries provided by Adobe, e.g. CSInterface.js) and TypeScript files (Vue components, our own libraries, etc.). We use webpack 2 to manage the TypeScript compilation and packaging of all relevant JavaScript into a single "bundle.js" file which is included by our very minimal index.html file. We instruct webpack to output a sourcemap which allows us to map the packaged "bundle.js" back to the original source files for debugging purposes (we use the same setup outlined in the sample).
In the end, our panel is driven by an 18-line HTML file and a 10,807-line JavaScript file (currently... this has not been minified; still contains comments, etc.).
I would very much suggest that you make use of static site. In the Angular documentation, they refer to this as AOT (Ahead Of Time compile). In your development environment (your local machine), you can use the latest NodeJS to grab and run development tools using npm. Keep in mind that the CEP Node implementation is very old (io.js 1.2.0, specifically) and does not include npm: it is a running context that provides you with access to the NodeJS API. It's not a Node development environment.
I hope this helps!
Copy link to clipboard
Copied
Thanks, sberic!
That put me on the right direction, I'll try to configure my environment (VS 2017) to bundle my angular project with AOT (as you suggested).
That's quite a challenge - I still struggle with the entire workflow that contains webpack from an AOT compilation - which are new concepts to me.
Hopefully, I'll report my progress here.
Copy link to clipboard
Copied
eyali.av wrote
That put me on the right direction, I'll try to configure my environment (VS 2017) to bundle my angular project with AOT (as you suggested).
That's quite a challenge - I still struggle with the entire workflow that contains webpack from an AOT compilation - which are new concepts to me.
Entirely understood. I've not built an Angular webapp myself, the Vue setup took us a few days to get right. Admittedly, it was our first time using lots of tools (TypeScript+Vue+webpack), so it was a learning experience all around. While there's not much I could add from here, I did find this resource which looks to have a useful Further Reading section. At the very least, I would suggest referring to the webpack 2.0 Configuration Documentation whenever you get stuck. It's the best source of clear and specific webpack information; one that we've referenced quite a bit.
eyali.av wrote
Hopefully, I'll report my progress here.
Please do! You're almost certainly not the only person interested in using Angular and/or webpack with TypeScript and CEP panels! Best of luck!
Copy link to clipboard
Copied
Thanks, sberic!
I took your advice, and used this resource (this is an 'Hello world' example) which demonstrate AOT usage and configuration.
It really helped in understanding ngc (this is an alternative compiler which works a lot like tsc and is suitable for the AOT approach) concept and also set-up the npm process (within a package.json file).
The one thing that I managed to change, and I believe can be useful for others is the ability to use a json file as a configuration for the client app (b.t.w - I only refer the HTML code in this reply) - and this can be used to configure settings which ce be changed in runtime for different users/stations. For example, I can set a URL for an API of some kind, of set a user name etc.
Copy link to clipboard
Copied
eyali.av wrote
The one thing that I managed to change, and I believe can be useful for others is the ability to use a json file as a configuration for the client app (b.t.w - I only refer the HTML code in this reply) - and this can be used to configure settings which ce be changed in runtime for different users/stations. For example, I can set a URL for an API of some kind, of set a user name etc.
That's fantastic! Great job getting it to work! Very glad to hear that you were able to get things working - and in a flexible manner as well!
Copy link to clipboard
Copied
Good day, everyone.
I have been working with ExtendScript since 2013 and the main projects I have at work are being called from a Java desktop app through AppleScript (so results can be written to a remote MySQL database). It's as hacky as can be, but that's what I came up with years ago.
I now find myself in a position where I really want to redo all of these projects. I need to convert them from very poorly-made, single-file, procedural, spaghetti-code AES JavaScript files to something more structured and easier to maintain in the future. To that end, I want to use TypeScript and leverage many of its benefits, including modules. And to get rid of the Java desktop launcher app, I think an Adobe CEP extension would be the best way to go (I hope).
Since developing an Adobe CEP extension requires two separate JS environments, I already have my project set up with two tsconfig.json files to handle transpiling to the correct ECMAScript versions for each. And since CEP doesn't seem to support CommonJS, I have the HTML Panel side set up to use SystemJS (0.21, as 2.0 has little documentation for newbies so far) in order to facilitate modules. And I'm using TypeScript's namespacing to use external modules on the AES side.
It works, even if it seems a bit kludgey. I can write TypeScript for both sides and have it all transpiled correctly on the fly. External modules work on both sides now (somewhat), so I can have classes in their own files, etc.
Is this the "correct" way to go about it, though? For reference, I am using PHPStorm (since other projects I work on use Laravel and PHPStorm appears to handle front-end development just fine, I see no need to also purchase WebStorm). SystemJS is a huge headache for a newbie like me—I cannot even seem to get node_modules to work correctly with it—and I sometimes find myself having to copy a module from the dom_app folder to the dom_html folder or vice-versa to get them to be referenced in each context; neither context seems to be able to reference a module from any directory higher than itself (I cannot do an import from "../../node_modules/<whatever>", for example). Also, I had to write my own cookie class because I could not get js-cookie to be imported with SystemJS.
I've tried Webpack before, and—maybe because I'm still a newbie with it, too—I couldn't get it to work right, either, thus the need for SystemJS (Since CEP doesn't like CommonJS). But SystemJS doesn't like Node.js, so I cannot use its built-in functions like "fs". I've heard of Mixed context, but after looking at it briefly, it seems more complicated than it's worth (unless I can be convinced otherwise) and, again, I'd run into how I could get that to work with TypeScript.
UGH, such a pickle! I've started with a relatively simple project—Just list some files from a user-chosen folder and have Illustrator open them. I absolutely would welcome any eyeballs to see if there's a better way to get it all working. If I should be creating a new thread to ask this, please let me know that, too. I guess I'm just looking for the "perfect" development environment that takes advantage of TypeScript, external modules, and Node.js' functions. Something relatively easy-to-follow would be ideal. Thank you.
Copy link to clipboard
Copied
Sturm359 wrote
For reference, I am using PHPStorm (since other projects I work on use Laravel and PHPStorm appears to handle front-end development just fine, I see no need to also purchase WebStorm).
If you haven't checked it out yet, I would highly recommend giving Visual Studio Code a test run. It is fully integrated with TypeScript out of the box and makes working with the language a breeze.
Sturm359 wrote
Since developing an Adobe CEP extension requires two separate JS environments
Technically speaking, Adobe CEP extension development involves three separate JS environments:
This is an incredibly important point and may affect how you organize your development strategy.
Sturm359 wrote
I already have my project set up with two tsconfig.json files to handle transpiling to the correct ECMAScript versions for each.
Please be very careful using TypeScript to transpile into ExtendScript. ExtendScript itself is effectively an abandoned language and has some serious language-level bugs in it. This Bug, for instance, causes transpiled Generator code to break when run in an ExtendScript Virtual Machine.
Rather, you should probably write ExtendScript natively. The TypeScript language services can still provide auto-completion, IntelliSense, warnings and error support, and more, provided the tsconfig.json (or jsconfig.json) file is configured properly.
That said, if you use fairly simple coding patterns, you are likely okay. I would suggest that you ensure that all of your code is properly tested if you do decide to transpile TypeScript to ExtendScript.
Sturm359 wrote
But SystemJS doesn't like Node.js, so I cannot use its built-in functions like "fs". I've heard of Mixed context, but after looking at it briefly, it seems more complicated than it's worth (unless I can be convinced otherwise) and, again, I'd run into how I could get that to work with TypeScript.
TypeScript works just fine with NodeJS. In our CEP panel we can import "fs" like this:
import * as fs from 'fs';
However, this approach absolutely requires enabling the Mixed Context. It may also require a webpack setup wherein you set the target to "node-webkit". The webpage you linked has quite a bit of information, but it is centered around another users' solution. I would highly recommend reading Adobe's Cookbook. This is the section on Node, which has some very important information in it. Please be sure to read the Mixed Context sub-section of that page. It should help convince you that it's not such a bad thing to use.
I should also note that the Cookbook I linked is specific to the most recent CEP9. For earlier versions, see this repo.
I'm not really sure what to say about CommonJS vs SystemJS, myself. I guess I don't really have an opinion. Our tsconfig.json uses "es2015" for the "module" setting, but that's in support of Vue.js and Webpack.
Does this help answer some of your questions?
Copy link to clipboard
Copied
Hey, sberic, thanks for responding. I hope you had a good weekend.
sberic wrote
If you haven't checked it out yet, I would highly recommend giving Visual Studio Code a test run. It is fully integrated with TypeScript out of the box and makes working with the language a breeze.
I have used VSCode in the past and I did, indeed, like it. However, I needed something more for working with Laravel projects, thus I purchased PHPStorm a while back and fell in love with its capabilities. It also handles TS out-of-the-box easily. Now, I wouldn't mind trying VSCode again, but I don't think the IDE is really the issue at hand, I think.
sberic wrote
Technically speaking, Adobe CEP extension development involves three separate JS environments:
Okay, this does make some sense, although I'll have some difficulty separating the Browser JS and Node JS in my head, I think.
sberic wrote
Please be very careful using TypeScript to transpile into ExtendScript. ExtendScript itself is effectively an abandoned language and has some serious language-level bugs in it.
The reason why I didn't really want to write ExtendScript (AES) natively is that I did so years ago and wound up with scripts that are thousands of lines long with spaghetti code all over the place. I have to maintain it and it becomes more and more difficult year after year. After having learned some OOP principles, it makes more sense for me to re-do those old scripts using those principles—classes, inheritance, etc. And if I can leverage external modules, then I can make the code perhaps a bit more modular as well as easier to maintain and build upon in the future. Would you think so?
I understand the inherent issues that could arise with transpiling to such an old language, however, I don't really plan on doing anything super-fancy. I only know the basics of OOP and don't plan on using all of the features of TypeScript. Heck, I don't even understand all of them. And you can bet that I'll be doing plenty of testing before deploying. (It's for our internal company's use only.)
sberic wrote
I'm not really sure what to say about CommonJS vs SystemJS, myself. I guess I don't really have an opinion. Our tsconfig.json uses "es2015" for the "module" setting, but that's in support of Vue.js and Webpack.
Now, to the crux of the matter. In order to use modules without SystemJS (because of its Node.js incompatibility), It seems that I would need to try Webpack again. Okay, I'm certainly willing to do so, but can you tell me how to set up the webpack.config.js file properly? Especially to handle both (or all three) JS contexts? Or maybe have it only handle the HTML Panel context while the JSX context only runs the TS compiler without Webpack? (Actually, that's a thought that I'll have to test…) I ask because, in my previous dealings with Webpack, it generates code that the ExtendScript VM doesn't handle. I'm not sure exactly where the problem is, but I do know it is probably in the comments. I've seen ExtendScript just give up when it encounters a // @ts-ignore directive, for example.
So, yes, you have helped to answer some of my questions. I'll try Webpack again, but see if I can only have it work on the Panel (JS) side.