Skip to content

Commit

Permalink
Maintain correctness when rewriting fastboot-capable apps
Browse files Browse the repository at this point in the history
Apps that are built with fastboot support contain a fastboot.manifest in their package.json. The manifest includes the names of JS and HTML files. These files may be renamed by broccoli-asset-rev.

Up until now, ember-cli-fastboot has been doing hacks to handle adjusting those references itself. But this requires it to have too much knowledge of broccoli-asset-rev, and it forces ember-cli-fastboot to run *after* broccoli-asset-rev, which is problematic for use-cases like ef4/prember#2.

This PR reverses that approach by considering fastboot.manifest a standard part of the built ember app that broccoli-asset-rev should know how to update for consistency when renaming files.

This PR includes a flag on the addon itself that we can use to migrate ember-cli-fastboot away from its hacky behavior.
  • Loading branch information
ef4 committed Nov 3, 2017
1 parent 1ad8086 commit 4e9aea2
Show file tree
Hide file tree
Showing 17 changed files with 139 additions and 3 deletions.
9 changes: 7 additions & 2 deletions index.js
Expand Up @@ -37,5 +37,10 @@ module.exports = {
this.app = app;
this.initializeOptions();
},
treeFor: function() {}
}
treeFor: function() {},

// ember-cli-fastboot uses the presence of this flag to give a
// helpful error if you're using an older version of this addon that
// doesn't know how to rewrite the fastboot manifest.
supportsFastboot: true
};
3 changes: 2 additions & 1 deletion lib/asset-rev.js
@@ -1,6 +1,7 @@
var defaults = require('./default-options');
var Fingerprint = require('./fingerprint');
var UseRev = require('broccoli-asset-rewrite');
var FastbootManifestRewrite = require('./fastboot-manifest-rewrite');

function AssetRev(inputTree, options) {
if (!(this instanceof AssetRev)) {
Expand Down Expand Up @@ -37,7 +38,7 @@ function AssetRev(inputTree, options) {
var fingerprintTree2 = Fingerprint(assetRewrite, this);
var assetRewrite2 = UseRev(fingerprintTree2, this);

return assetRewrite2;
return new FastbootManifestRewrite(assetRewrite2, this.assetMap);
}

module.exports = AssetRev;
42 changes: 42 additions & 0 deletions lib/fastboot-manifest-rewrite.js
@@ -0,0 +1,42 @@
/* jshint node: true */
"use strict";

var Filter = require('broccoli-persistent-filter');
var fs = require('fs');

module.exports = class FastbootManifestRewrite extends Filter {
constructor(inputNode, assetMap) {
super(inputNode, { annotation: 'broccoli-asset-rev/fastboot-manifest-rewrite'});
this.assetMap = assetMap;
this.extensions = ['json'];
}

getDestFilePath(relativePath) {
if (relativePath === 'package.json') {
return relativePath;
}
}

processString(contents, relativePath) {
var pkg = JSON.parse(contents);
if (pkg.fastboot && pkg.fastboot.manifest) {
var manifest = pkg.fastboot.manifest;
this._process(manifest, 'appFiles', true);
this._process(manifest, 'vendorFiles', true);
this._process(manifest, 'htmlFile', false);
return JSON.stringify(pkg);
}
return contents;
}

_process(manifest, key, asArray) {
if (manifest[key]) {
if (asArray) {
var assetMap = this.assetMap;
manifest[key] = manifest[key].map(function(filename){ return assetMap[filename] || filename; });
} else {
manifest[key] = this.assetMap[manifest[key]] || manifest[key];
}
}
}
};
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"broccoli-asset-rewrite": "^1.1.0",
"broccoli-filter": "^1.2.2",
"broccoli-persistent-filter": "^1.4.3",
"json-stable-stringify": "^1.0.0",
"minimatch": "^3.0.4",
"rsvp": "^3.0.6"
Expand Down
15 changes: 15 additions & 0 deletions tests/filter-tests.js
Expand Up @@ -416,4 +416,19 @@ describe('broccoli-asset-rev', function() {
fs.statSync.restore()
});
});

it('rewrites the fastboot manifest', function(){
var sourcePath = 'tests/fixtures/fastboot';

var node = AssetRev(sourcePath + '/input', {
extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map'],
replaceExtensions: ['html', 'js', 'css']
});

builder = new broccoli.Builder(node);
return builder.build().then(function(graph) {
confirmOutput(graph.directory, sourcePath + '/output');
});
});

});
5 changes: 5 additions & 0 deletions tests/fixtures/fastboot/input/assets/application.js
@@ -0,0 +1,5 @@
const translations = {
en: 'translations/en.json'
};

console.log('Hello World');
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/fastboot/input/images/sample.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions tests/fixtures/fastboot/input/index.html
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">

<title>Application</title>

<link rel="stylesheet" href="/styles.css">
<link rel="icon" href="/images/icons/favicon.png">
</head>
<body>
<script type="text/javascript" src="/assets/application.js"></script>
<script type="text/javascript" src=/assets/application.js></script>
</body>
</html>
9 changes: 9 additions & 0 deletions tests/fixtures/fastboot/input/package.json
@@ -0,0 +1,9 @@
{
"fastboot": {
"manifest": {
"appFiles": ["assets/application.js"],
"htmlFile": "index.html",
"vendorFiles": []
}
}
}
11 changes: 11 additions & 0 deletions tests/fixtures/fastboot/input/styles.css
@@ -0,0 +1,11 @@
.sample-img {
width: 50px;
height: 50px;
background-image: url(images/sample.png);
}

.sample-img2 {
width: 50px;
height: 50px;
background-image: url('images/sample.png');
}
@@ -0,0 +1,5 @@
const translations = {
en: 'translations/en.json'
};

console.log('Hello World');
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions tests/fixtures/fastboot/output/index.html
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">

<title>Application</title>

<link rel="stylesheet" href="/styles-0315ae5ce5f11670cbdea72c9bea621a.css">
<link rel="icon" href="/images/icons/favicon-9243e67fccd0c5e08a3d2c158af6500d.png">
</head>
<body>
<script type="text/javascript" src="/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js"></script>
<script type="text/javascript" src=/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js></script>
</body>
</html>
1 change: 1 addition & 0 deletions tests/fixtures/fastboot/output/package.json
@@ -0,0 +1 @@
{"fastboot":{"manifest":{"appFiles":["assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js"],"htmlFile":"index.html","vendorFiles":[]}}}
@@ -0,0 +1,11 @@
.sample-img {
width: 50px;
height: 50px;
background-image: url(images/sample-1f6b78f1b4667adc7e397f7bf94041ab.png);
}

.sample-img2 {
width: 50px;
height: 50px;
background-image: url('images/sample-1f6b78f1b4667adc7e397f7bf94041ab.png');
}

0 comments on commit 4e9aea2

Please sign in to comment.