Last active
January 17, 2019 10:14
-
-
Save VonHeikemen/6ec3543c4229e98963fd376f522bd81b to your computer and use it in GitHub Desktop.
Experimental webpack plugin to execute scripts using puppeteer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on egoist's work in @poi/plugin-puppet | |
// https://github.com/egoist/poi/tree/master/plugins/puppet | |
// npm install -D serve-static | |
const util = require('util'); | |
const http = require('http'); | |
const serveStatic = require('serve-static'); | |
const MAGIC_LOG = '__PUPPET__'; | |
const windowPuppet = ` | |
window.puppet = { | |
exit(code = 0) { | |
console.log('${MAGIC_LOG}', 'exit', code) | |
}, | |
} | |
`; | |
const createServer = (publicFolder) => { | |
const serve = serveStatic( | |
publicFolder, | |
{'index': ['index.html', 'index.htm']} | |
); | |
return http.createServer(serve); | |
} | |
const captureOutput = exitProcess => async (message) => { | |
const type = message.type(); | |
const args = message.args(); | |
const jsonArgs = await Promise.all(args.map(arg => arg.jsonValue())) | |
// Clean-up to enable garbage collection | |
args.forEach(arg => arg.dispose()); | |
const text = util.format(...jsonArgs); | |
if (type === 'clear') { | |
return console.clear(); | |
} | |
if (type === 'startGroupCollapsed') { | |
return console.groupCollapsed(); | |
} | |
if (type === 'endGroup') { | |
return console.groupEnd(); | |
} | |
if (!text) { | |
return; | |
} | |
if(jsonArgs[0] == MAGIC_LOG) { | |
const [, command, code] = jsonArgs; | |
return exitProcess(command, code); | |
} | |
if (type === 'error') { | |
console.error(text); | |
} else if (type === 'warning') { | |
console.warn(text); | |
} else if (type === 'debug') { | |
console.debug(text); | |
} else if (type === 'startGroup') { | |
console.group(text); | |
} else if (type === 'info') { | |
console.log(text); | |
} else { | |
console.log(text); | |
} | |
} | |
class Puppet { | |
constructor({ launchBrowser = null, port = 8080 }) { | |
this.launcher = launchBrowser; | |
this.port = port; | |
this.loadPage = this.loadPage.bind(this); | |
this.cleanUp = this.cleanUp.bind(this); | |
this.exit = this.exit.bind(this); | |
} | |
prepareServer() { | |
this.server = createServer(this.outputPath); | |
return new Promise(resolve => this.server.listen(this.port, resolve)); | |
} | |
async spawnPuppet() { | |
this.browser = await this.launcher(); | |
this.page = await this.browser.newPage(); | |
this.page.on('console', captureOutput(this.exit)); | |
await this.page.evaluateOnNewDocument(windowPuppet); | |
} | |
loadPage() { | |
if(this.started && this.isWatchMode) { | |
return this.page.reload(); | |
} | |
if(this.server.listening) { | |
this.started = true; | |
return this.page.goto(`http://localhost:${this.port}`); | |
} | |
} | |
async cleanUp() { | |
await this.page.close(); | |
await this.browser.close(); | |
if(this.server.listening) { | |
await new Promise(resolve => this.server.close(resolve)); | |
} | |
} | |
async exit(command, code) { | |
if(this.isWatchMode) { | |
return; | |
} | |
if(command == 'exit') { | |
await this.cleanUp(); | |
process.exit(code); | |
} | |
} | |
async apply(compiler) { | |
if(typeof this.launcher !== 'function') { | |
return; | |
} | |
const {done, watchClose} = compiler.hooks; | |
this.isWatchMode = compiler.options.watch; | |
this.outputPath = compiler.options.output.path; | |
done.tap('puppet', this.loadPage); | |
watchClose.tap('puppet', this.cleanUp); | |
await this.prepareServer(); | |
await this.spawnPuppet(); | |
} | |
} | |
module.exports = Puppet; |
Author
VonHeikemen
commented
Jan 17, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment