Skip to content

Commit

Permalink
Inline webpack runtime js bundle for production (#1662)
Browse files Browse the repository at this point in the history
  • Loading branch information
yishengjiang99 authored Jun 2, 2020
1 parent 898bc6b commit cf64c59
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 10 deletions.
33 changes: 24 additions & 9 deletions packages/subapp-web/lib/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,12 @@ module.exports = function setup(setupContext) {
const distDir = process.env.NODE_ENV === "production" ? "../dist/min" : "../dist/dev";
const clientJs = Fs.readFileSync(Path.join(__dirname, distDir, "subapp-web.js")).toString();
const cdnJs = Fs.readFileSync(Path.join(__dirname, distDir, "cdn-map.js")).toString();
const loadJs = Fs.readFileSync(
require.resolve("loadjs/dist/loadjs.min.js"),
"utf8"
);

const loadJs = Fs.readFileSync(require.resolve("loadjs/dist/loadjs.min.js"), "utf8");
//
// TODO: in webpack dev mode, we need to reload stats after there's a change
//

const { assets } = util.loadAssetsFromStats(setupContext.routeOptions.stats);

setupContext.routeOptions.__internals.assets = assets;

const cdnJsBundles = util.getCdnJsBundles(assets, setupContext.routeOptions);
Expand All @@ -34,14 +29,32 @@ module.exports = function setup(setupContext) {
basePath: ""
};

let inlineRuntimeJS = "";
let runtimeEntryPoints = [];
if (process.env.NODE_ENV === "production") {
runtimeEntryPoints = Object.keys(assets.chunksById.js).filter(ep =>
assets.chunksById.js[ep].startsWith("runtime.bundle")
);
inlineRuntimeJS =
"/*rt*/" +
runtimeEntryPoints
.map(ep => Path.resolve("dist", "js", Path.basename(cdnJsBundles[ep])))
.filter(fullPath => Fs.existsSync(fullPath))
.map(fullPath => Fs.readFileSync(fullPath))
.join(" ") +
"/*rt*/";

inlineRuntimeJS += `\nwindow.xarcV1.markBundlesLoaded(${JSON.stringify(runtimeEntryPoints)});`;
}

const webSubAppJs = `<script id="bundleAssets" type="application/json">
${JSON.stringify(bundleAssets)}
</script>
<script>/*LJ*/${loadJs}/*LJ*/
${clientJs}
${cdnJs}
</script>
`;
${inlineRuntimeJS}
</script>`;

// check if any subapp has server side code with initialize method and load them
const subAppServers = Object.keys(subappUtil.getAllSubAppManifest())
Expand All @@ -52,7 +65,9 @@ ${cdnJs}
process: context => {
context.user.assets = assets;
context.user.includedBundles = {};

runtimeEntryPoints.forEach(ep => {
context.user.includedBundles[ep] = true;
});
// invoke the initialize method of subapp's server code
if (subAppServers.length > 0) {
for (const server of subAppServers) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* placeholder */
157 changes: 157 additions & 0 deletions packages/subapp-web/test/data/mock-app/dist/stats-with-runtime.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"assetsByChunkName": {
"runtime": ["runtime.bundle.js", "../map/runtime.bundle.js.map"],
"vendors.~c145fdcf": ["vendors.~c145fdcf.bundle.js", "../map/vendors.~c145fdcf.bundle.js.map"],
"demo1": ["demo1.bundle.js", "../map/demo1.bundle.js.map"],
"demo2": ["demo2.bundle.js", "../map/demo2.bundle.js.map"],
"home": ["home.bundle.js", "../map/home.bundle.js.map"]
},
"assets": [
{
"name": "../map/demo1.bundle.js.map",
"size": 7349,
"chunks": [2],
"chunkNames": ["demo1"],
"info": {
"development": true
},
"emitted": false
},
{
"name": "../map/demo2.bundle.js.map",
"size": 122584,
"chunks": [3],
"chunkNames": ["demo2"],
"info": {
"development": true
},
"emitted": false
},
{
"name": "../map/home.bundle.js.map",
"size": 7451,
"chunks": [4],
"chunkNames": ["home"],
"info": {
"development": true
},
"emitted": false
},
{
"name": "../map/runtime.bundle.js.map",
"size": 8258,
"chunks": [0],
"chunkNames": ["runtime"],
"info": {
"development": true
},
"emitted": false
},
{
"name": "../map/vendors.~c145fdcf.bundle.js.map",
"size": 354688,
"chunks": [1],
"chunkNames": ["vendors.~c145fdcf"],
"info": {
"development": true
},
"emitted": false
},
{
"name": "2b7ac2d4ff91cca5b9c8e742eda58b24.png",
"size": 5402,
"chunks": [],
"chunkNames": [],
"info": {},
"emitted": false
},
{
"name": "demo1.bundle.js",
"size": 2153,
"chunks": [2],
"chunkNames": ["demo1"],
"info": {},
"emitted": false
},
{
"name": "demo2.bundle.js",
"size": 21808,
"chunks": [3],
"chunkNames": ["demo2"],
"info": {},
"emitted": false
},
{
"name": "home.bundle.js",
"size": 2139,
"chunks": [4],
"chunkNames": ["home"],
"info": {},
"emitted": false
},
{
"name": "runtime.bundle.js",
"size": 1551,
"chunks": [0],
"chunkNames": ["runtime"],
"info": {},
"emitted": false
},
{
"name": "vendors.~c145fdcf.bundle.js",
"size": 132264,
"chunks": [1],
"chunkNames": ["vendors.~c145fdcf"],
"info": {},
"emitted": false
}
],
"entrypoints": {
"demo1": [0, 1, 2],
"demo2": [0, 1, 3],
"home": [0, 1, 4]
},
"chunks": [
{
"id": 0,
"hash": "7a720e5ee25fe7c2fc7d",
"names": ["runtime"],
"entry": true,
"initial": true,
"rendered": true
},
{
"id": 1,
"hash": "cf181f43d0d9ef793316",
"names": ["vendors.~c145fdcf"],
"entry": false,
"initial": true,
"rendered": true,
"reason": "split chunk (cache group: vendors) (name: vendors.~c145fdcf)"
},
{
"id": 2,
"hash": "536dcd6808cc93441725",
"names": ["demo1"],
"entry": false,
"initial": true,
"rendered": true
},
{
"id": 3,
"hash": "cd5a8800a0311615f3de",
"names": ["demo2"],
"entry": false,
"initial": true,
"rendered": true
},
{
"id": 4,
"hash": "bcaf762e6a7f230aebb4",
"names": ["home"],
"entry": false,
"initial": true,
"rendered": true
}
]
}
29 changes: 28 additions & 1 deletion packages/subapp-web/test/spec/init.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"use strict";

const { init } = require("../../lib");
const { resetCdn } = require("../../lib/util");

const Path = require("path");

// test the init token for subapps

describe("init", function() {
describe("init", function () {
afterEach(() => {
delete process.env.NODE_ENV;
delete process.env.APP_SRC_DIR;
Expand All @@ -29,4 +31,29 @@ describe("init", function() {
expect(initJs).contains(`<script id="bundleAssets" type="application/json">`);
expect(initJs).contains(`<script>/*LJ*/`);
});

it("it should load timetime runtime.bundle.js inline and mark includedBundles.runtime to true", () => {
resetCdn();
process.env.NODE_ENV = "production";
const originalWd = process.cwd();
process.chdir(Path.resolve("test/data/mock-app"));

const initToken = init({
routeOptions: {
__internals: {},
cdn: {},
prodBundleBase: "/js",
stats: Path.join(__dirname, "../data/mock-app/dist/stats-with-runtime.json")
}
});

const context = { user: {} };
const initJs = initToken.process(context);
process.chdir(originalWd);
expect(Object.keys(context.user.includedBundles).length).to.equal(1);
const loadedBundles = Object.keys(context.user.includedBundles);
const markLoadedStr = `markBundlesLoaded(${JSON.stringify(loadedBundles)})`;
expect(initJs).to.contain(markLoadedStr);
expect(initJs).to.contain("/* placeholder */");
});
});
1 change: 1 addition & 0 deletions packages/xarc-create-app/my-app
Submodule my-app added at 832922

0 comments on commit cf64c59

Please sign in to comment.