Migrating Elgg libraries to AMD modules in 2.x

We're experiencing some growing pains in this area due to backwards compatibility issues.

Let's say we have a legacy Elgg library elgg.foo we'd like to migrate to a new module elgg/foo.

API and Deprecation

I'm going to rewrite this...

Let's say elgg.foo has several public methods usable by plugins. In 2.x these must stay operational, but they should ideally cause a deprecation notice. There's a simple, if crude, pattern to achieve this:

In each elgg.foo method, test for the variable elgg.foo.method._amd. If it's not found, show the deprecation notice. In either case, delete elgg.foo.method._amd afterwards. See elgg.ui.widgets.init.

In the new module, we make a copy of the the whole library, and overwrite each method such that it sets elgg.foo.method._amd before calling the original method. The module then returns the altered library copy. See elgg/widgets.

Effectively elgg/foo returns a lightweight wrapper to elgg.foo such that each call to an elgg.foo method is "pre-cleared" in advance. If anyone has a cleaner method to do this, I'm open to suggestions.


Let's say elgg.foo calls its init function in the [init, system] hook. What that promises to 3rd party plugins is that, if they register for the [init, system] hook, elgg.foo.init will have already run.

[Aside: some 3rd party JS uses Elgg libs without even blocking on [init, system]. This is a bad idea that makes your JS dependent on luck.]

Now we're loading our new module async. For BC, we have to delay the [init, system] hook until elgg/foo is loaded. In 2.1 we can do that by having the new elgg/init module depend on elgg/foo, but there's a cost: This slows down all code waiting on [init, system]. If we do this several modules, it's going to get painful unless we proactively inline modules into elgg.js.

Feedback and Planning

Feedback and Planning

Discussions about the past, present, and future of Elgg and this community site.