- Slow initial page render
- Performance issues/quirks between maintaing two apps in one.
- Duplicating logic on client/server
- Client-side code is a second-class citizen
# | |
# Barebones HTML caching with Redis | |
# | |
redis = require("redis") | |
client = redis.createClient() | |
app.get '/', (req, res, next) -> | |
# Check if the request is cached |
describe 'LocationView', -> | |
before (done) -> | |
clientenv.prepare '../client/location_view', module, | |
serverTemplate: | |
filename: '../templates/index.jade' | |
locals: { sd: {} } | |
clientTemplates: ['template'] | |
done: (mod) => | |
{ @LocationView } = mod | |
@view = new @LocationView(state: @state, user: @user) |
Frameworks like Rendr, Derby, and Meteor try to create this magical environment where you can stop thinking about whether your code is running on the client or server. This seems to lead to learning a bunch of concepts unique to the framework that define this "shared" environment. Sometimes that can feel like a leaky abstraction (what is a server-side Backbone view?), or lock you in to the full stack to make it work (Derby/Meteor backed by a REST API instead of mongo?).
Instead of tackling the massive problem of trying to abstract away the server and client, lets acknowledge they're completely different and embrace using modules of code that we can reasonably expect to work on both sides.
I've tried Backbone relational before and hadn't had a great experience with it. Although that was a long time ago, and it may be robust enough to make sense now. Regardless, personally I'm not even sure built in relations have a place as a Backbone library (I even remember a talk by jashkenas where he briefly mentions not supporting relations/nested models in Backbone because Backbone core peeps though it was a bad idea). My experience tends to agree because API conventions can vary quite a-lot, even just in our own API. There tend to be more edge cases to handle than makes it worth saving a couple lines of code here an there.
I had attempted to write my own relational library for Backbone back in the day. But ultimately decided to drop it because of this exact point, it felt like a leaky abstraction. Instead I opted for a light-weight mixin for relations that Torque/Inertia uses. Although that has mostly be
{ | |
"name": "juliacolavita.com", | |
"subdomain": "juliacolavita", | |
"domains": [ | |
"juliacolavita.com", | |
"www.juliacolavita.com" | |
], | |
"version": "0.0.1-23", | |
"private": true, | |
"engines": { |
info: Welcome to Nodejitsu craigspaeth | |
info: jitsu v0.9.7 | |
info: It worked if it ends with Nodejitsu ok | |
info: Executing command restart | |
info: Restarting app juliacolavita.com | |
error: Error running command restart | |
error: Nodejitsu Error (500): Internal Server Error | |
warn: Error returned from Nodejitsu | |
error: Error: Application has not been started yet. | |
error: at module.exports (/root/nodejitsu/lib/nodejitsu/resources/app/controller/restart.js:26:23) |
# | |
# Wraps `get` and `set` to wrap raw data with instances of models. Also wraps `toJSON` | |
# to give better serialized output. | |
# mixin with _.extend @prototype, Backbone.Relations | |
# | |
# e.g. | |
# | |
# class Paws extends Backbone.Collection | |
# class Dog extends Backbone.Model | |
# _.extend @prototype, Backbone.Relations |
# | |
# Mixin to a router to wrap `route` so that it clears ajax requests and transitions frames. | |
# | |
Backbone.FrameManager = | |
# | |
# Declare regex: frame pairs. If the route matches the regex it will create an instance | |
# of the frame once, and activate/deactivate that view from there on. | |
# | |
# A "frame" is a high-level view associated with an element that is a child of the #frames div. |