hyperbrew / bolt-cep

A lightning-fast boilerplate for building Adobe CEP Extensions in React, Vue, or Svelte built on Vite + TypeScript + Sass
MIT License
313 stars 40 forks source link

ExtendScript classes transpilation #93

Open igor-elovikov opened 1 year ago

igor-elovikov commented 1 year ago

sorry, I have very little experience with js/ts but I've noticed that if I'm trying to use classes in extendscript babel adds bunch of hepers

for example like those:

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  }
}

when babel transpiles classes to functions it injects these helpers

the problem is that extendscript doesn't know anything about Object.defineProperty so as soon as I'm trying to use classes in extendscript it just breaks the bundle.

I've managed to disable helpers in vite.es.config.ts via

plugins: [
  "@babel/plugin-syntax-dynamic-import",
  ["@babel/plugin-transform-classes", { loose: true }],
  "@babel/plugin-proposal-class-properties",
]

Though I'm not sure if it's the right way

justintaylor-dev commented 1 year ago

Pretty sure those helpers are needed in order for it to work, but if you have an example of before (ES6) / after (ES3) of what you're trying to achieve that would be great.

igor-elovikov commented 1 year ago

Sure

consider this simple class in tsx

import { jsxLogEvent, LogEntry, LogType } from "../../shared/shared";

class Logger {
  constructor() {
    var externalObjectName = "PlugPlugExternalObject";
    var mylib = new ExternalObject("lib:" + externalObjectName);
  }

  private logEntry(type: LogType, data: any[]) {
    const evt = new CSXSEvent();
    evt.type = jsxLogEvent;

    const entry: LogEntry = {
      type: type,
      entries: data,
    };

    evt.data = JSON.stringify(entry);

    evt.dispatch();
  }
}

const logger = new Logger();

export default logger;

if I set vite.es.config.ts to this (in exact same order btw otherwise it doesn't work properly)

...
        plugins: [
          "@babel/plugin-proposal-class-properties",
          "@babel/plugin-syntax-dynamic-import",
          ["@babel/plugin-transform-classes", { loose: true }],
        ]
...

it transpiles to this:

var Logger = /*#__PURE__*/function () {
  function Logger() {
    var externalObjectName = "PlugPlugExternalObject";
    new ExternalObject("lib:" + externalObjectName);
  }
  var _proto = Logger.prototype;
  _proto.logEntry = function logEntry(type, data) {
    var evt = new CSXSEvent();
    evt.type = jsxLogEvent;
    var entry = {
      type: type,
      entries: data
    };
    evt.data = JSON.stringify(entry);
    evt.dispatch();
  };
  return Logger;
}();
var logger = new Logger();

The one above is working fine in AE as far as I can tell. There are some little issues with typescript constructor syntax. I'm not able to declare class properties as constructor parameters like constructor(public number x). Babel just can't transform it for some reason. However that's not a big deal.

If I use default settings I have this one with injected helpers:

var Logger = /*#__PURE__*/function () {
  function Logger() {
    _classCallCheck(this, Logger);
    var externalObjectName = "PlugPlugExternalObject";
    new ExternalObject("lib:" + externalObjectName);
  }
  _createClass(Logger, [{
    key: "logEntry",
    value: function logEntry(type, data) {
      var evt = new CSXSEvent();
      evt.type = jsxLogEvent;
      var entry = {
        type: type,
        entries: data
      };
      evt.data = JSON.stringify(entry);
      evt.dispatch();
    }
  }]);
  return Logger;
}();
var logger = new Logger();

this one is not working for me (AE 23.5.0, CEP 11, Win11)

image

This is just a simple class which could be transform to function in a first place, but I have pretty complicated exporter for game engine so classes are pretty much required for me.

Thank you for framework btw, saved me so much time, tried to use scriptui before I discovered this. That was a nightmare

nangonghan commented 1 year ago

@igor-elovikov @justintaylor-dev Or we can add the es5 environment by default like adding json2.js, so that there will be no such errors

nangonghan commented 1 year ago
image