fuse-box
Version:
Fuse-Box a bundler that does it right
88 lines (79 loc) • 2.8 kB
text/typescript
import { } from "../core/File";
import { Plugin } from "../core/WorkflowContext";
import { BundleProducer } from "../core/BundleProducer";
import * as fs from "fs";
import { ensureAbsolutePath, joinFuseBoxPath } from "../Utils";
export interface IndexPluginOptions {
title?: string;
charset?: string;
description?: string;
keywords?: string;
author?: string;
bundles?: string[];
path?: string;
target?: string;
template?: string;
async?: boolean;
}
export class WebIndexPluginClass implements Plugin {
constructor(public opts?: IndexPluginOptions) {
}
producerEnd(producer: BundleProducer) {
let bundlePaths = [];
let bundles = producer.sortBundles();
bundles.forEach((bundle) => {
let pass = true;
if (this.opts.bundles) {
if (this.opts.bundles.indexOf(bundle.name) === -1) {
pass = false;
}
}
pass = pass && bundle.webIndexed;
if (pass) {
const output = bundle.context.output;
if (output && output.lastPrimaryOutput) {
bundlePaths.push(
joinFuseBoxPath(this.opts.path ? this.opts.path : "/", output.folderFromBundleName || "/",
output.lastPrimaryOutput.filename)
)
}
}
});
let html = `<!DOCTYPE html>
<html>
<head>
<title>$title</title>
$charset
$description
$keywords
$author
</head>
<body>
$bundles
</body>
</html>`;
if (this.opts.template) {
let filePath = ensureAbsolutePath(this.opts.template);
html = fs.readFileSync(filePath).toString();
}
let jsTags = bundlePaths.map(bundle =>
`<script ${this.opts.async ? 'async' : ''} type="text/javascript" src="${bundle}"></script>`
).join("\n");
let macro = {
title: this.opts.title ? this.opts.title : "",
charset: this.opts.charset ? `<meta charset="${this.opts.charset}">` : "",
description: this.opts.description ? `<meta name="description" content="${this.opts.description}">` : "",
keywords: this.opts.keywords ? `<meta name="keywords" content="${this.opts.keywords}">` : "",
author: this.opts.author ? `<meta name="author" content="${this.opts.author}">` : "",
bundles: jsTags
}
for (let key in macro) {
html = html.replace('$' + key, macro[key])
}
producer.fuse.context
.output.write(this.opts.target || "index.html", html, true);
}
};
export const WebIndexPlugin = (opts?: IndexPluginOptions) => {
return new WebIndexPluginClass(opts || {});
};