cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gord Tanner <gtan...@gmail.com>
Subject Re: Moving plugin JS files around
Date Mon, 14 Jan 2013 21:30:53 GMT
I was envisioning this working closer to the node_modules pattern.

Ideally with a module loading framework you should be able to XHR these
modules over at require time.

Here is where the debate of commonJS vrs AMD will heat up.  CommonJS will
require sync XHR because of it's ties to node (which I don't think is a bad
thing ;))

Since we have made the leap to a module based javascript layer we should be
able to leverage it to dynamically load the modules for us (may it be XHR,
over the exec bridge, voodoo).




On Mon, Jan 14, 2013 at 4:19 PM, Andrew Grieve <agrieve@chromium.org> wrote:

> On Mon, Jan 14, 2013 at 4:04 PM, Gord Tanner <gtanner@gmail.com> wrote:
>
> > Yes,
> >
> > BlackBerry is really 3 platforms in one.  We used to have them as 3
> > seperate platforms but was a headache for writing apps and ensuring that
> > you had the right javascript file in the right place.
> >
> Just so I understand this, is it that blackberry has fat binaries? e.g. one
> binary can be deployed to multiple platforms?
>
> Otherwise, it's quite likely that cordova-cli will make the old
> multi-platform headaches go away.
>
>
> >
> > Since I wrote most of the module stuff I agree I have abused it a little
> > with some of the tricks of the trade we have in place with the build
> step.
> >
> > I would rather see us handle this via the exec bridge than including
> script
> > files in the DOM (stay with me for a little bit).
> >
> > Not a final spec but an idea would be:
> >
> > var foo = require('cordova/plugin/foo')
> >
> > inside require we would realize we don't have foo preloaded in cordova.js
> > and call exec>
> >
> > exec(success, fail, 'PluginManager', 'getPluginSource', {plugin: "foo",
> > platform: "ios"})
> >
> > where success would be something like:
> >
> > function (func) {
> >     cordova.define('cordova/plugin/foo', func);
> > }
> >
> > Thoughts?
> >
>
> Gord, what's the motivation for this? Maybe that it addresses the having
> alter <script> tags when adding/removing plugins?
> You'd still need to deal with knowing which JS to include in your App
> package (might be a bit bloated to include all JS for all platforms in all
> apps)
> It would mean making require() an async call (unless you use sync. XHRs),
> and I think would have negative effects on performance.
>
>
>
> >
> >
> > On Mon, Jan 14, 2013 at 3:41 PM, Jesse <purplecabbage@gmail.com> wrote:
> >
> > > Comments inline below.
> > >
> > >
> > > On Mon, Jan 14, 2013 at 11:43 AM, Andrew Grieve <agrieve@chromium.org
> > > >wrote:
> > >
> > > > Created a bug for the file moving part (CB-2214), but we can
> > > > continue discussing here.
> > > >
> > > >
> > > > On Mon, Jan 14, 2013 at 2:39 PM, Andrew Grieve <agrieve@chromium.org
> >
> > > > wrote:
> > > >
> > > > > 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?
> > > >
> > >
> > > What I meant about WebOS, was just that it overwrites most of the APIs.
> > > There is a distinct difference in the way the platforms without a
> native
> > > counterpart are authored. (bada, windows8, tizen, bb-webworks, ..)
> > >
> > >
> > > > >
> > > > > 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>
> > > >
> > >
> > > And maybe even:
> > > <platform name="android">
> > >   <source-file src="filetransfer-common.js" />
> > >   <source-file src="filetransfer-android.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?
> > > >
> > >
> > > Yes, something like this.
> > > The plugin would be wrapped in a module-closure, and 'define' it's
> > > interface.
> > >
> > > cordova.define("my/namespace", function(require, exports, module) { });
> > >
> > > Some of this would need to reworked as currently we have 2 aliases for
> > > every plugin:
> > > navigator.accelerometer === cordova.plugin.accelerometer
> > >
> > >
> > >
> > >
> > > > >
> > > > > 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 <
> > > > purplecabbage@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 <agrieve@chromium.org>
> > > wrote:
> > > > >>
> > > > >> On Wed, Jan 9, 2013 at 10:28 AM, Gord Tanner <gtanner@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 <
> agrieve@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
> > > > >> >
> > > > >>
> > > > >
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > @purplecabbage
> > > risingj.com
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message