-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from trentmwillis/node
Enable the asset-manifest to be present in SSR environments
- Loading branch information
Showing
10 changed files
with
166 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,23 @@ | ||
import environment from './config/environment'; | ||
|
||
const metaName = environment.modulePrefix + '/asset-manifest'; | ||
const modulePrefix = environment.modulePrefix; | ||
const metaName = `${modulePrefix}/asset-manifest`; | ||
const nodeName = `${modulePrefix}/node-asset-manifest`; | ||
|
||
let config = {}; | ||
|
||
try { | ||
const rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content'); | ||
config = JSON.parse(unescape(rawConfig)); | ||
// If we have a Node version of the asset manifest, use that for FastBoot and | ||
// similar environments. | ||
if (require.has(nodeName)) { | ||
config = require(nodeName).default; // eslint-disable-line | ||
} else { | ||
const rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content'); | ||
config = JSON.parse(unescape(rawConfig)); | ||
} | ||
} catch(err) { | ||
throw new Error('Could not read asset manifest from meta tag with name "' + metaName + '".'); | ||
throw new Error('Failed to load asset manifest. For browser environments, verify the meta tag with name "'+ metaName + | ||
'" is present. For non-browser environments, verify that you included the node-asset-manifest module.'); | ||
} | ||
|
||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
var Plugin = require('broccoli-caching-writer'); | ||
var walk = require('walk-sync'); | ||
var path = require('path'); | ||
var fs = require('fs-extra'); | ||
|
||
/** | ||
* A Broccoli plugin to generate a module to be used in Node for resolving the | ||
* asset manifest. Primary use case is for FastBoot like environments. | ||
* | ||
* @class NodeAssetManifestGenerator | ||
* @extends BroccoliCachingWriter | ||
*/ | ||
function NodeAssetManifestGenerator(inputTrees, options) { | ||
options = options || {}; | ||
|
||
this.appName = options.appName; | ||
|
||
Plugin.call(this, [ inputTrees ], { | ||
annotation: options.annotation | ||
}); | ||
} | ||
|
||
NodeAssetManifestGenerator.prototype = Object.create(Plugin.prototype); | ||
NodeAssetManifestGenerator.prototype.constructor = NodeAssetManifestGenerator; | ||
|
||
/** | ||
* Generates an asset manifest module on build from the passed in | ||
* asset-manifest.json file. | ||
*/ | ||
NodeAssetManifestGenerator.prototype.build = function() { | ||
var inputPath = this.inputPaths[0]; | ||
var assetManifestPath = path.join(inputPath, 'asset-manifest.json'); | ||
var assetManifest = fs.readJsonSync(assetManifestPath); | ||
|
||
var moduleTemplatePath = path.join(__dirname, './utils/node-module-template.js'); | ||
var moduleTemplate = fs.readFileSync(moduleTemplatePath, 'utf-8'); | ||
var module = moduleTemplate | ||
.replace('APP_NAME', this.appName) | ||
.replace('ASSET_MANIFEST', JSON.stringify(assetManifest)); | ||
|
||
var outputAssets = path.join(this.outputPath, 'assets'); | ||
fs.mkdirSync(outputAssets); | ||
|
||
var nodeModuleFile = path.join(outputAssets, 'node-asset-manifest.js'); | ||
fs.writeFileSync(nodeModuleFile, module); | ||
}; | ||
|
||
module.exports = NodeAssetManifestGenerator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* eslint-disable */ | ||
define('APP_NAME/node-asset-manifest', function() { | ||
return { | ||
default: ASSET_MANIFEST | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* global require */ | ||
|
||
import { module, test } from 'qunit'; | ||
|
||
module('Unit | asset-manifest', { | ||
beforeEach() { | ||
resetModules(); | ||
this.originalNodeModule = require.entries['dummy/node-asset-manifest']; | ||
}, | ||
|
||
afterEach() { | ||
require.entries['dummy/node-asset-manifest'] = this.originalNodeModule; | ||
resetModules(); | ||
} | ||
}); | ||
|
||
function resetModules() { | ||
require.unsee('dummy/node-asset-manifest'); | ||
require.unsee('dummy/asset-manifest'); | ||
} | ||
|
||
test('node-asset-manifest is generated properly', function(assert) { | ||
const nodeManifest = require('dummy/node-asset-manifest').default; | ||
delete require.entries['dummy/node-asset-manifest']; | ||
|
||
const manifest = require('dummy/asset-manifest').default; | ||
|
||
assert.notStrictEqual(nodeManifest, manifest); | ||
assert.deepEqual(nodeManifest, manifest); | ||
}); | ||
|
||
test('loads the node-asset-manifest if present', function(assert) { | ||
const replacementModule = {}; | ||
define('dummy/node-asset-manifest', () => ({ default: replacementModule})); | ||
|
||
assert.strictEqual(require('dummy/asset-manifest').default, replacementModule); | ||
}); | ||
|
||
test('loads the manifest from the meta tag if available', function(assert) { | ||
delete require.entries['dummy/node-asset-manifest']; | ||
|
||
const meta = document.querySelector('meta[name="dummy/asset-manifest"]'); | ||
const metaContent = meta.getAttribute('content'); | ||
meta.setAttribute('content', '{"derp":"herp"}'); | ||
assert.deepEqual(require('dummy/asset-manifest').default, { derp: 'herp' }); | ||
meta.setAttribute('content', metaContent); | ||
}); | ||
|
||
test('throws an error if unable to load the manifest', function(assert) { | ||
delete require.entries['dummy/node-asset-manifest']; | ||
|
||
const meta = document.querySelector('meta[name="dummy/asset-manifest"]'); | ||
const metaContent = meta.getAttribute('content'); | ||
meta.setAttribute('content', 'herp'); | ||
assert.throws(() => assert.deepEqual(require('dummy/asset-manifest').default, {})); | ||
meta.setAttribute('content', metaContent); | ||
}); |