-
Notifications
You must be signed in to change notification settings - Fork 392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add: preProcess and postProcess functionality #170
Conversation
Currently, with most options, it's either take what react-snap does, or you get nothing. For instance, `removeScripts` remove every single script. `removeStyles` removes every single style. There's no way to customise this in anyway. Similarly, I've also needed a `defer` scripts functionality before (PR: stereobooster#169) but it didn't quite fit in nicely. This solves all these problem by being able to any custom functionality to modify the output as desired by directly using chrome's `puppeteer`. This also helps moving all features as plugins and helps to easily experiment and add/remove features to react-snap.
Example usage: // snap.js
const url = require("url");
const { run } = require("react-snap");
const fs = require("fs-extra");
const path = require("path");
async function snap() {
process.chdir(path.resolve(path.join(__dirname, "./../")));
run({
publicPath: "/",
preProcess: (snappy) => {
return removeScriptTagsWithSrcAttribute(snappy)
},
});
}
async function runAsync() {
await snap();
// workaround react-snap bug where the promise actually
// gets resolved before it truly completes.
process.once("beforeExit", () => {
fs.unlink("./build/200.html");
fs.unlink("./build/404.html");
});
}
const deferScriptTags = ({ page }) => {
return page.evaluate(() => {
Array.from(document.querySelectorAll("script[src]")).forEach(x => {
x.removeAttribute("async");
x.setAttribute("defer", "true");
});
});
};
// This removes *only* the script tags with an `src` attribute - so that it's
// still possible to add some script in the file like Google Analytics, etc
// using direct `script` without the src attribute.
const removeScriptTagsWithSrcAttribute = ({ page }) => {
return page.evaluate(() => {
Array.from(document.querySelectorAll("script")).filter(node => node.src).forEach(ell => {
ell.parentElement && ell.parentElement.removeChild(ell);
});
});
};
runAsync(); PS: This also highlights a bug in react-snap where the promises are resolved before it's actually complete. Should file an issue. But for the lack of time, just using this opportunity to just throw it in at the moment :) The above is a part of my website source. Here's the full source code if it's useful to someone: https://github.com/prasannavl/prasannavl.com/blob/master/tools/snap.js |
At the moment I'm trying to write proper tests for the package. It was without tests way too long. This means, that all other PRs will be on hold. See #171 |
ae782b6
to
193b27b
Compare
Any update on this? |
It is easy to introduce new functionality, but it will be hard to maintain it. You know you can install it from github url, right? |
@stereobooster - Hmm. I'd assume that being able to do this removes a lot of maintenance overhead, since it'd provide a pretty neat plugin hook. Anyway, whichever works for you! I'm maintaining a fork of this with these two additions, that I rely pretty heavily on -- as different projects have different needs, and this hook provides me with the ability to change things at will without having to touch react-snap directly. So, was hoping to see what your thoughts were on this. Cheers! |
@stereobooster I have a question that how to cleanup dynamically inserted scripts? e.g. Google Analytics script is inserted by calling |
Currently, with most options, it's either take what react-snap does, or you get nothing. For instance,
removeScripts
remove every single script.removeStyles
removes every single style. There's no way to customise this in anyway. Similarly, I've also needed adefer
scripts functionality before (PR: #169) but it didn't quite fit in nicely.This solves all these problem by being able to any custom functionality to modify the output as desired by directly using chrome's
puppeteer
. This also helps moving all features as plugins and helps to easily experiment and add/remove features to react-snap.