of your potential users will inevitably be left out in the cold. But if you start by building on a classic server/ client model, and then enhance with JavaScript, you can have your cake and eat it too. Jeremy Keith
and response and injects * it into the application instance. */ function registerFastBootInfo(req, res) { return function(instance) { var info = new FastBootInfo(req, res); info.register(instance); return instance; }; } ember-fastboot-server/lib/ember-app.js
current HTTP request from FastBoot. This is injected * on to the FastBoot service. */ function FastBootInfo(request, response) { this.request = request; this.response = response; this.cookies = this.extractCookies(request); this.headers = request.headers; } FastBootInfo.prototype.extractCookies = function(request) { // If cookie-parser middleware has already parsed the cookies, // just use that. if (request.cookies) { return request.cookies; } // Otherwise, try to parse the cookies ourselves, if they exist. var cookies = request.get('cookie'); if (cookies) { return cookie.parse(cookies); } // Return an empty object instead of undefined if no cookies are present. return {}; }; /* * Registers this FastBootInfo instance in the registry of an Ember * ApplicationInstance. It is configured to be injected into the FastBoot * service, ensuring it is available inside instance initializers. */ FastBootInfo.prototype.register = function(instance) { instance.register('info:-fastboot', this, { instantiate: false }); instance.inject('service:fastboot', '_fastbootInfo', 'info:-fastboot'); }; ember-fastboot-server/lib/ember-app.js
a running `Application`. At a high-level, we break application boot into two distinct phases: * Definition time, where all of the classes, templates, and other dependencies are loaded (typically in the browser). * Run time, where we begin executing the application once everything has loaded. Definition time can be expensive and only needs to happen once since it is an idempotent operation. For example, between test runs and FastBoot requests, the application stays the same. It is only the state that we want to reset. That state is what the `ApplicationInstance` manages: it is responsible for creating the container that contains all application state, and disposing of it once the particular test run or FastBoot request has finished. @public @class Ember.ApplicationInstance @extends Ember.EngineInstance */ ember.js/packages/ember-application/lib/system/application-instance.js
* resulting DOM element into HTML to be transmitted back to the user agent. */ function serializeHTML(doc, rootElement) { return function(instance) { var head; if (doc.head) { head = HTMLSerializer.serialize(doc.head); } try { return { url: instance.getURL(), // TODO: use this to determine whether to 200 or redirect title: doc.title, head: head, body: HTMLSerializer.serialize(rootElement) }; } finally { instance.destroy(); } }; } ember-fastboot-server/lib/ember-app.js
renames it to the // normalized `fetch.js`. That shim file calls `FastBoot.require`, which allows // you to require node modules (in this case `node-fetch`) in FastBoot mode. function treeForNodeFetch() { return normalizeFileName(funnel(path.join(__dirname, './assets'), { files: ['fastboot-fetch.js'], })); }