Skip to content
Maurits Lamers edited this page May 5, 2014 · 11 revisions

A separate page for describing the different needs and configurations for the saving procedure(s). The starting point is the text taken from the Abbot features page, but altered to describe things in more detail.

Essentially there are three groups to be taken care of:

  • apps
  • SproutCore
  • supportive frameworks (other frameworks required by an app)

For serving, the build tools treat everything as private for an app, meaning that inside the build tools each app has its own instance of the SproutCore frameworks as well as any other supportive frameworks, even though these instances point to the same files on disk. This allows you to run in a single project multiple apps with multiple versions and/or multiple configurations (including non-default frameworks for example) of SproutCore and/or supportive frameworks.

This situation has to be converted by the saving procedure into files on disk. In most situations the serving structure of the build-tools is not the structure you want to have on disk. The situation for the files on disk can be split out in the following "targets"

  • Relative builds: all urls in a project are relative
  • Absolute builds: all urls in a project are absolute
  • Hashed builds: all urls in a project contain hashes which are based on the content they refer to
  • SproutCore as central shared resource (Abbot style)
  • SproutCore as private resource per app
  • Supportive frameworks as central shared resource
  • Supportive frameworks as private resource per app

In addition there is the level of combined files:

  • SproutCore as a single JS + CSS
  • SproutCore frameworks each have a single JS + CSS
  • SproutCore + supportive frameworks as a single JS + CSS
  • Supportive frameworks as a single JS+CSS
  • Supportive frameworks each have a single JS + CSS
  • Application + supportive frameworks + SproutCore as a single JS + CSS

It would be ideal if these different "targets" could be combined in any combination. It is important however to have a few use cases to describe why a certain way of building is useful.

Generic use cases

Multiple SproutCore versions

When a situation uses a single project with multiple SproutCore versions, it is best to use a private SproutCore per app. The advantage is that a new app can be served next to the old one, while making support of the old one still possible.

Central SproutCore split into separate frameworks

When a set of applications use different selections from the SproutCore frameworks, it is the nice to be able to only load the required frameworks and nothing more.

Specific use cases

CouchDB

In a CouchDB deploy it is the easiest to have a relative build, where all resources are private and SproutCore is stored as a single JS + CSS, and the app together with its supporting frameworks as a single JS + CSS. This is because everything is inside a single document, to which all files are attachments and CouchDB will take care of the caching using E-Tags. It is perhaps possible to make a central shared SproutCore and / or supportive frameworks work.

PhoneGap/Cordova

In a PhoneGap/Cordova environment, it is the easiest to have a relative build, where all resources are private. How the app, the supportive frameworks and SproutCore are stored exactly is less important. The only difference between a normal app and an app inside Cordova is that a different event should be listened to when starting the app.

Additional functionality

It would be very useful to be able to run separate scripts as a post-build script (semi-)automatically in environments like PhoneGap/Cordova. After every update of the files inside the Cordova environment the cordova app needs to be "refreshed", and a post-build script can take care of this otherwise time consuming manual task.

Implementation details

Internally the buildtools will follow the following pattern for an app:

/
    app_name/
              index.html => the index.html of the app
              sproutcore/ => the content of frameworks
              app_name/ => the content of the app itself

This means that all the frameworks will always be private to the app. When building the app, this url format needs to be converted to the desired kind of target. This is done by a combination of mixins, where a certain mixin causes certain effects because of the task they add, or the way they change specific settings.

  • Relative builds vs Absolute builds are essentially a mixin for a single setting: an urlPrefix for all resources, scripts and stylesheets
  • Hashed urls add a content hash to the paths or filenames used. This can be done as an adjustment on the folder name of a framework, or as an addition to the file name, depending on the way of combining.
  • SproutCore as central resource or private resource boils down to a single setting: include SC into the app or not. If not, the app cannot solve it, and the layer above has to do it. It also means that certain urls have to be adjusted, which boils down to omitting the app name from the sproutcore urls.
  • Supportive frameworks as central resources or private resource boils down to a single setting per framework: include with the app or not. Certain urls have to be adjusted accordingly.
  • Combining: This seems to be best done through a single mixin with a few settings:
    • Combine WrapperFrameworks (like SproutCore) as a whole, only as its subframeworks, or everything as files: Essentially this can be done with four properties: two on the WrapperFramework:
      • combineScripts
      • combineStylesheets and the same on each of the other frameworks. These can be set either individually, by providing a key:value pair instead of a string in the app config, or by setting it on the build.all setting.
    • Combine supportive frameworks as a whole, as separate frameworks, as a combination of combined and separate (can be done with single setting per framework), or as separate files. This can be selected through a setting on the app (combineFrameworks) and if a certain framework should not be included, it can be set through the combineSeparate setting.
    • Combine application, or separate files.
    • Combine application with supportive frameworks: setting on the app: combineWithFrameworks
    • Combine application with supportive frameworks + Sproutcore: combineAll

Another way of offering lots of options is to provide a urlPrefix template. This could get rid of a few properties (useHashedBuilds or something), because it gets calculated when it is necessary. For abbot this would be something like:

/static/@fwname/@language/@contentHash

It is not yet clear how this would work out when different configurations for different frameworks would be required...