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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const translations = {
en: 'translations/en.json'
};

console.log('Hello World');
Loading
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
Loading
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const translations = {
en: 'translations/en.json'
};

console.log('Hello World');
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"fastboot":{"manifest":{"appFiles":["assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js"],"htmlFile":"index.html","vendorFiles":[]}}}
Original file line number Diff line number Diff line change
@@ -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.