tatianamac 6d5445ecc5 update
2019-11-26 14:50:43 -08:00

177 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require("fs-extra");
const TemplatePath = require("./TemplatePath");
const config = require("./Config");
const debug = require("debug")("EleventyServe");
class EleventyServe {
constructor() {}
get config() {
return this.configOverride || config.getConfig();
}
set config(config) {
this.configOverride = config;
}
setOutputDir(outputDir) {
this.outputDir = outputDir;
}
getPathPrefix() {
return this.config.pathPrefix || "/";
}
getRedirectDir(dirName) {
return TemplatePath.join(this.outputDir, dirName);
}
getRedirectDirOverride() {
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (this.getPathPrefix() !== "/") {
return "_eleventy_redirect";
}
}
getRedirectFilename(dirName) {
return TemplatePath.join(this.getRedirectDir(dirName), "index.html");
}
getOptions(port) {
let pathPrefix = this.getPathPrefix();
// TODO customize this in Configuration API?
let serverConfig = {
baseDir: this.outputDir
};
let redirectDirName = this.getRedirectDirOverride();
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (redirectDirName) {
serverConfig.baseDir = this.getRedirectDir(redirectDirName);
serverConfig.routes = {};
serverConfig.routes[pathPrefix] = this.outputDir;
// if has a savedPathPrefix, use the /savedPathPrefix/index.html template to redirect to /pathPrefix/
if (this.savedPathPrefix) {
serverConfig.routes[this.savedPathPrefix] = TemplatePath.join(
this.outputDir,
this.savedPathPrefix
);
}
}
return Object.assign(
{
server: serverConfig,
port: port || 8080,
ignore: ["node_modules"],
watch: false,
open: false,
notify: false,
index: "index.html"
},
this.config.browserSyncConfig
);
}
cleanupRedirect(dirName) {
if (dirName && dirName !== "/") {
let savedPathFilename = this.getRedirectFilename(dirName);
setTimeout(function() {
if (!fs.existsSync(savedPathFilename)) {
debug(`Cleanup redirect: Could not find ${savedPathFilename}`);
return;
}
let savedPathContent = fs.readFileSync(savedPathFilename, "utf-8");
if (
savedPathContent.indexOf("Browsersync pathPrefix Redirect") === -1
) {
debug(
`Cleanup redirect: Found ${savedPathFilename} but it wasnt an eleventy redirect.`
);
return;
}
fs.unlink(savedPathFilename, err => {
if (!err) {
debug(`Cleanup redirect: Deleted ${savedPathFilename}`);
}
});
}, 2000);
}
}
serveRedirect(dirName) {
fs.outputFile(
this.getRedirectFilename(dirName),
`<!doctype html>
<meta http-equiv="refresh" content="0; url=${this.config.pathPrefix}">
<title>Browsersync pathPrefix Redirect</title>
<a href="${this.config.pathPrefix}">Go to ${this.config.pathPrefix}</a>`
);
}
serve(port) {
// only load on serve—this is pretty expensive
const browserSync = require("browser-sync");
this.server = browserSync.create();
let pathPrefix = this.getPathPrefix();
if (this.savedPathPrefix && pathPrefix !== this.savedPathPrefix) {
let redirectFilename = this.getRedirectFilename(this.savedPathPrefix);
if (!fs.existsSync(redirectFilename)) {
debug(
`Redirecting BrowserSync from ${
this.savedPathPrefix
} to ${pathPrefix}`
);
this.serveRedirect(this.savedPathPrefix);
} else {
debug(
`Config updated with a new pathPrefix. Tried to set up a transparent redirect but found a template already existing at ${redirectFilename}. Youll have to navigate manually.`
);
}
}
let redirectDirName = this.getRedirectDirOverride();
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (redirectDirName) {
this.serveRedirect(redirectDirName);
}
this.cleanupRedirect(this.savedPathPrefix);
this.server.init(this.getOptions(port));
// this needs to happen after `.getOptions`
this.savedPathPrefix = pathPrefix;
}
close() {
if (this.server) {
this.server.exit();
}
}
reload(path, isInclude) {
if (this.server) {
if (this.getPathPrefix() !== this.savedPathPrefix) {
this.server.exit();
this.serve();
} else {
// Is a CSS input file and is not in the includes folder
// TODO check output path file extension of this template (not input path)
if (path && path.split(".").pop() === "css" && !isInclude) {
this.server.reload("*.css");
} else {
this.server.reload();
}
}
}
}
}
module.exports = EleventyServe;