You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Harbs <ha...@gmail.com> on 2017/02/12 23:17:18 UTC

[FlexJS] CompressionUtils (linking scripts)

I just added a CompressionUtils class which uses ByteArray on the Flash side and pako on the javascript side.

It uses inject_html to link to the js because I don’t know of a better way to currently do this.

I don’t like this approach for a number of reasons:
1. It hardwires the link into the generated HTML. In this case it’s using the “best” cdn, but it does not allow the content to be hosted on the app server.
2. There’s no (easy) way to link to relative paths when an app is being loaded locally. Requiring it be downloaded from the internet is inefficient, and does not allow the app to be run when there’s no internet connection.
3. This will not work for Node.js. Node.js needs require(‘pako’) instead of linking to the script.

Here’s what I’m thinking: I’d like to have a “Require” tag which would cause FlaconJX to do the right thing depending on the compilation. If it’s compiling for Node.js, it would require() the dependency. If it’s compiling for the browser, it would link to a relative path if that path exists (there would be some standardized way of linking) or to a url if not (assuming a url is provided).

I don’t really care what the require tag looks like, but I personally like metadata over the comment approach. It could also be a function call which the compiler recognizes as a “special” one which gets optimized out.

So something like this:

[Require(name=“pako", url="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js”)]

or:
/**
* @require pako, https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js <https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js>
*/
or:
require(‘pako’,'https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js' <https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js'>);
where the signature for require would be:
require(name:String,url:String=“”)

Thoughts?
Harbs

Re: [FlexJS] CompressionUtils (linking scripts)

Posted by Josh Tynjala <jo...@gmail.com>.
The compiler supports special [JSModule] metadata for Node so that it emits
the correct require() calls. It might be possible to make use of this for
projects that target Node and other contexts. The compiler will probably
need some tweaks, though.

Here's an example:

package {
  [JSModule]
  public class fs {
  }
}

It will use the class name as the module name by default, or you can
specify the module name explicitly:

package fs {
  [JSModule(name="fs")]
  public class FSWatcher extends events.EventEmitter {
  }
}

The compiler will emit a require() call in the following style any time
that a class with [JSModule] metadata is used:

var fs = require("fs");

Currently, it will always emit the require() call, even if you aren't
building a Node project. The compiler could probably be tweaked so that
emitting require() calls works for Node only and gets skipped in other
contexts.

- Josh

On Sun, Feb 12, 2017 at 3:17 PM, Harbs <ha...@gmail.com> wrote:

> I just added a CompressionUtils class which uses ByteArray on the Flash
> side and pako on the javascript side.
>
> It uses inject_html to link to the js because I don’t know of a better way
> to currently do this.
>
> I don’t like this approach for a number of reasons:
> 1. It hardwires the link into the generated HTML. In this case it’s using
> the “best” cdn, but it does not allow the content to be hosted on the app
> server.
> 2. There’s no (easy) way to link to relative paths when an app is being
> loaded locally. Requiring it be downloaded from the internet is
> inefficient, and does not allow the app to be run when there’s no internet
> connection.
> 3. This will not work for Node.js. Node.js needs require(‘pako’) instead
> of linking to the script.
>
> Here’s what I’m thinking: I’d like to have a “Require” tag which would
> cause FlaconJX to do the right thing depending on the compilation. If it’s
> compiling for Node.js, it would require() the dependency. If it’s compiling
> for the browser, it would link to a relative path if that path exists
> (there would be some standardized way of linking) or to a url if not
> (assuming a url is provided).
>
> I don’t really care what the require tag looks like, but I personally like
> metadata over the comment approach. It could also be a function call which
> the compiler recognizes as a “special” one which gets optimized out.
>
> So something like this:
>
> [Require(name=“pako", url="https://cdnjs.cloudflare.
> com/ajax/libs/pako/1.0.3/pako.min.js”)]
>
> or:
> /**
> * @require pako, https://cdnjs.cloudflare.com/
> ajax/libs/pako/1.0.3/pako.min.js <https://cdnjs.cloudflare.com/
> ajax/libs/pako/1.0.3/pako.min.js>
> */
> or:
> require(‘pako’,'https://cdnjs.cloudflare.com/ajax/libs/pako/
> 1.0.3/pako.min.js' <https://cdnjs.cloudflare.com/
> ajax/libs/pako/1.0.3/pako.min.js'>);
> where the signature for require would be:
> require(name:String,url:String=“”)
>
> Thoughts?
> Harbs

Re: [FlexJS] CompressionUtils (linking scripts)

Posted by Harbs <ha...@gmail.com>.
> On Feb 14, 2017, at 6:00 PM, Alex Harui <ah...@adobe.com> wrote:
> 
> An Emitter could change the goog.requires in every file, and even use a
> different require system like RequireJS.

This might be a good solution. The initial compilation could be optimized for Node (and just require() all the assets) and it could then use Browserify or Webpack to bundle it all for use on the web. It is a major departure from what the compiler does now, however.

> If the <head> needs to be different between Browser and Node, then you
> could introduce inject_node_html and have the NodePublisher check for that
> instead of inject_html.

Node does not have <head> The Javascript is executed directly by the Node.js engine.

Re: [FlexJS] CompressionUtils (linking scripts)

Posted by Alex Harui <ah...@adobe.com>.

On 2/13/17, 11:51 PM, "Harbs" <ha...@gmail.com> wrote:

>Fair enough… ;-)
>
>The problem is creating libraries which can be used both in the browser
>and in Node.
>
>Unless we add another set of swcs for Node with a new COMPILE::NODE
>conditional, I don’t see how we can generalize FlexJS to be usable for
>both.
>
>Maybe adding COMPILE::NODE is the right answer.

Does the actual code path need to be different?  If so, then we will need
more conditional compilation statements.

Otherwise, it might be better to have a custom Emitter and/or Publisher
for Node.  Looks like there is already a NodePublisher.  I'm not quite
clear on what needs to be different.

The publishers generally visit the output JS files, scanning for the
goog.requires and removing them.  Since they scan that far, we have the
publisher look for inject_html, collect those in order to determine what
goes in the <head> section.  Currently, that's the only mechanism for
altering the <head> of the output html wrapper.

An Emitter could change the goog.requires in every file, and even use a
different require system like RequireJS.

If the <head> needs to be different between Browser and Node, then you
could introduce inject_node_html and have the NodePublisher check for that
instead of inject_html.

One reason to use inject_html as a directive in the comments instead of
MetaData is simply to avoid having to scan entire files of output.  The
requires are always early in the file.

HTH,
-Alex


Re: [FlexJS] CompressionUtils (linking scripts)

Posted by Harbs <ha...@gmail.com>.
Fair enough… ;-)

The problem is creating libraries which can be used both in the browser and in Node.

Unless we add another set of swcs for Node with a new COMPILE::NODE conditional, I don’t see how we can generalize FlexJS to be usable for both.

Maybe adding COMPILE::NODE is the right answer.

> On Feb 13, 2017, at 8:16 AM, Alex Harui <ah...@adobe.com> wrote:
> 
> Sounds like work.  Feel free to try to make the changes.  An alternative
> might be to have a "NodeCompressionUtils" that has the appropriate require
> in it?  Or is this a general problem for Node?


Re: [FlexJS] CompressionUtils (linking scripts)

Posted by Alex Harui <ah...@adobe.com>.

On 2/12/17, 3:17 PM, "Harbs" <ha...@gmail.com> wrote:

>I just added a CompressionUtils class which uses ByteArray on the Flash
>side and pako on the javascript side.
>
>It uses inject_html to link to the js because I don’t know of a better
>way to currently do this.
>
>I don’t like this approach for a number of reasons:
>1. It hardwires the link into the generated HTML. In this case it’s using
>the “best” cdn, but it does not allow the content to be hosted on the app
>server.
>2. There’s no (easy) way to link to relative paths when an app is being
>loaded locally. Requiring it be downloaded from the internet is
>inefficient, and does not allow the app to be run when there’s no
>internet connection.

Somewhere in the work queue is having inject_html copy over local files
referenced in the injected HTML.

>3. This will not work for Node.js. Node.js needs require(‘pako’) instead
>of linking to the script.
>
>Here’s what I’m thinking: I’d like to have a “Require” tag which would
>cause FlaconJX to do the right thing depending on the compilation. If
>it’s compiling for Node.js, it would require() the dependency. If it’s
>compiling for the browser, it would link to a relative path if that path
>exists (there would be some standardized way of linking) or to a url if
>not (assuming a url is provided).
>
>I don’t really care what the require tag looks like, but I personally
>like metadata over the comment approach. It could also be a function call
>which the compiler recognizes as a “special” one which gets optimized out.
>
>So something like this:
>
>[Require(name=“pako",
>url="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js”)]
>
>or:
>/**
>* @require pako, 
>https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js
><https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js>
>*/
>or:
>require(‘pako’,'https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min
>.js' <https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.3/pako.min.js'>);
>where the signature for require would be:
>require(name:String,url:String=“”)

Sounds like work.  Feel free to try to make the changes.  An alternative
might be to have a "NodeCompressionUtils" that has the appropriate require
in it?  Or is this a general problem for Node?

-Alex