Jesse, thanks for the explanation. Certainly my experience is just with Android & iOS, so it's good to get opinions from the other platforms.
I took a look at WebOS, but pkg/cordova.webos.js does seem to pull in all of the shared plugin modules and hooks them up with the common bootstrap. Why do you say that WebOS shares hardly any code? Blackberry certainly seems to be a bit different in that it looks like it is actually 4 platforms in one. Not sure why we don't just make it four separate platforms. Gord? That said, Blackberry uses the module system even more than other platforms. I think it would be a lot of work to make plugin within blackberry have it's own loading logic that selectively loads module based on the sub-platform (if we went with a single-file pre-built approach). With the single-file prebuilt approach, I'd guess it would look something like this: plugin.xml says which .js file to include for the platform: <platform name="android"> <source-file src="filetransfer.js" /> </platform> There is certainly a bug-report advantage to having each in its own .js file. If everything is in cordova.js, and we get bugs with "Error on line ##", we can't actually map that to a file. On the other hand, each platform has bootstrap logic that must come after plugins are loaded. This might turn into a source of errors if we have a bunch of .js files being added via <script> tags. One aspect of plugin JS that I don't want to lose, is our separate pass of module -> symbol (defaults/merges/clobbers). In fact, I think this is an area that we may wish to enhance in the future. E.g. a couple of releases ago we added the ability to print a deprecation message when old namespaces are referenced. Other advantages of the system: - Helps authors write modules side-effect free modules - Allows us to detect symbol collisions - Gives us control over when the modules are loaded - e.g. We could add measurement to see how long this process takes - e.g. We could experiment with lazy-loaded modules by using JS getters that return require(module) - e.g. We could use this to support exposing Cordova APIs to iframes It might be possible for us to maintain the module->symbol mapping system if we had plugins use pre-built .js files. E.g. their .js could be a collection of cordova.define() calls, followed by a cordova.registerModuleMappings() call. Is that what you're thinking? In either way, I think I'd like to go ahead with this change of moving from lib/$PLATFORM/plugin to plugin/PLUGIN_NAME/PLATFORM, since I think this is a good first step for either proposal. On Fri, Jan 11, 2013 at 1:48 PM, Jesse MacFadyen <purplecabb...@gmail.com>wrote: > Hi Andrew, > > Having spent some time with this, I don't think it's awful, but I am > worried about complexity. > > To me, a better approach is: > > - all plugins are simply ripped out of cordova-js > - each plugin is distributed 'built' meaning for an API like file or > contacts, there is only 1 js file, and while it depends on cordova.js, > it is not part of it. ( or possibly just a concat ) > - plugman does the work of adding/removing but it is really just > changing script tags for the js portion > > This means all our core plugs will need to be modified as the > currently depend on the builder to wrap them. > > I spent some time working with your approach Andrew, and I think it > sounds better than it is. Blackberry has 4 inter-related branches to > consider, webos shares hardly any code with the other platforms, ... I > am more keen on adding consistency than I am to making the tool work > around it. > > If we were only concerned with iOS, Android, and windows phone, then > your approach might be best, but there are some messes in there. > > I will continue to push for the simpler solution, but I won't block > you anymore. > I do think you should dive a little deeper into your approach, and > possibly prove me wrong. I am completely open to further discussion on > the point. > > > Cheers, > Jesse > > Sent from my iPhone5 > > On 2013-01-10, at 8:09 PM, Andrew Grieve <agri...@chromium.org> wrote: > > On Wed, Jan 9, 2013 at 10:28 AM, Gord Tanner <gtan...@gmail.com> wrote: > > > Ideally the require paths should stay true to the following rules (not > that > > we follow them exactly now but we are close): > > > > 1. should always start with cordova (in case we ever share a require > > framework) > > 2. should follow as close as possible to the folder structure. > > > > We don't really do this now (but we are close). It is mainly to help > with > > navigation of the project from a require statement: > > > > var foo = require('cordova/plugin/foo/submodule') > > > > Ideally I should be able to navigate to a file that lives in: > > > > ~/cordova.js/plugin/foo/submodule.js > > > > But realistically we are probably going to see: > > > > ~/cordova.js/plugin/foo/js/submodule.js > > > > Assuming we are dumping everything into a js folder here is the "mapping" > > off the top of my head: > > > > var foo = require('cordova/plugin/foo') > > ~/cordova.js/plugin/foo/js/index.js > > > > var foo = require('cordova/plugin/foo/ios') > > ~/cordova.js/plugin/foo/js/ios.js > > > > var foo = require('cordova/plugin/foo/blackberry/qnx') > > ~/cordova.js/plugin/foo/js/blackberry/qnx.js > > > > What does a plugin (native and js code) folder structure look like? > > > Have a look at this plugin: https://github.com/shazron/KeychainPlugin > > With the JS changes I'm proposing, it would look like: > /src/ios/*.h, *.m > /www <- empty! > /src/js/common/keychain.js > or > /src/js/ios/keychain.js > > So, the idea behind moving all of the plugins to /plugin/$PLUGIN_NAME > within cordova-js, is that when they move out, there will be the mapping: > cordova-js/plugin/$PLUGIN_NAME ---> $PLUGIN_REPO/src/js > > > When a plugin is installed into a project via cordova-cli, I suggest that > we get a structure like this: > > MyApp/platforms/ios/... same as before ... > MyApp/cordova-js/... copy of cordova-js > MyApp/cordova-js/plugin/keychain/common/keychain.js > MyApp/plugins/keychain/plugin.xml > MyApp/www > > So, the idea here is that the cordova-js will have no top-level plugin/ > directory, but one will be added when plugins are added. > > Also, like other sources, .js file should be listed in the plugin.xml so > that they can be reliably removed. > > > > About the require paths. I think for files in cordova-js, the prefix should > be "cordova/", but for plugin files, it should be "plugin/" (or maybe > "cordovaplugin/"?), so that plugin JS doesn't accidentally clobber core > cordova modules. > > For the keychain example: require('cordovaplugin/keychain/keychain') > > > In terms of changes to the builder, we'd need to add the idea of multiple > roots. Instead of just 'lib', there will also be 'plugin' as a root. > > > > > > > > On Wed, Jan 9, 2013 at 9:42 AM, Andrew Grieve <agri...@google.com> > wrote: > > > >> I'd like to take a first step towards moving plugin JS into separate > > repos > >> by first moving them around within cordova-js. > >> > >> Here is my proposal: > >> > >> Current structure: > >> lib/common/plugin/*.js > >> lib/$PLATFORM/plugin/*.js > >> > >> New structure: > >> plugin/$PLUGIN_NAME/js/common/*.js > >> plugin/$PLUGIN_NAME/js/$PLATFORM/*.js > >> > >> The require path will need to change. Going from: > >> cordova.require('cordova/plugin/FileTransferError') > >> To: > >> cordova.require('plugin/file/FileTransferError') > >> > >> > >> I'll obviously need to update the builder scripts accordingly. The idea > >> here is that we: > >> 1. "cordova plugin add" will copy files into a project's plugins > >> directory > >> 2. "cordova build ios" will use the cordova-js packager and pass > > it > >> the plugin/ directory to use > >> > >> This will not involve changing how we export modules onto namespaces in > >> common.js / platform.js. That will come next though. > >> > >> > >> The resulting structure will look like: > >> > >> plugin/accelerometer/js/common/Acceleration.js > >> plugin/accelerometer/js/common/accelerometer.js > >> plugin/battery/js/common/battery.js > >> plugin/compass/js/common/Compass*.js > >> plugin/contacts/js/common/Contact*.js > >> plugin/device/js/common/device.js > >> plugin/geolocation/js/common/Coordinates.js > >> plugin/geolocation/js/common/Position*.js > >> plugin/globalization/js/common/Globalization*.js > >> plugin/inappbrowser/js/common/InAppBrowser.js > >> plugin/logger/js/common/logger.js > >> plugin/logger/js/common/console-via-logger.js > >> plugin/media/js/common/Capture*.js > >> plugin/media/js/common/ConfigurationData.js > >> plugin/media/js/common/Media*.js > >> plugin/network/js/common/Connection.js > >> plugin/notification/js/common/notification.js > >> plugin/camera/js/common/Camera*.js > >> plugin/echo/js/common/echo.js > >> plugin/file/js/common/Directory*.js > >> plugin/file/js/common/Entry.js > >> plugin/file/js/common/File*.js > >> plugin/file/js/common/Flags.js > >> plugin/file/js/common/LocalFileSystem.js > >> plugin/file/js/common/Metadata.js > >> plugin/file/js/common/ProgressEvent.js > >> plugin/splashscreen/js/common/splashscreen.js > > >