Using Meteor as frontend library!

Update I found a better way of doing this: https://github.com/SpaceCapsule/packmeteor This takes the current app running at http://localhost:3000 and packs the frontend part conveniently.


If you’re impatient go here: https://github.com/frozeman/MeteorFrontend

Meteor is awesome, i loved it immediately as i saw the video. The way you can build one page apps is absolutely intuitive. I struggled with Ember.js, Backbone.js and AngularJS (which clutter the HTML too much), but Meteor really got it, in my opinion.

The problem with Meteor is that it forces you to use the full-stack. Natively there is currently no easy way to separate the frontend from the server in Meteor.

As i’m using Meteor to build the awesome TunedIn WebApp and we have already an existing API, i was in the need to split Meteor. Out of any need comes a solution so i wrote a grunt script which takes care of this automatically.

Automated Meteor decoupling

The script runs the $ meteor bundle ... command, extracts the bundle and copies the frontend part to the dist/ folder. It even takes care of adding the required __meteor_runtime_config__ variable to the resulting index.html.

In detail the process will do the following tasks:

// empties the "bundle/" folder
'clean:bundle',
// bundles your meteor app
'shell:bundleMeteor',
// extract the bundle.tar to the "bundle/" folder
'shell:extractMeteorBundle',
// cleans the "dist/" folder and deletes the bundle.tar
'clean:dist',
// copies all the client files to the "dist/" folder
'copy',
// renames the app.html -> index.html
'rename',
// replaces the placeholders in the index.html with the __meteor_runtime_config__ variable
'string-replace',
// starts the server to test your distribution at http://localhost:9000
'connect:dist'

Download the repo and try it yourself: https://github.com/frozeman/MeteorFrontend

Hints

When only using meteors frontend you have to keep a few things in mind.

Add your js files to the app/client/ folder, as meteor then for sure knows where they belong, and you don’t have to deal with the Meteor.isClient variable.

You need to change the ROOT_URL variable in the Gruntfile.js and set it to the URL of your server, where you want it to deploy.

Additional you need to disconnect from the Meteor server, as he otherwise constantly tries to reconnect. Just add these lines to your code:

Meteor.connection._stream._retryTimeout = function(){ return 365 * 24 * 60 * 60 * 1000};
Meteor.connection._stream._lostConnection();

Those make sure he won’t try to reconnect for the next 1000 years :)

Note: this package uses meteor 0.6.5, if you want to use a previous version, change the lines above to Meteor.default_connection._stream...

Collections

When you want to use a local collection for storing data and create some nice reactivity you need to create unmanaged collections like this:

var myCollection = new Meteor.Collection('myCollection', {connection: null});

if you’re using a version of Meteor previous 0.6.5 you only can create one unnamed unmanaged collection like this:

var myCollection = new Meteor.Collection(null);

Images

All files inside the app/public/ folder will be copied to the root of your web server (or the dist/ folder) and you won’t need to change any paths.

Meteor packages

To slim down meteor you can also remove the standard-app-packages package and add the following packages back to your app/.meteor/packages file (or manually with $ meteor add ...)

I’m not quite sure, if they are all really needed, as there is no real description for the core packages. I just removed the ones, which i guess contact the server, any suggestions are welcome.

meteor
session
deps
templating
spark
handlebars
universal-events
startup
preserve-inputs
service-configuration
audit-argument-checks
check
underscore
json
jsparse
liverange
localstorage
logging
minimongo
ordered-dict
reactive-dict
reload
amplify
http
webapp
minifiers

Conclusion

Using this grunt script makes it fairly easy, so go ahead and download it here: https://github.com/frozeman/MeteorFrontend

Please comment, i’m happy to hear any suggestions!

6 Pingbacks/Trackbacks

  • Nate

    *too much

    • frozeman

      too much of what?

      • greaterweb

        I think name was pointing out:

        which clutter the HTML *too much

        • greaterweb

          Nate event :-)

        • frozeman

          angular.js uses declarative attributes and this clutters the HTML, IMHO :)

          i like that meteor, with the use of handlebars keeps the clutter very small. everything is basically nicely described inside the Template.myTemplate.methods = function() {...}

    • frozeman

      ah, now i got it, spelling…

  • Zach

    Very interesting. I was actually looking for a good way to do this the past couple of days (if this does what I think it does). So would it be possible to use this with a Rails API for the backend but still benefit from meteor’s front end features?

    • frozeman

      absolutely!
      This is what i do too. The only disadvantage currently is that its tries to make one request, when you open the website, to connect to the server, so this will show up as an error in the console.

      • Zach

        I’d love to try this out but still pretty new to Meteor and not sure exactly how to go about it. Would I create unmanaged collections using data from the rails app and it would just work or would I need to manually update the rails app’s database using ddp with publish/subscribe? If you have time I would be in your debt for some code examples on how to do this. I’ll experiment with this though, and thanks a ton for MeteorFrontend.

        • frozeman

          i wrote an APIController, where i request our API to get some data. I then store this data in my local (unmanaged) collections and use it to display data in the frontend (e.g. using the {{#each}} helper).

          This way i can control when my data gets refreshed/loaded and i still have the nice reactivity from Meteor.collection() :)

          but to answer your question, yeah you have to manually update the Rails DB, in the backend.

          • Zach

            Ok awesome, that’s kind of what I was thinking.

            I’m getting caught on one problem though. Say a record gets deleted from a local collection, how would I capture that and send the info to the Rails API but at the same time if the request fails from Rails then add the deleted record back into the collection.

            This also brings up the question if something changes in the Rails DB, will it be instantly reflected in every client that is connected like meteor does normally?

          • frozeman

            if you want full reactivity across clients, its definitely better to to use the meteor full-stack, or implement your own DDP client/server.

            When i change data, i first change it on the server, and when this succeeded i then remove it from the local collection.

          • Zach

            Ah ok, makes sense. Thanks a ton for your help.

  • Chris

    I’ve spent a lot of time with Meteor and also Backbone. Give Ember.js another try. It has it right and, in my opinion at this stage (but things change all the time!), Meteor doesn’t. If you’re ever interested in some training, get in touch with me.

    • frozeman

      thanks, but i’m already pretty far in my progress and meteor is a perfect fit…

  • olragon

    Totally agree with you! Thank you for your very useful post.

  • frozeman

    I posted this on the meteor-core google-groups for discussion, as i really would like to see a frontend only version of meteor.
    https://groups.google.com/forum/#!topic/meteor-core/7qmpbXaW9HI

  • Pingback: Pie in the Sky (August 23, 2013) | MSDN Blogs()

  • Pingback: Using Meteor as frontend library! | JavaScript ...()

  • Pingback: Using Meteor as frontend library! | Development...()

  • Pingback: Joy Poston()

  • Pingback: Using Meteor as frontend library! | Front End P...()

  • Stephen Pope

    You can actually use meteor as a front end directly. In meteor 0.6.5 you can remove the standard packages, one of which is the web server and simply bundle the app and use the client. You’ll be good to go.

    • frozeman

      Tried that. As you can read further down in the article, i’m quite aware of that :)
      The problem comes, that meteor still creates a folder and server structure, which need additional moving of files etc.

      my grunt script takes care of everything, so you can put it on any server, as a soley client side app.

      do you have any idea, which packages are actually only client side?

  • Pingback: URL()