incubator-flex-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Harui <aha...@adobe.com>
Subject Re: [FalconJx] New JavaScript runtime format prototype
Date Thu, 20 Dec 2012 19:23:23 GMT
Hi Frank,

I will try to take a look, but right now my priorities are post-graduation
tasks, the 4.9 release and getting the current FalconJS code to spit out the
Base.js format for both MXML and AS.  Also, I'm theoretically off duty next
week, so I won't be poking at this stuff full-time.

Hopefully we can pick this up again in the new year.

-Alex


On 12/20/12 9:30 AM, "Frank Wienberg" <frank@jangaroo.net> wrote:

> Hi folks,
> 
> as mentioned in another thread, I have been working on a new JavaScript
> "runtime", which is what I call the way the generated JavaScript code looks
> and works like. While this thread's title has [FalconJx] in it, there is no
> reason the proposal could not be used for FalconJS, too, but I understood
> that for now, using Google Closure is a given.
> 
> I had the following design goals:
> 
>    - Support ActionScript 3's "differentiator" features: private members,
>    interfaces + is/as, lazy class initialization, method binding,
>    getter/setter functions
>    - work in IE < 9 (except for getter/setter functions)
>    - Produce debuggable JavaScript code that can also be optimized for
>    deployment. The debuggable code should be very similar to the original
>    ActionScript source code for every line containing executable code
>    - Dependency management: load/bundle only the needed classes. Every
>    compilation unit to debug should load as a separate request
>    - Minimal to no runtime overhead, even in debug mode
>    - Support trace()
> 
> 
> I took the following design decisions:
> 
>    - For private members, a mix of JavaScript lexical scope and field
>    renaming like in Jangaroo is used
>    - To implement an efficient "is" operator, all interfaces a class
>    implements are determined once for the class. I use a prototype chain to
>    inherit the interfaces implemented by the super class
>    - Lazy class initialization uses a very efficient technique refined by
>    Olaf Kummer: Wherever a constructor or non-private static member is called,
>    the "self-destructing" class initialization function is checked for
>    existence and, if still existing, called ("guarded" call)
>    - Method binding is again borrowed from the Jangaroo Runtime: the bound
>    function is "cached" at the object under a different but unique name so
>    that it keeps its identity. This is important e.g. to be able to remove
>    event listeners
>    - Getter/setter functions map to Object.defineProperty("...", { get:
>    ..., set: ...}), thus no support in IE < 9
>    - To make everything else work in IE < 9, I use polyfills for ECMAScript
>    5 Object, Array and Function API
>    - For keeping generated code in separate JS files, expressing
>    dependencies between these files, loading them separately at runtime and
>    linking them statically into a single JavaScript file, I chose to use
>    Asynchronous Module Definitions (AMD) and RequireJS (version 2.1.2) as the
>    concrete implementation of AMD. AMD is preferred over CommonJS because it
>    better fits web applications, as e.g. argued here:
>    
> http://blog.millermedeiros.com/amd-is-better-for-the-web-than-commonjs-modules
> /To
> link and optimize the application, RequireJS provides an optimizer
> tool
>    simply called "r.js".
>    - To conditionally load polyfills (for IE < 9), I use the "shim"
>    RequireJS plugin
>    - To achieve minimal runtime overhead, I only use helper functions to
>    define the class structure once (defineClass and defineInterface). As soon
>    as the complete application structure is set up, all code executed is
>    inlined
>    - Since all modern browsers seem to support a "console" object with a
>    "log" method, trace() is simply implemented to check for the existence of
>    console.log() by trial-and-error (try... catch). It then String-converts
>    and concatenates all its arguments like its ActionScript sibling
> 
> 
> *About the Example*
> 
> To specify how I think FalconJx-generated JavaScript output should look
> like, I created an ActionScript example, consisting of two classes and
> three interfaces. Every language feature supported by the new runtime
> format gives an appearance in the code (well, I didn't add a private static
> method, because it works like a private method, only simpler).
> The whole thing is a public GitHub project at
> https://github.com/fwienber/as-js-runtime-prototype.
> To download all files in one go as a zip or tar.gz, please use the tag
> page: https://github.com/fwienber/as-js-runtime-prototype/tags.
> 
> A live demo is available on the corresponding GitHub pages at
> http://fwienber.github.com/as-js-runtime-prototype/index.html
> From there, you can reach all ActionScript example sources and the proposed
> JavaScript equivalent (so far, hand-coded :-)).
> To see the example in action, use the three bottom links which start the
> same application in three flavors:
> 
>    - debug: Each JS file corresponding to an AS class or interface and the
>    main bootstrap file is loaded with a single request. This gives you a nice
>    1:1 mapping of source to output in the JavaScript debugger. Additionally,
>    there are some "infrastructure" files: require.js itself, the RequireJS
>    plugin "shim" (shim.js, shims.js), my AS3 runtime helpers defineClass.js
>    and defineInterface.js, and a couple of built-in AS3 functions (bind, as,
>    is, trace). If loading in IE < 9, the shim plugin loads several ES5
>    polyfills.
>    - linked: The whole application is merged into one JS file using the
>    RequireJS optimizer "r.js" without optimizations. Thus you only have two
>    requests: require.js and hello-worls-all.js are loaded. In IE < 9, the
>    polyfills are still loaded one-by-one (I didn't bother to optimize this
>    case, but of course, it can be done).
>    - minified: Same as "linked", only that require.js and
>    hellow-world-all.js are minified by Uglify2. This can easily be achieved
>    using "r.js" with the parameter optimize=uglify2.
> 
> 
> For the demo, I redirected trace() from the JavaScript console (backed-up
> in trace-console.js) to the DOM, so that you can see the log messages
> directly.
> 
> Just look into the code and observe how it works in Firebug or any other
> JavaScript debugger of your choice, and let me know if anything is unclear,
> missing or if you need more reasoning for the design decisions taken.
> I know there are still several issues to be fleshed out (e.g. interaction
> with "native" JavaScript or package-scope variables, just to name two), but
> I think the current state is a solid core of how a modern, efficient,
> self-contained, extensive and still concise JavaScript runtime format for
> Apache Flex could look like.
> Please tell me what you think!
> 
> Have fun,
> -Frank-

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Mime
View raw message