- 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
| 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) |
| # | |
| # Barebones HTML caching with Redis | |
| # | |
| redis = require("redis") | |
| client = redis.createClient() | |
| app.get '/', (req, res, next) -> | |
| # Check if the request is cached |
| // I have a Backbone model where I need to use the same API_URL variable | |
| // on the server and client. With Sharify it looks something like this... | |
| // app.js | |
| sharify.data = { API_URL: 'http://artsy.net/api/v1' }; | |
| app.use(sharify); | |
| // models/artwork.js | |
| var Backbone = require('backbone'), | |
| API_URL = require('sharify').data.API_URL; |
| # Pretending we have a module called rooter.. | |
| # Option #1 - Abstract only the shared portion | |
| # | |
| # Accepts a callback and the params. The callback takes (err, locals). | |
| # Rooter then injects locals into the express request, and when mixed into | |
| # Backbone it wraps the route handlers passing the locals as the first argument. | |
| # This splits the further handling of the routing to the respective server/client | |
| # routing engines. | |
| _ = require 'underscore' | |
| Backbone = require 'backbone' | |
| redis = require 'redis' | |
| module.exports = (artsyUrl) -> | |
| # For paginated routes, this will recursively fetch until the end of the set. | |
| # | |
| # @param {Object} options Backbone sync options like `success` and `error` |
| # API examples | |
| cache artist, 'fetch', success: -> | |
| #... | |
| cache artworks, 'fetchUntilEnd', success: (artworks) -> | |
| res.render artworks: artworks | |
| cache fair, 'fetchExhibitors', success: -> | |
| # ... | |
| # Implementation | |
| cache = (model, method, options) -> |
| # | |
| # A library of common cache helpers. If you need to do something more complex than | |
| # the naive query caching Backbone Cache Sync (https://github.com/artsy/backbone-cache-sync) | |
| # provides then it's recommended to wrap it up in a function in this lib. | |
| # | |
| _ = require 'underscore' | |
| { NODE_ENV, DEFAULT_CACHE_TIME, REDIS_URL } = require '../config' | |
| redis = require 'redis' | |
| client = null |
| # | |
| # Single sign on, follow the redirect, and render the page for authenticated routes. | |
| # | |
| { SECURE_ARTSY_URL } = require '../../config' | |
| request = require 'superagent' | |
| express = require 'express' | |
| qs = require 'querystring' | |
| app = module.exports = express() |
| class ArtworkAttrSelect extends React.Component { | |
| onChange(e) { | |
| this.setState({ disabled: true }) | |
| $.ajax({ | |
| url: `/artwork/${this.props.id}/attr`, | |
| type: 'PUT', | |
| data: { [this.props.attr]: e.target.value } | |
| }).then(() => this.setState({ disabled: false })) | |
| } |