Skip to content

Commit 9c6bb70

Browse files
committed
Allow an ordered list of app files to be loaded in sandbox
This PR is to address a usecase where an app may want to load other assets after the vendor asset is loaded and before the app asset is loaded in the sandbox. Primarily for example, if we want to load i18n translations file, lazy engine assets. Making the appFiles an array allows other addons that will run after ember-cli-fastboot to update package.json with the order.
1 parent ec98310 commit 9c6bb70

8 files changed

Lines changed: 84167 additions & 15 deletions

File tree

src/ember-app.js

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ class EmberApp {
3232
let distPath = path.resolve(options.distPath);
3333
let config = this.readPackageJSON(distPath);
3434

35-
this.appFilePath = config.appFile;
36-
this.vendorFilePath = config.vendorFile;
35+
this.appFilePaths = config.appFiles;
36+
this.vendorFilePaths = config.vendorFiles;
3737
this.moduleWhitelist = config.moduleWhitelist;
3838
this.hostWhitelist = config.hostWhitelist;
3939
this.appConfig = config.appConfig;
@@ -128,21 +128,26 @@ class EmberApp {
128128
*/
129129
loadAppFiles() {
130130
let sandbox = this.sandbox;
131-
let appFilePath = this.appFilePath;
132-
let vendorFilePath = this.vendorFilePath;
131+
let appFilePaths = this.appFilePaths;
132+
let vendorFilePaths = this.vendorFilePaths;
133133

134134
sandbox.eval('sourceMapSupport.install(Error);');
135135

136-
let appFile = fs.readFileSync(appFilePath, 'utf8');
137-
let vendorFile = fs.readFileSync(vendorFilePath, 'utf8');
136+
debug("evaluating app and vendor files");
138137

139-
debug("evaluating app; app=%s; vendor=%s", appFilePath, vendorFilePath);
140-
141-
sandbox.eval(vendorFile, vendorFilePath);
138+
vendorFilePaths.forEach(function(vendorFilePath) {
139+
debug("evaluating vendor file %s", vendorFilePath);
140+
let vendorFile = fs.readFileSync(vendorFilePath, 'utf8');
141+
sandbox.eval(vendorFile, vendorFilePath);
142+
});
142143
debug("vendor file evaluated");
143144

144-
sandbox.eval(appFile, appFilePath);
145-
debug("app file evaluated");
145+
appFilePaths.forEach(function(appFilePath) {
146+
debug("evaluating app file %s", appFilePath);
147+
let appFile = fs.readFileSync(appFilePath, 'utf8');
148+
sandbox.eval(appFile, appFilePath);
149+
});
150+
debug("app files evaluated");
146151
}
147152

148153
/**
@@ -153,7 +158,6 @@ class EmberApp {
153158
*/
154159
createEmberApp() {
155160
let sandbox = this.sandbox;
156-
let appFilePath = this.appFilePath;
157161

158162
// Retrieve the application factory from within the sandbox
159163
let AppFactory = sandbox.run(function(ctx) {
@@ -162,7 +166,7 @@ class EmberApp {
162166

163167
// If the application factory couldn't be found, throw an error
164168
if (!AppFactory || typeof AppFactory['default'] !== 'function') {
165-
throw new Error('Failed to load Ember app from ' + appFilePath + ', make sure it was built for FastBoot with the `ember fastboot:build` command.');
169+
throw new Error('Failed to load Ember app from app.js, make sure it was built for FastBoot with the `ember fastboot:build` command.');
166170
}
167171

168172
// Otherwise, return a new `Ember.Application` instance
@@ -349,9 +353,33 @@ class EmberApp {
349353
throw new Error(`${pkgPath} was malformed or did not contain a manifest. Ensure that you have a compatible version of ember-cli-fastboot.`);
350354
}
351355

356+
var appFiles = [];
357+
if (manifest.appFiles) {
358+
debug("reading array of app file paths from manifest");
359+
manifest.appFiles.forEach(function(appFile) {
360+
appFiles.push(path.join(distPath, appFile));
361+
});
362+
} else if (manifest.appFile) {
363+
// TODO : remove after Fastboot 1.0
364+
debug("reading app file path from manifest");
365+
appFiles = [path.join(distPath, manifest.appFile)];
366+
}
367+
368+
var vendorFiles = [];
369+
if (manifest.vendorFiles) {
370+
debug("reading array of vendor file paths from manifest");
371+
manifest.vendorFiles.forEach(function(vendorFile) {
372+
vendorFiles.push(path.join(distPath, vendorFile));
373+
});
374+
} else if (manifest.vendorFile) {
375+
// TODO : remove after Fastboot 1.0
376+
debug("reading vendor file path from manifest");
377+
vendorFiles = [path.join(distPath, manifest.vendorFile)];
378+
}
379+
352380
return {
353-
appFile: path.join(distPath, manifest.appFile),
354-
vendorFile: path.join(distPath, manifest.vendorFile),
381+
appFiles: appFiles,
382+
vendorFiles: vendorFiles,
355383
htmlFile: path.join(distPath, manifest.htmlFile),
356384
moduleWhitelist: pkg.fastboot.moduleWhitelist,
357385
hostWhitelist: pkg.fastboot.hostWhitelist,

test/fastboot-test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ describe("FastBoot", function() {
5151
});
5252
});
5353

54+
it("can render HTML with array of app files defined in package.json", function() {
55+
var fastboot = new FastBoot({
56+
distPath: fixture('multiple-app-files')
57+
});
58+
59+
return fastboot.visit('/')
60+
.then(r => r.html())
61+
.then(html => {
62+
expect(html).to.match(/Welcome to Ember/);
63+
});
64+
});
65+
5466
it("cannot not render app HTML with shouldRender set as false", function() {
5567
var fastboot = new FastBoot({
5668
distPath: fixture('basic-app')

0 commit comments

Comments
 (0)