From 4e9aea23c45c8fe0994920d415bc624e3bc137b7 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Thu, 2 Nov 2017 23:10:45 -0400 Subject: [PATCH] Maintain correctness when rewriting fastboot-capable apps 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 https://github.com/ef4/prember/issues/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. --- index.js | 9 +++- lib/asset-rev.js | 3 +- lib/fastboot-manifest-rewrite.js | 42 ++++++++++++++++++ package.json | 1 + tests/filter-tests.js | 15 +++++++ .../fastboot/input/assets/application.js | 5 +++ .../fastboot/input/images/icons/favicon.png | Bin 0 -> 937 bytes .../fixtures/fastboot/input/images/sample.png | Bin 0 -> 937 bytes tests/fixtures/fastboot/input/index.html | 15 +++++++ tests/fixtures/fastboot/input/package.json | 9 ++++ tests/fixtures/fastboot/input/styles.css | 11 +++++ ...cation-b55acd2e0e4c88b3d29cb7fdbc768eb5.js | 5 +++ ...vicon-9243e67fccd0c5e08a3d2c158af6500d.png | Bin 0 -> 937 bytes ...ample-1f6b78f1b4667adc7e397f7bf94041ab.png | Bin 0 -> 937 bytes tests/fixtures/fastboot/output/index.html | 15 +++++++ tests/fixtures/fastboot/output/package.json | 1 + ...tyles-0315ae5ce5f11670cbdea72c9bea621a.css | 11 +++++ 17 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 lib/fastboot-manifest-rewrite.js create mode 100644 tests/fixtures/fastboot/input/assets/application.js create mode 100644 tests/fixtures/fastboot/input/images/icons/favicon.png create mode 100644 tests/fixtures/fastboot/input/images/sample.png create mode 100644 tests/fixtures/fastboot/input/index.html create mode 100644 tests/fixtures/fastboot/input/package.json create mode 100644 tests/fixtures/fastboot/input/styles.css create mode 100644 tests/fixtures/fastboot/output/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js create mode 100644 tests/fixtures/fastboot/output/images/icons/favicon-9243e67fccd0c5e08a3d2c158af6500d.png create mode 100644 tests/fixtures/fastboot/output/images/sample-1f6b78f1b4667adc7e397f7bf94041ab.png create mode 100644 tests/fixtures/fastboot/output/index.html create mode 100644 tests/fixtures/fastboot/output/package.json create mode 100644 tests/fixtures/fastboot/output/styles-0315ae5ce5f11670cbdea72c9bea621a.css diff --git a/index.js b/index.js index 520748c..0ead079 100644 --- a/index.js +++ b/index.js @@ -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 +}; diff --git a/lib/asset-rev.js b/lib/asset-rev.js index b2ab203..24135e2 100644 --- a/lib/asset-rev.js +++ b/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)) { @@ -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; diff --git a/lib/fastboot-manifest-rewrite.js b/lib/fastboot-manifest-rewrite.js new file mode 100644 index 0000000..16dc1f8 --- /dev/null +++ b/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]; + } + } + } +}; diff --git a/package.json b/package.json index bd3aba0..75cad4f 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/tests/filter-tests.js b/tests/filter-tests.js index 79dd442..4fa5571 100644 --- a/tests/filter-tests.js +++ b/tests/filter-tests.js @@ -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'); + }); + }); + }); diff --git a/tests/fixtures/fastboot/input/assets/application.js b/tests/fixtures/fastboot/input/assets/application.js new file mode 100644 index 0000000..0ba8818 --- /dev/null +++ b/tests/fixtures/fastboot/input/assets/application.js @@ -0,0 +1,5 @@ +const translations = { + en: 'translations/en.json' +}; + +console.log('Hello World'); diff --git a/tests/fixtures/fastboot/input/images/icons/favicon.png b/tests/fixtures/fastboot/input/images/icons/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..3db835bdf3a84edfb6e93acae0f7e73b5e22bfcb GIT binary patch literal 937 zcmaJ=yN=U96t$KHMT)cy;?<12TP%opY$s0QQOs&%C&UttqHH8m?!=xXR@NRfo)9PH zc9e8<6!iQ61&EGc;1g(ohMI9U$x;wpc<#MA=iJBKdEM(iD;6FUBuOf|9j7nO+%DWc z5dVYT@Vhwf^VX1`(=lIQMx?WVjtFogJRyC8gXPPwq#;SSPQt;E554Eer;&nljFLr( zU`tZtG)u5QBOHv#B#bTj$Hz}H2m?!gVR)*S*kl@ZR*amlx&wbT^UXj$eF_>G5&{w7 z7-Z39oTAK<*Sbj9c^JxI4dF9OzAkF$^?*$o0ftg7`Knd{HB-@yYR#-Y0lM&^T8Fw? zQcYx(k*b5uCyQ(>7^A+^-sBRVB~Lj|5QK}xLRpj*$|g`VO%tj*)b)};l+tC)aaM}c zqpgBNQlEth4`~c?MLeQ&Zpot3>lUJ9CmW}mF^Pe}3@1=i)V!rF(DVKejiMbo<$ZEf z?>~jp!7?GRPf|K(zPPyYQJyM6HY1o*HlXx!JH_6Va+*$Q0&IIdHE`l#KaBI>qczL( zkQ=8Q$3Af#OBOmx7zW66nue~awQ9YpYFeveYVBs*&<(9pc3Lf4-Etl3&m$7^EjPH~ z*7tJrg@_W7*&!@^MS?b?5m+~l!u_=vd-XQlV1F&uy<8}Yf%*0Rb=}*L*rD9qEw6BP z>rY~_^Gq!FyF0%R#lyJkI%k9I+bF;oe=feg_w(w_p7c(;R~U literal 0 HcmV?d00001 diff --git a/tests/fixtures/fastboot/input/images/sample.png b/tests/fixtures/fastboot/input/images/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..cdfaf5e593f5028afeb8a25384f69e00944ce1cd GIT binary patch literal 937 zcmaJ=zi-n(6gEXjC{iUBgec3^S&G#7Y$s0YQ%u#^3AKc)C=DV50~h;}SgC!7eIZUJ z1QY)Z8w(6Du<#FbU}9om;a}jK#wi2AgYUhk@B7}5d-tw;_IS6nSCS-Y*FAN5;>_*R z?H%#o=?;F0<34W>_&FW%IZlXl63`(5ZiL6AM{uxs`HeIs>E=P$AMklaE?*3 zhzYhNHIFlf{VCyKNXB7o$-h5+mO&U;@-xFzJ!X?hc)Co;`SPsqFQ>j4$j6UBGebfk zA{>J(x`=&*`jl3D1%zoHGRBd_Gs^RfQ&FsF|h-RUPVjMIb8aBIY=& z#A&%ua7gMWA>$#9L9U30bjB@NRC?7y#5S^Vx*n4l7|bw(nxf_{6+qAXKQxLq=#=-! zb-n)-PWuZ+V2`A9miXf0M&&#eLv}(ir%9jEi(-o13FS1MPzG#!H8pVHVLy!X;KLQm z^N<^-9LGL!9ZMEEN*D&nbXtb4snz;XUDdR9&D1)rj-eY`t?IPfwpwr<>dzt)^MV^( zb8B0<`9efYWOhgrz9K;7G=Xj}Ex++cex`c^I!#lZY}|GMrXBz7n_H_I!W z&H9sA?0h1Yo9*AZD;~x@*E#8D--m~#=U-nxP_-Yo%1`&e7wO}N8;hTBFE8`Q + + + + + Application + + + + + + + + + diff --git a/tests/fixtures/fastboot/input/package.json b/tests/fixtures/fastboot/input/package.json new file mode 100644 index 0000000..b5f7a82 --- /dev/null +++ b/tests/fixtures/fastboot/input/package.json @@ -0,0 +1,9 @@ +{ + "fastboot": { + "manifest": { + "appFiles": ["assets/application.js"], + "htmlFile": "index.html", + "vendorFiles": [] + } + } +} diff --git a/tests/fixtures/fastboot/input/styles.css b/tests/fixtures/fastboot/input/styles.css new file mode 100644 index 0000000..6b1dcc8 --- /dev/null +++ b/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'); +} diff --git a/tests/fixtures/fastboot/output/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js b/tests/fixtures/fastboot/output/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js new file mode 100644 index 0000000..0ba8818 --- /dev/null +++ b/tests/fixtures/fastboot/output/assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js @@ -0,0 +1,5 @@ +const translations = { + en: 'translations/en.json' +}; + +console.log('Hello World'); diff --git a/tests/fixtures/fastboot/output/images/icons/favicon-9243e67fccd0c5e08a3d2c158af6500d.png b/tests/fixtures/fastboot/output/images/icons/favicon-9243e67fccd0c5e08a3d2c158af6500d.png new file mode 100644 index 0000000000000000000000000000000000000000..3db835bdf3a84edfb6e93acae0f7e73b5e22bfcb GIT binary patch literal 937 zcmaJ=yN=U96t$KHMT)cy;?<12TP%opY$s0QQOs&%C&UttqHH8m?!=xXR@NRfo)9PH zc9e8<6!iQ61&EGc;1g(ohMI9U$x;wpc<#MA=iJBKdEM(iD;6FUBuOf|9j7nO+%DWc z5dVYT@Vhwf^VX1`(=lIQMx?WVjtFogJRyC8gXPPwq#;SSPQt;E554Eer;&nljFLr( zU`tZtG)u5QBOHv#B#bTj$Hz}H2m?!gVR)*S*kl@ZR*amlx&wbT^UXj$eF_>G5&{w7 z7-Z39oTAK<*Sbj9c^JxI4dF9OzAkF$^?*$o0ftg7`Knd{HB-@yYR#-Y0lM&^T8Fw? zQcYx(k*b5uCyQ(>7^A+^-sBRVB~Lj|5QK}xLRpj*$|g`VO%tj*)b)};l+tC)aaM}c zqpgBNQlEth4`~c?MLeQ&Zpot3>lUJ9CmW}mF^Pe}3@1=i)V!rF(DVKejiMbo<$ZEf z?>~jp!7?GRPf|K(zPPyYQJyM6HY1o*HlXx!JH_6Va+*$Q0&IIdHE`l#KaBI>qczL( zkQ=8Q$3Af#OBOmx7zW66nue~awQ9YpYFeveYVBs*&<(9pc3Lf4-Etl3&m$7^EjPH~ z*7tJrg@_W7*&!@^MS?b?5m+~l!u_=vd-XQlV1F&uy<8}Yf%*0Rb=}*L*rD9qEw6BP z>rY~_^Gq!FyF0%R#lyJkI%k9I+bF;oe=feg_w(w_p7c(;R~U literal 0 HcmV?d00001 diff --git a/tests/fixtures/fastboot/output/images/sample-1f6b78f1b4667adc7e397f7bf94041ab.png b/tests/fixtures/fastboot/output/images/sample-1f6b78f1b4667adc7e397f7bf94041ab.png new file mode 100644 index 0000000000000000000000000000000000000000..cdfaf5e593f5028afeb8a25384f69e00944ce1cd GIT binary patch literal 937 zcmaJ=zi-n(6gEXjC{iUBgec3^S&G#7Y$s0YQ%u#^3AKc)C=DV50~h;}SgC!7eIZUJ z1QY)Z8w(6Du<#FbU}9om;a}jK#wi2AgYUhk@B7}5d-tw;_IS6nSCS-Y*FAN5;>_*R z?H%#o=?;F0<34W>_&FW%IZlXl63`(5ZiL6AM{uxs`HeIs>E=P$AMklaE?*3 zhzYhNHIFlf{VCyKNXB7o$-h5+mO&U;@-xFzJ!X?hc)Co;`SPsqFQ>j4$j6UBGebfk zA{>J(x`=&*`jl3D1%zoHGRBd_Gs^RfQ&FsF|h-RUPVjMIb8aBIY=& z#A&%ua7gMWA>$#9L9U30bjB@NRC?7y#5S^Vx*n4l7|bw(nxf_{6+qAXKQxLq=#=-! zb-n)-PWuZ+V2`A9miXf0M&&#eLv}(ir%9jEi(-o13FS1MPzG#!H8pVHVLy!X;KLQm z^N<^-9LGL!9ZMEEN*D&nbXtb4snz;XUDdR9&D1)rj-eY`t?IPfwpwr<>dzt)^MV^( zb8B0<`9efYWOhgrz9K;7G=Xj}Ex++cex`c^I!#lZY}|GMrXBz7n_H_I!W z&H9sA?0h1Yo9*AZD;~x@*E#8D--m~#=U-nxP_-Yo%1`&e7wO}N8;hTBFE8`Q + + + + + Application + + + + + + + + + diff --git a/tests/fixtures/fastboot/output/package.json b/tests/fixtures/fastboot/output/package.json new file mode 100644 index 0000000..2df411e --- /dev/null +++ b/tests/fixtures/fastboot/output/package.json @@ -0,0 +1 @@ +{"fastboot":{"manifest":{"appFiles":["assets/application-b55acd2e0e4c88b3d29cb7fdbc768eb5.js"],"htmlFile":"index.html","vendorFiles":[]}}} \ No newline at end of file diff --git a/tests/fixtures/fastboot/output/styles-0315ae5ce5f11670cbdea72c9bea621a.css b/tests/fixtures/fastboot/output/styles-0315ae5ce5f11670cbdea72c9bea621a.css new file mode 100644 index 0000000..a40610c --- /dev/null +++ b/tests/fixtures/fastboot/output/styles-0315ae5ce5f11670cbdea72c9bea621a.css @@ -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'); +}