@greenwood/cli
Version:
106 lines (91 loc) • 3.42 kB
JavaScript
import fs from "fs/promises";
import livereload from "livereload";
class LiveReloadServer {
constructor(compilation, options = {}) {
this.compilation = compilation;
this.options = options;
}
async start() {
const { userWorkspace, projectDirectory } = this.compilation.context;
const standardPluginsDirectoryPath = new URL("../resource/", import.meta.url);
const standardPluginsNames = (await fs.readdir(standardPluginsDirectoryPath)).filter(
(filename) => filename.indexOf("plugin-standard") === 0,
);
const standardPluginsExtensions = (
await Promise.all(
standardPluginsNames.map(async (filename) => {
const pluginImport = await import(
// @ts-expect-error see https://github.com/microsoft/TypeScript/issues/42866
new URL(`./${filename}`, standardPluginsDirectoryPath)
);
const plugin = pluginImport[Object.keys(pluginImport)[0]];
return plugin;
}),
)
)
.filter((plugin) => plugin.type === "resource")
.map((plugin) => plugin.provider(this.compilation).extensions || [].flat())
.flat();
const customPluginsExtensions = this.compilation.config.plugins
.filter((plugin) => plugin.type === "resource")
.map((plugin) => {
return plugin.provider(this.compilation).extensions || [].flat();
})
.flat();
// filter out wildcards or otherwise undesired values and remove any . since livereload likes them that way
const allExtensions = [
...standardPluginsExtensions,
...customPluginsExtensions,
...this.compilation.config.devServer.extensions,
]
.filter((ext) => ext !== "*" || ext !== "") // basic filter for false positives
.filter((ext, idx, array) => array.indexOf(ext) === idx) // dedupe
.map((ext) => (ext.startsWith(".") ? ext.replace(".", "") : ext)); // trim . from all entries
const liveReloadServer = livereload.createServer(
{
exts: allExtensions,
applyCSSLive: false, // https://github.com/napcs/node-livereload/issues/33#issuecomment-693707006
applyImgLive: false, // https://github.com/ProjectEvergreen/greenwood/issues/1263
},
() => {
const abridgedWorkspacePath = userWorkspace.pathname
.replace(projectDirectory.pathname, "")
.replace("/", "");
console.info(
`Now watching workspace directory (./${abridgedWorkspacePath}) for changes...`,
);
},
);
liveReloadServer.watch(userWorkspace.pathname);
}
}
class LiveReloadResource {
async shouldIntercept(url, request, response) {
const contentType = response.headers.get("Content-Type");
return contentType?.indexOf("text/html") >= 0 && process.env.__GWD_COMMAND__ === "develop";
}
async intercept(url, request, response) {
let body = await response.text();
body = body.replace(
"</head>",
`
<script src="http://localhost:35729/livereload.js?snipver=1"></script>
</head>
`,
);
return new Response(body);
}
}
const greenwoodPluginLivereload = [
{
type: "server",
name: "plugin-live-reload:server",
provider: (compilation) => new LiveReloadServer(compilation),
},
{
type: "resource",
name: "plugin-live-reload:resource",
provider: () => new LiveReloadResource(),
},
];
export { greenwoodPluginLivereload };