├── .editorconfig ├── .gitignore ├── README.md ├── index.js └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *.log 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # psi-local-cli 2 | 3 | > [Google PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights) CLI for localhost projects via [ngrok](https://ngrok.com). 4 | 5 | ## Install 6 | 7 | ```bash 8 | npm i psi-local-cli -g 9 | ``` 10 | 11 | ## Examples 12 | 13 | ```bash 14 | psi-local --port 8080 15 | # will test http://localhost:8080 via ngrok tunnel 16 | ``` 17 | 18 | ```bash 19 | psi-local --port 8080 --route /signup 20 | # will test http://localhost:8080/signup via ngrok tunnel 21 | ``` 22 | 23 | ```bash 24 | psi-local --port 8080 --nopsi 25 | # will just create tunnel for http://localhost:8080 without calling PSI 26 | # you can manually copy-paste generated ngrok url to PSI web interface 27 | ``` 28 | 29 | All [psi-cli](https://github.com/addyosmani/psi) options are supported: 30 | 31 | ```bash 32 | psi-local --port 8080 --strategy mobile 33 | # will test http://localhost:8080 via ngrok tunnel and pass `strategy` to psi-cli 34 | ``` 35 | 36 | --- 37 | 38 | **MIT Licensed** 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const ngrok = require('ngrok'); 4 | const yargs = require('yargs'); 5 | const ora = require('ora'); 6 | const exec = require('child_process').exec; 7 | 8 | const opts = yargs.default({ 9 | strategy: 'desktop', 10 | nokey: true 11 | }).argv; 12 | 13 | if (opts.help) { 14 | return exec('psi --help', (err, stdout) => { 15 | stdout = stdout 16 | .replace(/psi/gm, 'psi-local') 17 | .replace('', '--port ') 18 | .replace('todomvc.com', '--port 8080'); 19 | 20 | process.stdout.write(stdout); 21 | }); 22 | } 23 | 24 | if (!opts.port) { 25 | return error({ 26 | message: '--port option is required', 27 | noStack: true 28 | }); 29 | } 30 | 31 | const spinner = ora({color: 'yellow'}); 32 | 33 | spinner.start(); 34 | spinner.text = '---> Creating ngrok tunnel'; 35 | 36 | ngrok.connect(opts.port, (err, url) => { 37 | if (err) { 38 | return error(err) 39 | } 40 | 41 | if (opts.route) { 42 | url += opts.route 43 | } 44 | 45 | spinner.text = `---> PageSpeed Insights will run for: ${url}`; 46 | 47 | if (opts.nopsi) { 48 | return; 49 | } 50 | 51 | exec(`psi ${url} ${_createPsiParams(opts)}`, (err, stdout) => { 52 | spinner.text = '---> PageSpeed Insights are done!'; 53 | spinner.stop(); 54 | 55 | process.stdout.write(`\n${stdout}`); 56 | process.exit(); 57 | }); 58 | }); 59 | 60 | function _createPsiParams (obj) { 61 | const params = Object.assign({}, obj, { 62 | port: 0, 63 | route: 0, 64 | nopsi: 0 65 | }); 66 | 67 | return Object.keys(params) 68 | .filter(key => params[key]) 69 | .reduce((memo, key) => { 70 | memo += ` --${key} ${params[key]}`; 71 | return memo; 72 | }, ''); 73 | } 74 | 75 | function _error (err) { 76 | if (err.noStack) { 77 | console.error(err.message); 78 | process.exit(1); 79 | } else { 80 | throw err; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "psi-local-cli", 3 | "version": "1.0.1", 4 | "description": "PageSpeed Insights for localhost via ngrok", 5 | "main": "index.js", 6 | "bin": { 7 | "psi-local": "./index.js" 8 | }, 9 | "preferGlobal": true, 10 | "engines": { 11 | "node": ">=6.0.0" 12 | }, 13 | "dependencies": { 14 | "ngrok": "^2.2.3", 15 | "ora": "^0.3.0", 16 | "psi": "^2.0.4", 17 | "yargs": "^6.3.0" 18 | }, 19 | "devDependencies": {}, 20 | "scripts": { 21 | "test": "echo \"Error: no test specified\" && exit 0" 22 | }, 23 | "keywords": [ 24 | "psi", 25 | "google", 26 | "speed", 27 | "optimize", 28 | "localhost", 29 | "ngrok" 30 | ], 31 | "author": "Dmitri Voronianski ", 32 | "license": "MIT" 33 | } 34 | --------------------------------------------------------------------------------