1 | const Packager = require('./Packager');
|
2 | const posthtml = require('posthtml');
|
3 | const path = require('path');
|
4 | const urlJoin = require('../utils/urlJoin');
|
5 |
|
6 |
|
7 | const metadataContent = new Set([
|
8 | 'base',
|
9 | 'link',
|
10 | 'meta',
|
11 | 'noscript',
|
12 | 'script',
|
13 | 'style',
|
14 | 'template',
|
15 | 'title'
|
16 | ]);
|
17 |
|
18 | class HTMLPackager extends Packager {
|
19 | static shouldAddAsset() {
|
20 |
|
21 | return false;
|
22 | }
|
23 |
|
24 | async addAsset(asset) {
|
25 | let html = asset.generated.html || '';
|
26 |
|
27 |
|
28 |
|
29 | let siblingBundles = Array.from(this.bundle.childBundles)
|
30 | .reduce((p, b) => p.concat([...b.siblingBundles.values()]), [])
|
31 | .filter(b => b.type === 'css' || b.type === 'js');
|
32 |
|
33 | if (siblingBundles.length > 0) {
|
34 | html = posthtml(
|
35 | this.insertSiblingBundles.bind(this, siblingBundles)
|
36 | ).process(html, {sync: true}).html;
|
37 | }
|
38 |
|
39 | await this.write(html);
|
40 | }
|
41 |
|
42 | addBundlesToTree(bundles, tree) {
|
43 | const head = find(tree, 'head');
|
44 | if (head) {
|
45 | const content = head.content || (head.content = []);
|
46 | content.push(...bundles);
|
47 | return;
|
48 | }
|
49 |
|
50 | const html = find(tree, 'html');
|
51 | const content = html ? html.content || (html.content = []) : tree;
|
52 | const index = findBundleInsertIndex(content);
|
53 |
|
54 | content.splice(index, 0, ...bundles);
|
55 | }
|
56 |
|
57 | insertSiblingBundles(siblingBundles, tree) {
|
58 | const bundles = [];
|
59 |
|
60 | for (let bundle of siblingBundles) {
|
61 | if (bundle.type === 'css') {
|
62 | bundles.push({
|
63 | tag: 'link',
|
64 | attrs: {
|
65 | rel: 'stylesheet',
|
66 | href: urlJoin(this.options.publicURL, path.basename(bundle.name))
|
67 | }
|
68 | });
|
69 | } else if (bundle.type === 'js') {
|
70 | bundles.push({
|
71 | tag: 'script',
|
72 | attrs: {
|
73 | src: urlJoin(this.options.publicURL, path.basename(bundle.name))
|
74 | }
|
75 | });
|
76 | }
|
77 | }
|
78 |
|
79 | this.addBundlesToTree(bundles, tree);
|
80 | }
|
81 | }
|
82 |
|
83 | function find(tree, tag) {
|
84 | let res;
|
85 | tree.match({tag}, node => {
|
86 | res = node;
|
87 | return node;
|
88 | });
|
89 |
|
90 | return res;
|
91 | }
|
92 |
|
93 | function findBundleInsertIndex(content) {
|
94 | for (let index = 0; index < content.length; index++) {
|
95 | const node = content[index];
|
96 | if (node && node.tag && !metadataContent.has(node.tag)) {
|
97 | return index;
|
98 | }
|
99 | }
|
100 |
|
101 | return 0;
|
102 | }
|
103 |
|
104 | module.exports = HTMLPackager;
|