Skip to content

Commit

Permalink
✨ Automatically open file in browser
Browse files Browse the repository at this point in the history
  • Loading branch information
BetaHuhn committed Jan 22, 2021
1 parent 8759587 commit 65e59aa
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 20 deletions.
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ Usage: ejs-serve -f <filename> -d <json string|file> -p <port>
Build, watch and serve your EJS templates in your browser.

Options:
-f, --file <path> path to ejs file
-d, --data <json> JSON string or path to json file
-p, --port <number> port on which to serve the file (default: 8080)
-e, --email [boolean] render file with mjml (default: false)
-v, --version output the version number
-h, --help display help for command
-f, --file <path> path to ejs file
-d, --data <json> JSON string or path to json file
-p, --port <number> port on which to serve the file (default: 8080)
-e, --email [boolean] render file with mjml (default: false)
-o, --open [local/network] open file in browser automatically (default: false)
-v, --version output the version number
-h, --help display help for command
```

## 🛠️ Examples
Expand All @@ -64,6 +65,14 @@ ejs-serve -f index.ejs -d '{"message":"Hello World!"}'
ejs-serve -f index.ejs -d data.json -p 3000
```

### Automatically open browser

`ejs-serve` can automatically open the file in the browser. If you use `-o` it will open the file via its local address (localhost:port). You can use `-o network` to use the network address.

```shell
ejs-serve -f index.ejs -d data.json -p 3000 -o
```

### Generate email with mjml

`ejs-serve` can be used in conjunction with [mjml](https://github.com/mjmlio/mjml) to render your ejs file with data and generate a reponsive email. Use the `-e` option to enable this feature and it will run the rendered ejs file through mjml.
Expand Down
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"commander": "^6.2.1",
"ejs": "^3.1.5",
"mjml": "^4.8.1",
"open": "^7.3.1",
"running-at": "^0.3.5",
"ws": "^7.4.1"
},
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ program
.option('-d, --data <json>', 'JSON string or path to json file')
.option('-p, --port <number>', 'port on which to serve the file', 8080)
.option('-e, --email [boolean]', 'render file with mjml', false)
.option('-o, --open [local/network]', 'open file in browser automatically', false)
.action((args) => {
const runner = new Runner(args, program)
runner.serve()
Expand Down
19 changes: 13 additions & 6 deletions src/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Runner {
}

async serve() {
const { file, data, port, email } = this.args
const { file, data, port, email, open } = this.args

if (!file) {
return this.program.help()
Expand All @@ -21,6 +21,12 @@ class Runner {
return log.fail(`error: file not found => ${ file }`)
}

const shouldOpen = open !== false
if (typeof open === 'string' && [ 'network', 'local' ].includes(open) === false) {
log.fail(`error: '${ open }' not valid for option --open, use network or local instead`)
process.exit(1)
}

const dataFile = fs.existsSync(data) ? data : undefined

let json
Expand All @@ -29,17 +35,18 @@ class Runner {
json = JSON.parse(rawData)
} catch (err) {
log.fail(`error: failed to parse JSON => ${ data }`)
process.exit()
process.exit(1)
}

log.info(`[ejs-serve] starting...`)
log.info(`starting...`)
const server = new Server(port)

const network = runningAt(port).network
const ips = runningAt(port)
const ip = open === 'network' ? ips.network : ips.local

if (email === true) log.info(`[ejs-serve] using mjml...`)
if (email === true) log.info(`using mjml...`)

const watcher = new Watcher(file, json, dataFile, email, server, network)
const watcher = new Watcher(file, json, dataFile, email, server, ip, shouldOpen)
watcher.run()

}
Expand Down
7 changes: 5 additions & 2 deletions src/utils/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ const chalk = require('chalk')

const log = {
info: (text) => {
console.log(chalk.green(text))
console.log(chalk.green(`[ejs-serve] ${ text }`))
},
warn: (text) => {
console.log(chalk.yellow(`[ejs-serve] ${ text }`))
},
fail: (text) => {
console.log(chalk.red(text))
console.log(chalk.red(`[ejs-serve] ${ text }`))
}
}

Expand Down
25 changes: 19 additions & 6 deletions src/watcher.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
const ejs = require('ejs')
const fs = require('fs')
const mjml = require('mjml')
const open = require('open')

const log = require('./utils/log')

class Watcher {
constructor(file, data, dataFile, email, server, network) {
constructor(file, data, dataFile, email, server, network, shouldOpen) {
this.file = file
this.data = data
this.dataFile = dataFile
this.email = email
this.server = server
this.network = network
this.shouldOpen = shouldOpen
}

async run() {
Expand All @@ -24,23 +26,24 @@ class Watcher {
this.watchData()
}

log.info(`[ejs-serve] watching and serving file '${ this.file }' at ${ this.network }`)
log.info(`watching and serving file '${ this.file }' at ${ this.network }`)
await this.openInBrowser()
}

async watchFile() {
fs.watchFile(this.file, { interval: 500 }, async () => {
log.info(`[ejs-serve] restarting due to changes...`)
log.info(`restarting due to changes...`)

const html = await this.renderFile()
await this.server.restart(html)

log.info(`[ejs-serve] watching and serving file '${ this.file }' at ${ this.network }`)
log.info(`watching and serving file '${ this.file }' at ${ this.network }`)
})
}

async watchData() {
fs.watchFile(this.dataFile, { interval: 500 }, async () => {
log.info(`[ejs-serve] restarting due to changes...`)
log.info(`restarting due to changes...`)

try {
const rawData = fs.readFileSync(this.dataFile)
Expand All @@ -53,7 +56,7 @@ class Watcher {
const html = await this.renderFile()
await this.server.restart(html)

log.info(`[ejs-serve] watching and serving file '${ this.file }' at ${ this.network }`)
log.info(`watching and serving file '${ this.file }' at ${ this.network }`)
})
}

Expand All @@ -73,6 +76,16 @@ class Watcher {

return rawHtml
}

async openInBrowser() {
if (this.shouldOpen) {
try {
await open(`${ this.network }`)
} catch (err) {
log.warn(`Could not open file in browser automatically`)
}
}
}
}

module.exports = Watcher

0 comments on commit 65e59aa

Please sign in to comment.