[ALOY-86] Widget dependency management
GitHub Issue | n/a |
---|---|
Type | Story |
Priority | Medium |
Status | Resolved |
Resolution | Fixed |
Resolution Date | 2016-03-11T19:57:32.000+0000 |
Affected Version/s | n/a |
Fix Version/s | alloy 1.7.35, alloy 1.8.0 |
Components | Runtime, Titanium Studio, XML |
Labels | n/a |
Reporter | Tony Lukasavage |
Assignee | Fokke Zandbergen |
Created | 2012-07-16T08:21:55.000+0000 |
Updated | 2016-03-16T22:20:36.000+0000 |
Description
Widgets will need dependency management if we are to build widgets composed of other widgets that may or may not already be in a project. Some things we'll need to do so:
* A
dependencies
key in the manifest. We should probably format this just like the dependencies in nodejs packages to keep it familiar and flexible.
* A dependency manager that needs to be able to:
** check if dependencies are met for a project
** make supported widgets available for installation (think npm install PACKAGE
)
** add publicly available dependencies to project when needed, just as npm would.
These bullet point will probably require integration with TiStudio. The logic of the dependency manager probably makes most sense in a compiler plugin right now, but this may change as the CLI changes.
This is probably post an end of July developer "pre-release" issue.
Just like built-in put shipping widgets in alloy - it will take awhile to do a full widget dependency system plus once widgets are downloaded and installed they need to live somewhere a widgets folder at the same level as built-ins seems to make sense.
Widgets will take up significantly more space than builtins, as builtins are just JS. Widgets will include potentially large amounts of media assets that will unnecessarily bloat the size of the alloy package. Let's just make sure we get the wheels turning on the dependency manager because the pre-loaded widgets going into alloy could quickly become scalability issue.
How is this coming along? I think an Titanium-wide (not just Alloy) approach would be best.
Types of assets to be managed
* Titanium native modules (liketi.storekit
) * CommonJS modules, including: ** Titanium CommonJS modules (liketi.cloud
) ** Alloy sync adapters ** Alloy builtins ** Third-party (momentjs, backbonejs, underscorejs..) * Alloy widgets * Alloy JS Makefiles (which would require support for having multiple)Local and global installation
Like NPM modules and packaged Titanium native/CommonJS modules, the package manager should allow both global and local (in the project) installation. Therequire
method can already load global CommonJS modules, so global Alloy sync adapters, Alloy builtins and even third-party CommonJS modules shouldn't be to hard to support. But also Alloy widgets and JS Makefiles need to be loadable from a global (~/Library/Application Support/Titanium/widgets
?) path. Since each package at least has its own package-file giving info on the package and its dependencies, they need to be installed in separate directories. This means the Alloy builtins and sync adapters won't be available asrequire('alloy/animation')
anymore, but would likely be required asrequire('ti.alloy.animation')
, like a Titanium packaged CommonJS module.Dependency files
Alloy already has a dependency list inconfig.json
and Titanium native/CommonJS modules are listed intiapp.xml
. I would prefer to have just one dependency list per project and to support both Alloy and Classic projects I would suggest sticking totiapp.xml
. The Titanium native/CommonJS modules have amanifest
file but the text format might be difficult to use for specifying dependencies with versions and all. The Titanium CommonJS modules have apackage.json
file that would be easier to require for all packages to specify their own dependencies.Registry
When thinking about the online registry, it's clear that the [Marketplace](https://marketplace.appcelerator.com) has to play some role in that. It would need to be restructured in such a way that all discussed types assets can be registered and managed. The registry could be modeled after [NPM](https://npmjs.org/).As I mentioned on Twitter, I'm reading a lot that sounds like we want everything npm does, but we should use something besides npm. I'm going to do some research, probably talk to isaacs, and see what would be a good fit. We already require nodejs for alloy, titanium CLI, and code processor, and node comes with npm, it seems odd to introduce an entirely other package manager, now forcing developers to have 2, and to deal with all the maintenance issues that come with both.
But whatever new or existing package manager we decide to use for Titanium project dependencies, it should be able to handle *all* it's different types of dependencies. If it can't, and you'd still need to manually download native modules or sync adapters, then I rather have a new package manager that does all Titanium project stuff and use NPM for the meta-tools like Alloy.
Handling all dependencies should not be a problem. If npm was used, alloy's custom dependency files like the config.json and widget.json would likely be scrapped for npm's package.json, making the dependencies trivial. Take a look at how [grunt](http://gruntjs.com/) does it with it's dependencies and plugins. It uses simple naming conventions and indicators within the package.json to allow grunt to determine all available plugins on the fly. It's not a tough process, and it's a proven one that utilizes npm almost exactly as we would. I've emailed [Isaac Schlueter](https://github.com/isaacs) discussing the issue and I gave him some potential ways we'd like to use npm. One is a custom registry so that devs could use the npm client just as they do now, but also have access to the Titanium modules from out registry that would not be injected into the main public npm registry. I'll report back the result of that conversation here, if and when I hear back from him.
What about something like strongloop node. A pass through to npm but with its own repo. This way things like forks of nodejs modules can be maintained and hosted without having to change the name. Also we would be able to let users better search for modules, and not polite the nodejs repo with non node items
[~mattapperson] your opinion on "polluting" the registry _was_ a popular dissent to the idea of using npm. So rather than continue to wonder if it was a bad idea, I talked to Isaac Schlueter, the author of npm, and asked him what he thought of the idea. I won't paste the whole conversation here, but he was 100% behind the idea of using npm for the purposes we are discussing here. To paraphrase him, he knows that npm will always be node-centric, but has big plans to make it the one-stop-shop for all JS, including browser stuff, appc stuff, phonegap plugins, etc... Sooooo... I will work on an initial spec for this in the very near future and will then likely involve the community heavily. Until I do get something out there, if you are really looking forward to contributing, take a look at [grunt](http://gruntjs.com/) as their plugin system is where I will be drawing most of the inspiration. Pay particular attention to how plugins are created, the simple use of a naming convention + package.json keywords for loading on the fly, and the tooling packages they have for creating plugins (grunt-init). This will give you a very good idea of how this will work for Appcelerator as well.
PR on master to add support for resolving Alloy widgets as NodeJS modules (after trying existing paths): https://github.com/appcelerator/alloy/pull/755 [~fmiao] I need to know how to add a test that includes files and folders (
package.json
,node_modules
) at the project level. I've tested this locally (Mac OS X) and it works great, also with globally installed modules.PR merged.