OpenF2 / F2

Redefining web integration for the financial services community
Apache License 2.0
130 stars 62 forks source link

Evaluate AMD replacement of F2's internal loader #129

Open markhealey opened 11 years ago

markhealey commented 11 years ago

Based on the discussion in #125 let's use this Issue as a place to discuss requirements for replacing F2's internal loader with an AMD solution (such as requirejs). The discussion should also cover dependency management at a high level. (I realize there is overlap between AMD and "dependency management".)

Note: the internal loader was recently upgraded, see #120.

The floor is open...

ilinkuo commented 11 years ago

Please look at https://github.com/OpenF2/F2/commit/e2dfa28c32d5cc220e58d1529b65ef52616970a0#commitcomment-4013708 as a safer approach than an in-place rewrite of the F2 loader engine.

brianbaker commented 11 years ago

Few questions for discussion:

ilinkuo commented 11 years ago

From @montlebalm 's comment in https://github.com/OpenF2/F2/pull/125#commitcomment-4006920

To do a proper port of F2, every AppClass needs to be wrapped in a define() block with dependencies that are also wrapped in define(). These dependencies will need to be referenced by path, which likely can't be hard-coded because of your build system (i.e., for cache busting). Dependencies need to be named explicitly by version, because apps may depend on different 3rd party libraries. If path aliases are defined, containers and app developers need to agree on a naming convention or else every app needs to return every lib it needs, thereby inflating the size of every app request.

I'd like to add and clarify:

ilinkuo commented 11 years ago

@brianbaker I'll take a shot, but the answer depends on which strategy below is chosen

First, I think three strategies are possible:

  1. Rewrite the internals of the F2 engine to use AMD, keeping the existing API
  2. Switch F2 over completely to AMD
  3. Keep both legacy API and new AMD API, both using the same underlying AMD engine.

Option 1 is the cheapest and most backwards compatible. The AMD engine can load both define()- wrapped and unwrapped scripts, though you might need some small adjustments to the unwrapped scripts because the execution order of unwrapped scripts is not well-defined. There might also have to be some cross-domain loading tweaks. You'll get ~50% of the AMD benefits -- cached resources, elimination of duplicate resource loading, but no r.js optimization.

Option 2 requires Containers, Apps, and F2 itself to make big changes, but it also has the biggest benefits.

Option 3 is a blend of the options 1 and 2. It makes switching to AMD optional for users and has roughly the same development cost as Option 2, but the long term maintenance costs to F2 are quite high (consider that most estimate maintenance costs to be 3-4x development costs).

ilinkuo commented 11 years ago

My thoughts on @brianbaker's discussion questions

What would replacing the internals of F2 with AMD require of containers?

If done via Option 1, probably nothing would be required of Containers. It may or may not be necessary to label an appManifest or appConfig as being AMD-friendly.

If done via Option 2, then the Container itself should be an AMD module, though it is possible to call AMD code from non-AMD code, but you'll need to combine that with Promises.

Is it up to a container to provide require via RequireJS, Dojo, etc. or does is it bundled with F2?

The point of the AMD specification is to allow different AMD implementation to be interchangeable, so I would vote for unbundling.

require() and define(), ironically, are globals.

Does this type of update force all containers to adopt AMD?

Depends on which option is chosen, see https://github.com/OpenF2/F2/issues/129#issuecomment-23880238

Would it be necessary to have separate builds of F2 for AMD and non-AMD sites?

That depends on how much you care about JS minification -- you only need separate builds if there is a significant difference in the size of the library. Without AMD, there have to be separate grunt tasks for each configuration. With AMD correctly structured, r.js will build only the modules you actually use, without any work/decisions from the user.

ilinkuo commented 11 years ago

FYI, jQuery just finally switched their internals over to AMD

markhealey commented 11 years ago

Just to keep a heartbeat going and to inform watchers, we have been meeting internally to get a more formal proposal—which we'll post here—drafted on updating F2's internals to use AMD. We're striving to keep the current API the same as it is today but it's looking like we'll have some minor changes. More soon, stay tuned.

ilinkuo commented 11 years ago

If the API changes become major enough to also change the manifest, do please consider revising to extend package.json instead of extending the current F2 manifest format.