Skip to content

Commit 8f020cc

Browse files
committed
New html-oriented manifest format for embroider
1 parent 85fe688 commit 8f020cc

File tree

10 files changed

+84410
-22
lines changed

10 files changed

+84410
-22
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"debug": "^4.1.1",
3131
"resolve": "^1.15.0",
3232
"simple-dom": "^1.4.0",
33+
"simple-html-tokenizer": "^0.5.9",
3334
"source-map-support": "^0.5.16"
3435
},
3536
"devDependencies": {
@@ -42,13 +43,14 @@
4243
"eslint-plugin-node": "^11.0.0",
4344
"eslint-plugin-prettier": "^3.1.2",
4445
"express": "^4.17.1",
46+
"fixturify": "^2.1.0",
4547
"lerna-changelog": "^1.0.0",
4648
"mocha": "^7.0.1",
4749
"prettier": "^1.19.1",
4850
"release-it": "^12.4.3",
4951
"release-it-lerna-changelog": "^2.0.0",
5052
"rimraf": "^3.0.1",
51-
"temp": "^0.9.1"
53+
"tmp": "^0.2.1"
5254
},
5355
"engines": {
5456
"node": "10.* || >=12"

src/ember-app.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class EmberApp {
5757
this.config = allConfig;
5858
}
5959

60-
this.html = fs.readFileSync(config.htmlFile, 'utf8');
60+
this.html = config.html || fs.readFileSync(config.htmlFile, 'utf8');
6161

6262
this.sandboxRequire = this.buildWhitelistedRequire(this.moduleWhitelist, distPath);
6363
let filePaths = [require.resolve('./scripts/install-source-map-support')].concat(
@@ -492,20 +492,30 @@ class EmberApp {
492492
}
493493
}
494494

495-
debug('reading array of app file paths from manifest');
496-
let appFiles = manifest.appFiles.map(function(appFile) {
497-
return path.join(distPath, appFile);
498-
});
495+
let appFiles, vendorFiles, htmlFile, html;
499496

500-
debug('reading array of vendor file paths from manifest');
501-
let vendorFiles = manifest.vendorFiles.map(function(vendorFile) {
502-
return path.join(distPath, vendorFile);
503-
});
497+
if (manifest.htmlEntrypoint) {
498+
let htmlEntrypoint = require('./html-entrypoint');
499+
({ appFiles, vendorFiles, html } = htmlEntrypoint(distPath, manifest.htmlEntrypoint));
500+
} else {
501+
debug('reading array of app file paths from manifest');
502+
appFiles = manifest.appFiles.map(function(appFile) {
503+
return path.join(distPath, appFile);
504+
});
505+
506+
debug('reading array of vendor file paths from manifest');
507+
vendorFiles = manifest.vendorFiles.map(function(vendorFile) {
508+
return path.join(distPath, vendorFile);
509+
});
510+
511+
htmlFile = path.join(distPath, manifest.htmlFile);
512+
}
504513

505514
return {
506515
appFiles,
507516
vendorFiles,
508-
htmlFile: path.join(distPath, manifest.htmlFile),
517+
htmlFile,
518+
html,
509519
moduleWhitelist: pkg.fastboot.moduleWhitelist,
510520
hostWhitelist: pkg.fastboot.hostWhitelist,
511521
config,

src/html-entrypoint.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
const { tokenize } = require('simple-html-tokenizer');
4+
const fs = require('fs');
5+
const path = require('path');
6+
const pattern = /<fastboot-script[^>]*><\/fastboot-script>\n*/g;
7+
8+
function htmlEntrypoint(distPath, htmlPath) {
9+
let html = fs.readFileSync(path.join(distPath, htmlPath), 'utf8');
10+
11+
// all the scripts we want to run go into appFiles. We don't use vendorFiles.
12+
// The distinction doesn't matter here, as long as the scripts all stay in the
13+
// right relative order.
14+
let appFiles = [];
15+
16+
for (let token of tokenize(html)) {
17+
if (token.type === 'StartTag' && ['script', 'fastboot-script'].includes(token.tagName)) {
18+
for (let [name, value] of token.attributes) {
19+
if (name === 'src') {
20+
appFiles.push(path.join(distPath, value));
21+
}
22+
}
23+
}
24+
}
25+
26+
// we could bring a full html parser & serializer to the party, but the tags
27+
// we're trying to strip out here aren't even allowed to have any textContext,
28+
// so they're pretty tame.
29+
html = html.replace(pattern, '');
30+
31+
return { html, appFiles, vendorFiles: [] };
32+
}
33+
34+
module.exports = htmlEntrypoint;

test/fastboot-test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,4 +582,18 @@ describe('FastBoot', function() {
582582
usedPrebuiltSandbox: true,
583583
});
584584
});
585+
586+
it('htmlEntrypoint works', function() {
587+
var fastboot = new FastBoot({
588+
distPath: fixture('html-entrypoint'),
589+
});
590+
591+
return fastboot
592+
.visit('/')
593+
.then(r => r.html())
594+
.then(html => {
595+
expect(html).to.match(/Welcome to Ember/);
596+
expect(html).to.not.match(/fastboot-script/);
597+
});
598+
});
585599
});

0 commit comments

Comments
 (0)