From 689af787abbb6f0867ef0cbf1d9358025c01b778 Mon Sep 17 00:00:00 2001 From: Jacob Date: Fri, 9 Feb 2018 15:38:39 +0100 Subject: [PATCH] Support webpack chunks (css) (#715) * support webpack chunks (css & js) * fix quotes lint error * re-jig css ternary to be more grokable * fix lint violation * revert jsBundle & jsChunk change * clean up css list merge * restore cssChunk filtering & add support for both lists and single string * add case for multiple chunks * remove if branch for data.criticalCSS in HEADER_BUNDLE_MARKER * correct multi-chunk case expect copy-pasta --- .../lib/default-handlers.js | 14 ++++-- .../lib/react-webapp.js | 21 ++++++-- .../test/data/chunk-selector.js | 9 ++++ .../test/spec/hapi.index.spec.js | 49 +++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/packages/electrode-react-webapp/lib/default-handlers.js b/packages/electrode-react-webapp/lib/default-handlers.js index 7097bdc9b..3229ef48d 100644 --- a/packages/electrode-react-webapp/lib/default-handlers.js +++ b/packages/electrode-react-webapp/lib/default-handlers.js @@ -63,9 +63,17 @@ module.exports = function setup(options) { const manifest = bundleManifest(); const manifestLink = manifest ? `\n` : ""; const css = WEBPACK_DEV - ? data.devCSSBundle - : (data.cssChunk && `${prodBundleBase}${data.cssChunk.name}`) || ""; - const cssLink = css && !data.criticalCSS ? `` : ""; + ? Array.prototype.concat(data.devCSSBundle) + : Array.prototype.concat(data.cssChunk); + + const cssLink = css.reduce((acc, file) => { + acc += ``; + return acc; + }, ""); const htmlScripts = htmlifyScripts( groupScripts(routeOptions.unbundledJS.enterHead).scripts, diff --git a/packages/electrode-react-webapp/lib/react-webapp.js b/packages/electrode-react-webapp/lib/react-webapp.js index 6c242ae7a..81e9d5102 100644 --- a/packages/electrode-react-webapp/lib/react-webapp.js +++ b/packages/electrode-react-webapp/lib/react-webapp.js @@ -104,14 +104,27 @@ function makeRouteHandler(routeOptions, userContent) { } const chunkNames = chunkSelector(request); - const devCSSBundle = chunkNames.css - ? `${devBundleBase}${chunkNames.css}.style.css` - : `${devBundleBase}style.css`; + + let devCSSBundle; + if (chunkNames.css) { + const cssChunks = Array.isArray(chunkNames.css) + ? chunkNames.css + : [ chunkNames.css ]; + devCSSBundle = _.map( + cssChunks, + (chunkName) => `${devBundleBase}${chunkName}.style.css` + ); + } else devCSSBundle = [`${devBundleBase}style.css`]; + const devJSBundle = chunkNames.js ? `${devBundleBase}${chunkNames.js}.bundle.dev.js` : `${devBundleBase}bundle.dev.js`; const jsChunk = _.find(assets.js, asset => _.includes(asset.chunkNames, chunkNames.js)); - const cssChunk = _.find(assets.css, asset => _.includes(asset.chunkNames, chunkNames.css)); + const cssChunk = _.filter(assets.css, + asset => _.some(asset.chunkNames, + assetChunkName => _.includes(chunkNames.css, assetChunkName) + ) + ); const scriptNonce = cspScriptNonce ? ` nonce="${cspScriptNonce}"` : ""; const styleNonce = cspStyleNonce ? ` nonce="${cspStyleNonce}"` : ""; diff --git a/packages/electrode-react-webapp/test/data/chunk-selector.js b/packages/electrode-react-webapp/test/data/chunk-selector.js index 1038332f1..523f8a134 100644 --- a/packages/electrode-react-webapp/test/data/chunk-selector.js +++ b/packages/electrode-react-webapp/test/data/chunk-selector.js @@ -12,12 +12,21 @@ const DEFAULT_BUNDLE = { css: "home", js: "home" }; +const MULTI_BUNDLE = { + css: [ + "foo", + "bar" + ], + js: "home" +}; module.exports = request => { if (request.path.endsWith("/foo")) { return FOO_BUNDLE; } else if (request.path.endsWith("/bar")) { return BAR_BUNDLE; + } else if (request.path.endsWith("/multi-chunk")) { + return MULTI_BUNDLE; } else if (request.path.endsWith("/empty")) { return {}; } diff --git a/packages/electrode-react-webapp/test/spec/hapi.index.spec.js b/packages/electrode-react-webapp/test/spec/hapi.index.spec.js index 6afd5b617..5661f929b 100644 --- a/packages/electrode-react-webapp/test/spec/hapi.index.spec.js +++ b/packages/electrode-react-webapp/test/spec/hapi.index.spec.js @@ -226,6 +226,55 @@ describe("hapi electrode-react-webapp", () => { }); }); + it("should handle multiple entry points - multi-chunk", () => { + configOptions.bundleChunkSelector = "test/data/chunk-selector.js"; + configOptions.stats = "test/data/stats-test-multibundle.json"; + + return electrodeServer(config).then(server => { + return server + .inject({ + method: "GET", + url: "/multi-chunk" + }) + .then(res => { + expect(res.statusCode).to.equal(200); + expect(res.result).to.contain("foo.style.f07a873ce87fc904a6a5.css"); + expect(res.result).to.contain("bar.style.f07a873ce87fc904a6a5.css"); + expect(res.result).to.contain("home.bundle.f07a873ce87fc904a6a5.js"); + stopServer(server); + }) + .catch(err => { + stopServer(server); + throw err; + }); + }); + }); + + it("should handle multiple entry points - @dev multi-chunk", () => { + configOptions.bundleChunkSelector = "test/data/chunk-selector.js"; + configOptions.stats = "test/data/stats-test-multibundle.json"; + + process.env.WEBPACK_DEV = "true"; + return electrodeServer(config).then(server => { + return server + .inject({ + method: "GET", + url: "/multi-chunk" + }) + .then(res => { + expect(res.statusCode).to.equal(200); + expect(res.result).to.contain("http://127.0.0.1:2992/js/foo.style.css"); + expect(res.result).to.contain("http://127.0.0.1:2992/js/bar.style.css"); + expect(res.result).to.contain("http://127.0.0.1:2992/js/home.bundle.dev.js"); + stopServer(server); + }) + .catch(err => { + stopServer(server); + throw err; + }); + }); + }); + it("should handle multiple entry points - @dev @empty", () => { configOptions.bundleChunkSelector = "test/data/chunk-selector.js"; configOptions.stats = "test/data/stats-test-multibundle.json";