Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 45 additions & 52 deletions src/commands/dev/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const {flags} = require('@oclif/command')
const {spawn} = require('child_process')
const { flags } = require('@oclif/command')
const { spawn } = require('child_process')
const http = require('http')
const httpProxy = require('http-proxy')
const waitPort = require('wait-port')
const getPort = require('get-port')
const {serveFunctions} = require('@netlify/zip-it-and-ship-it')
const {serverSettings} = require('../../detect-server')
const { serveFunctions } = require('@netlify/zip-it-and-ship-it')
const { serverSettings } = require('../../detect-server')
const Command = require('@netlify/cli-utils')
const {getAddons} = require('netlify/src/addons')
const { getAddons } = require('netlify/src/addons')

function cleanExit() {
process.exit()
Expand All @@ -26,47 +26,45 @@ function addonUrl(addonUrls, req) {
async function startProxy(settings, addonUrls) {
const rulesProxy = require('netlify-rules-proxy')

await waitPort({port: settings.proxyPort})
await waitPort({ port: settings.proxyPort })
if (settings.functionsPort) {
await waitPort({port: settings.functionsPort})
await waitPort({ port: settings.functionsPort })
}
const port = await getPort({port: settings.port})
const functionsServer = settings.functionsPort ?
`http://localhost:${settings.functionsPort}` :
null
const port = await getPort({ port: settings.port })
const functionsServer = settings.functionsPort ? `http://localhost:${settings.functionsPort}` : null

const proxy = httpProxy.createProxyServer({
target: {
host: 'localhost',
port: settings.proxyPort,
},
port: settings.proxyPort
}
})

const rewriter = rulesProxy({publicFolder: settings.dist})
const rewriter = rulesProxy({ publicFolder: settings.dist })

const server = http.createServer(function (req, res) {
const server = http.createServer(function(req, res) {
if (isFunction(settings, req)) {
return proxy.web(req, res, {target: functionsServer})
return proxy.web(req, res, { target: functionsServer })
}
let url = addonUrl(addonUrls, req)
if (url) {
return proxy.web(req, res, {target: url})
return proxy.web(req, res, { target: url })
}

rewriter(req, res, () => {
if (isFunction(settings, req)) {
return proxy.web(req, res, {target: functionsServer})
return proxy.web(req, res, { target: functionsServer })
}
url = addonUrl(addonUrls, req)
if (url) {
return proxy.web(req, res, {target: url})
return proxy.web(req, res, { target: url })
}

proxy.web(req, res, {target: `http://localhost:${settings.proxyPort}`})
proxy.web(req, res, { target: `http://localhost:${settings.proxyPort}` })
})
})

server.on('upgrade', function (req, socket, head) {
server.on('upgrade', function(req, socket, head) {
proxy.ws(req, socket, head)
})

Expand All @@ -82,17 +80,17 @@ function startDevServer(settings, log, error) {
name: 'netlify-dev',
port: settings.proxyPort,
templates: {
notFound: '404.html',
},
notFound: '404.html'
}
})

server.start(function () {
server.start(function() {
log('Server listening to', settings.proxyPort)
})
return
}

const ps = spawn(settings.cmd, settings.args, {env: settings.env})
const ps = spawn(settings.cmd, settings.args, { env: settings.env })

ps.stdout.on('data', data => {
log(`${data}`.replace(settings.urlRegexp, `$1$2${settings.port}$3`))
Expand All @@ -112,24 +110,23 @@ function startDevServer(settings, log, error) {

class DevCommand extends Command {
async run() {
const {flags, args} = this.parse(DevCommand)
const {api, site, config} = this.netlify
const functionsDir =
flags.functions || (config.build && config.build.functions)
const { flags, args } = this.parse(DevCommand)
const { api, site, config } = this.netlify
const functionsDir = flags.functions || (config.build && config.build.functions)
const addonUrls = {}
if (site.id && !flags.offline) {
const accessToken = await this.authenticate()
const addons = await getAddons(site.id, accessToken)
addons.forEach(addon => {
addonUrls[addon.slug] = `${addon.config.site_url}/.netlify/${
addon.slug
}`
for (const key in addon.env) {
process.env[key] = process.env[key] || addon.env[key]
}
})
if (Array.isArray(addons)) {
addons.forEach(addon => {
addonUrls[addon.slug] = `${addon.config.site_url}/.netlify/${addon.slug}`
for (const key in addon.env) {
process.env[key] = process.env[key] || addon.env[key]
}
})
}
const api = this.netlify.api
const apiSite = await api.getSite({site_id: site.id})
const apiSite = await api.getSite({ site_id: site.id })
// TODO: We should move the environment outside of build settings and possibly have a
// `/api/v1/sites/:site_id/environment` endpoint for it that we can also gate access to
// In the future and that we could make context dependend
Expand All @@ -147,12 +144,12 @@ class DevCommand extends Command {
noCmd: true,
port: 8888,
proxyPort: 3999,
dist: config.build && config.build.publish,
dist: config.build && config.build.publish
}
}
startDevServer(settings, this.log, this.error)
if (functionsDir) {
const fnSettings = await serveFunctions({functionsDir})
const fnSettings = await serveFunctions({ functionsDir })
settings.functionsPort = fnSettings.port
}

Expand All @@ -165,30 +162,26 @@ DevCommand.description = `Local dev server
The dev command will run a local dev server with Netlify's proxy and redirect rules
`

DevCommand.examples = [
'$ netlify dev',
'$ netlify dev -c "yarn start"',
'$ netlify dev -c hugo',
]
DevCommand.examples = ['$ netlify dev', '$ netlify dev -c "yarn start"', '$ netlify dev -c hugo']

DevCommand.strict = false

DevCommand.flags = {
cmd: flags.string({char: 'c', description: 'command to run'}),
cmd: flags.string({ char: 'c', description: 'command to run' }),
devport: flags.integer({
char: 'd',
description: 'port of the dev server started by command',
description: 'port of the dev server started by command'
}),
port: flags.integer({char: 'p', description: 'port of netlify dev'}),
dir: flags.integer({char: 'd', description: 'dir with static files'}),
port: flags.integer({ char: 'p', description: 'port of netlify dev' }),
dir: flags.integer({ char: 'd', description: 'dir with static files' }),
functions: flags.string({
char: 'f',
description: 'Specify a functions folder to serve',
description: 'Specify a functions folder to serve'
}),
offline: flags.boolean({
char: 'o',
description: 'disables any features that require network access',
}),
description: 'disables any features that require network access'
})
}

module.exports = DevCommand