Skip to main content
Inspiring
August 15, 2022
Answered

Illustrator Object attribute/ method tips in VS Code

  • August 15, 2022
  • 1 reply
  • 1697 views

I am a novice in illustrator script. Now I try to write JS with VS Code, but the properties and methods of AI objects are very troublesome to me,including whether it is in upper or lower case letters. How can I have property and method prompts when writing JS with VS Code? It's like writing VBA in VBE.

I also tried to find relevant information on this forum, including the following links and documents on the vs code official website, but they seemed much professional and complicated.

https://community.adobe.com/t5/illustrator-discussions/jsdoc-for-illustrator-vscode/m-p/11831850 

https://github.com/aenhancers/Types-for-Adobe 

https://code.visualstudio.com/learn 

 

So far I have not understood how it is used! It seems that it needs to do some configuration files first, but I don't know where to start. I don't even know how to judge whether I have successfully installed node.js and typescript and git, and how they are installed.

 

I'm not a professional programmer. I just write some JS at ordinary times. I don't know whether there are simple steps 1, 2 and 3.... to realize this function? It would be better if you could attach pictures.

 

Many Thx for help and ideas, any other suggestions, I am also very grateful!

 

Object attribute/ method tips in VBE:

This topic has been closed for replies.
Correct answer Silly-V

You have to use TypeScript these days. The way old ES3 ExtendScript works is that you have #include statements which bring in files. But in the modern way, what you do is specify the compilation target as "ES3" in your tsconfig.json of the TS project and then you can write modern-format type-checked auto-completing code which can compile down to the one long ES3-style JSX file which is a stitched-together version of all your typescript files which have been compiled down to ES3 and put into one large body of text. It takes a bit of time to set up your first typescript project, essentially VSCode gives us the ability to create an auto-completion environment just like the old VB stuff, but even better because you're in control. But once you have got your first project up, you can just copy and paste it to create new projects. A very big benefit is being able to include or exclude various code from different locations, such as using a shared code folder or using some bits of code from separate scripts in each other. This is powered by the type checking, so if anything is wrong, the message will tell you. As opposed to the ESTK and its include statements which one would have to run and see it break to know if any of the files have changed or they aren't there anymore. Here is a sample project I've started with a long time ago, and now it's really updated and I need to update the repo. However, it shows a package structure and a tsconfig.json, and you can download this code to see if it's able to run.

In this old project I have used a .d.ts declaration file which specifies the polyfills such as Array.prototype.map prototype, and I have "allowJS" as true, so the JS files referenced by the .d.ts file are brought in. (EDIT: I just looked at it and forgot I have already updated it to convert the polyfills to TS) However, I since have realized that allowJS can cause some issues for me and it's better to have converted the polyfills files to typescript and include them 'normally', as a .ts file which is inside the "include" block of the tsconfig. I have turned the allowJS off these days, and use the include block along with the "exclude" and "files" blocks when needed.

My summary of this is:

  • The 'types for Adobe' files should be referenced at the "types" block of the tsconfig.
  • The code which will be used for the script is in the "include" block, often times as "./src/**/*.ts" to capture simply every ts file in the src folder. Note that you don't have to name it 'src' even, everything is up to you - but most just say 'src' and if you talk to anyone else they will immediately know about 'src'.
  • Sometimes you may write a script that would do well to just borrow some code from another script. You can simply use the include block to stick in various random ts files from arbitrary filesystem locations. However, maybe one of the inclusion patterns specifies a whole folder of files, but you want every file except certain ones from there. In this case, use the "exclude" block to exclude those undesired files.
  • However still, there may be a situation where you want to include some items, including folders of files, but maybe it's a folder that has a folder and actually you want to include the parent folder, exclude the child folder but still include just a couple of files from that excluded folder. In this case, use the "files" block to override the exclusion block (which can exclude folders and files) to override the exclusion statement and bring in those specific files. The items in the "files" block cannot be folders as opposed to the include/exclude blocks.

 

Anyways, that's a bit more of an advanced topic - but to start out if you can make your TS project run, then your magical world of auto-completing intellisense and the code writing itself for you is going to be opened! The question is, how many scripts you're doing and how much javascript do you foresee yourself doing in the future in general. Every javascript project can be a typescript project and it yields substantial benefits. I would say if you even intend to do a single javascript project that will ever need future maintenance, TS is the only way to fly!

PS: you can use typescript right away with no additional meta-codes which post-process the files. This way, every separate code file has to contain either variables by themselves or a function but no return statements. The resulting compiled file will have all the functions listed out in the resulting javascript file. But, I like to have every script of mine to be wrapped in a wrapper method, so it is completely scoped in and we can pass arguments to this one big function and therefore be able to activate this script via external means. A simplest way is to make another JSX file (it could be vanilla) and use an extendscript #include statement to bring the code in, into the contents of a method in this JSX file. The arguments passed to the parent function which contains the #include will be referenceable via the arguments keyword in the included code.
So that is why there's this whole 'build-code' folder in the project, you can activate the tasks with Ctrl+Shift+B to run tsc-watch and "Build-Export-Watch". The first tsc-watch simply does tsc every time you save, and it writes the file to the _CONTENTS.js file. But, there is extra node js javascript that puts a file watcher on that _CONTENTS file and every time there is a change to that file, it will take that text and put it inside the .template.js file, into a wrapper function.

So, you do not have to do all this, because technically 'all this' is a replacement of having that other JSX file which simply does an #include of the _CONTENTS file. However the reason I did it is because I personally wish to end up with one single file I can email to people.

 

Oh yea, but you can also just use regular javascript and use JSDoc. You either use tsconfig.json and use allowJS : true - and you don't even have to do any tsc or any typescript, or use jsconfig.json. (but you do have to use a lot of JSDoc comments)

1 reply

Silly-V
Silly-VCorrect answer
Legend
August 15, 2022

You have to use TypeScript these days. The way old ES3 ExtendScript works is that you have #include statements which bring in files. But in the modern way, what you do is specify the compilation target as "ES3" in your tsconfig.json of the TS project and then you can write modern-format type-checked auto-completing code which can compile down to the one long ES3-style JSX file which is a stitched-together version of all your typescript files which have been compiled down to ES3 and put into one large body of text. It takes a bit of time to set up your first typescript project, essentially VSCode gives us the ability to create an auto-completion environment just like the old VB stuff, but even better because you're in control. But once you have got your first project up, you can just copy and paste it to create new projects. A very big benefit is being able to include or exclude various code from different locations, such as using a shared code folder or using some bits of code from separate scripts in each other. This is powered by the type checking, so if anything is wrong, the message will tell you. As opposed to the ESTK and its include statements which one would have to run and see it break to know if any of the files have changed or they aren't there anymore. Here is a sample project I've started with a long time ago, and now it's really updated and I need to update the repo. However, it shows a package structure and a tsconfig.json, and you can download this code to see if it's able to run.

In this old project I have used a .d.ts declaration file which specifies the polyfills such as Array.prototype.map prototype, and I have "allowJS" as true, so the JS files referenced by the .d.ts file are brought in. (EDIT: I just looked at it and forgot I have already updated it to convert the polyfills to TS) However, I since have realized that allowJS can cause some issues for me and it's better to have converted the polyfills files to typescript and include them 'normally', as a .ts file which is inside the "include" block of the tsconfig. I have turned the allowJS off these days, and use the include block along with the "exclude" and "files" blocks when needed.

My summary of this is:

  • The 'types for Adobe' files should be referenced at the "types" block of the tsconfig.
  • The code which will be used for the script is in the "include" block, often times as "./src/**/*.ts" to capture simply every ts file in the src folder. Note that you don't have to name it 'src' even, everything is up to you - but most just say 'src' and if you talk to anyone else they will immediately know about 'src'.
  • Sometimes you may write a script that would do well to just borrow some code from another script. You can simply use the include block to stick in various random ts files from arbitrary filesystem locations. However, maybe one of the inclusion patterns specifies a whole folder of files, but you want every file except certain ones from there. In this case, use the "exclude" block to exclude those undesired files.
  • However still, there may be a situation where you want to include some items, including folders of files, but maybe it's a folder that has a folder and actually you want to include the parent folder, exclude the child folder but still include just a couple of files from that excluded folder. In this case, use the "files" block to override the exclusion block (which can exclude folders and files) to override the exclusion statement and bring in those specific files. The items in the "files" block cannot be folders as opposed to the include/exclude blocks.

 

Anyways, that's a bit more of an advanced topic - but to start out if you can make your TS project run, then your magical world of auto-completing intellisense and the code writing itself for you is going to be opened! The question is, how many scripts you're doing and how much javascript do you foresee yourself doing in the future in general. Every javascript project can be a typescript project and it yields substantial benefits. I would say if you even intend to do a single javascript project that will ever need future maintenance, TS is the only way to fly!

PS: you can use typescript right away with no additional meta-codes which post-process the files. This way, every separate code file has to contain either variables by themselves or a function but no return statements. The resulting compiled file will have all the functions listed out in the resulting javascript file. But, I like to have every script of mine to be wrapped in a wrapper method, so it is completely scoped in and we can pass arguments to this one big function and therefore be able to activate this script via external means. A simplest way is to make another JSX file (it could be vanilla) and use an extendscript #include statement to bring the code in, into the contents of a method in this JSX file. The arguments passed to the parent function which contains the #include will be referenceable via the arguments keyword in the included code.
So that is why there's this whole 'build-code' folder in the project, you can activate the tasks with Ctrl+Shift+B to run tsc-watch and "Build-Export-Watch". The first tsc-watch simply does tsc every time you save, and it writes the file to the _CONTENTS.js file. But, there is extra node js javascript that puts a file watcher on that _CONTENTS file and every time there is a change to that file, it will take that text and put it inside the .template.js file, into a wrapper function.

So, you do not have to do all this, because technically 'all this' is a replacement of having that other JSX file which simply does an #include of the _CONTENTS file. However the reason I did it is because I personally wish to end up with one single file I can email to people.

 

Oh yea, but you can also just use regular javascript and use JSDoc. You either use tsconfig.json and use allowJS : true - and you don't even have to do any tsc or any typescript, or use jsconfig.json. (but you do have to use a lot of JSDoc comments)

Inspiring
August 19, 2022

Thanks @Silly-V .

Because of my limited knowledge, I still can't use it correctly...🙁

Silly-V
Legend
August 19, 2022

Well just try this: make a new folder, then open that folder up with VSCode.

YourFolder/AdobeTypes/index.d.ts

YourFolder/AdobeTypes/JavaScript.d.ts

... and so on

Put the types for adobe .d.ts files inside it.

Make a new JSX file and at the top of this file write the following:

/// <reference types="./YourFolder/AdobeTypes"/>

When you put no semi-colon at the end of this, VSCode will better highlight the file path and it will tell you if the path is missing. Unfortunately, for me, VSCode does not auto-complete the path in this statement like it does with some other things. At least it tells you when the path is wrong. In types for adobe files you can also see the reference statements being included, they help bring in the other types files. For example, Illustrator-stuff index.d.ts contains reference statements that bring in code from JavaScript.d.ts and global.d.ts, etc.

You then can use JSDoc. Since an Adobe types file contains the "app" variable declaration, it will now know when you type in "app.activeDocument" that it's an Illustrator document and you can auto-complete the properties when you write all the code. You can also put in special comments such as:

/** @TyPe {string[]} */
var stringArray = [];
alert(stringArray.length);

When you type the dot after stringArray it will pop in with all kinds of properties. VSCode will do this anyway, because it will know you have an array, I think. But if you also put a ///@ts-check comment in your JSX file, it will also tell you that stringArray[0] can only be a string. I did it this way for a couple of years, and ended up putting in all the polyfills for modern array methods for example, in my library jsx files. The auto-completion for what your javascript of the moment can do is controlled by a tsconfig.json or jsconfig.json file's "lib" property, so absent the file and only using the open VSCode folder and reference statement, you may have to put in the directive no-default-lib="true" into the /// <reference statement. Anyway, just look into JSDoc to get you up and running with intellisense, it can go a very long way without any TypeScript. When you use JSDoc it will work in your js files and you won't have to do anything different, but it will still use TypeScript to carry out its type-checking and auto-completion. So if you use it, it's just like using TypeScript, minus the transpiling feature which takes modern JS you write in and compiles it down to ES3 for ExtendScript.