Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
stereobooster committed Oct 1, 2017
0 parents commit 50bbcd3
Show file tree
Hide file tree
Showing 6 changed files with 750 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8.6.0
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/prettier/prettier#pre-commit-hook
116 changes: 116 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env node
const puppeteer = require("puppeteer");
const http = require("http");
const https = require("https");
const express = require("express");
const serveStatic = require("serve-static");
const fallback = require("express-history-api-fallback");
const path = require("path");
const Url = require("url");
const _ = require("highland");
const program = require("commander");
const fs = require("fs");
const mkdirp = require("mkdirp");
const minify = require("html-minifier").minify;

const crawl = options => {
let shuttingDown = false;
process.on("SIGINT", () => {
if (shuttingDown) {
process.exit();
} else {
shuttingDown = true;
console.log(
"Gracefully shutting down. To exit immediately, press ^C again"
);
}
});

const buildDir = path.normalize(`${__dirname}/${options.build || "build"}`);
const startServer = options => {
const app = express()
.use(serveStatic(buildDir))
.use(fallback("index.html", { root: buildDir }));
const server = http.createServer(app);
server.listen(options.port);
return server;
};

const basePath = `http://localhost:${options.port}/`;
const basedomain = "localhost";
const queue = _();
let enqued = 0;
let processed = 0;
const uniqRegister = {};
const addToQueue = (url, referer) => {
if (Url.parse(url).hostname === basedomain && !uniqRegister[url]) {
uniqRegister[url] = true;
enqued++;
queue.write(url);
}
};

const fetchPage = async url => {
if (shuttingDown) return;
console.log(url);
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle" });
const links = await page.evaluate(() =>
Array.from(document.querySelectorAll("a")).map(link => link.href)
);
links.map(addToQueue);
const content = await page.evaluate(
() => document.documentElement.outerHTML
);
const route = url.replace(basePath, "");
let filePath = path.join(buildDir, route);
mkdirp.sync(filePath);
const minifiedContent = minify(content, {
minifyCSS: true,
removeComments: true,
collapseBooleanAttributes: true,
collapseWhitespace: true,
collapseInlineTagWhitespace: true,
decodeEntities: true,
keepClosingSlash: true,
sortAttributes: true,
sortClassName: true
});
fs.writeFileSync(path.join(filePath, "index.html"), minifiedContent);

return browser.close().then(() => {
processed++;
if (enqued === processed) queue.end();
});
};

const server = startServer(options);
const url = options.url || `http://localhost:${options.port}/`;
addToQueue(url);

queue
.map(x => _(fetchPage(x)))
.parallel(options.concurrency)
.collect()
.done(function() {
server.close();
});
};

const { version } = require("./package.json");

program
.version(version)
.description("Prerender Create React App.")
.option(
"-p, --port [port]",
"Temporary webserver port (Default: 45678)",
45678
)
.option("-b, --build [build]", "Webserver root (Default: build)", "build")
.option("-c, --concurrency [concurrency]", "Concurrency of crawler", 3)
.option("--progress [progress]", "Show progress", true)
.parse(process.argv);

crawl(program);
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "react-snap",
"version": "1.0.0",
"description": "react-snapshot, prep e.t.c",
"main": "index.js",
"author": "stereobooster",
"license": "MIT",
"dependencies": {
"commander": "^2.11.0",
"express": "^4.16.1",
"express-history-api-fallback": "^2.2.1",
"highland": "^2.11.1",
"html-minifier": "^3.5.5",
"mkdirp": "^0.5.1",
"puppeteer": "^0.11.0",
"serve-static": "^1.13.1"
},
"devDependencies": {
"prettier": "1.7.3"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"precommit": "prettier --write *.{js,json,css}"
},
"bin": {
"react-snap": "./index.js"
}
}
Loading

0 comments on commit 50bbcd3

Please sign in to comment.