mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(core, cli): builtin support of https and unix sockets (#3831)
Co-authored-by: Aurélien Chrétien <aurelien@manager.one> Co-authored-by: Rémy Sanchez <remy.sanchez@hyperthese.net>
This commit is contained in:
parent
4f6a048a4b
commit
72479687d9
@ -52,3 +52,22 @@ exports.loadNuxtConfig = (argv) => {
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
exports.getLatestHost = (argv) => {
|
||||
const port =
|
||||
argv.port ||
|
||||
process.env.NUXT_PORT ||
|
||||
process.env.PORT ||
|
||||
process.env.npm_package_config_nuxt_port
|
||||
const host =
|
||||
argv.hostname ||
|
||||
process.env.NUXT_HOST ||
|
||||
process.env.HOST ||
|
||||
process.env.npm_package_config_nuxt_host
|
||||
const socket =
|
||||
argv['unix-socket'] ||
|
||||
process.env.UNIX_SOCKET ||
|
||||
process.env.npm_package_config_unix_socket
|
||||
|
||||
return { port, host, socket }
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ const parseArgs = require('minimist')
|
||||
const consola = require('consola')
|
||||
const { version } = require('../package.json')
|
||||
const { Nuxt, Builder } = require('..')
|
||||
const { loadNuxtConfig } = require('./common/utils')
|
||||
const { loadNuxtConfig, getLatestHost } = require('./common/utils')
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
@ -75,7 +75,7 @@ const errorHandler = (err, instance) => {
|
||||
}
|
||||
|
||||
// Get latest environment variables
|
||||
const { port, host } = nuxt.options.server
|
||||
const { port, host, socket } = getLatestHost(argv)
|
||||
|
||||
return (
|
||||
Promise.resolve()
|
||||
@ -91,7 +91,7 @@ const errorHandler = (err, instance) => {
|
||||
})
|
||||
.then(() => oldInstance && oldInstance.nuxt.close())
|
||||
// Start listening
|
||||
.then(() => nuxt.listen(port, host))
|
||||
.then(() => nuxt.listen(port, host, socket))
|
||||
// Show ready message first time, others will be shown through WebpackBar
|
||||
.then(() => !oldInstance && nuxt.showReady(false))
|
||||
.then(() => builder.watchServer())
|
||||
|
@ -4,19 +4,20 @@ const { resolve } = require('path')
|
||||
const parseArgs = require('minimist')
|
||||
const consola = require('consola')
|
||||
const { Nuxt } = require('../dist/nuxt-start')
|
||||
const { loadNuxtConfig } = require('./common/utils')
|
||||
const { loadNuxtConfig, getLatestHost } = require('./common/utils')
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
H: 'hostname',
|
||||
p: 'port',
|
||||
n: 'unix-socket',
|
||||
c: 'config-file',
|
||||
s: 'spa',
|
||||
u: 'universal'
|
||||
},
|
||||
boolean: ['h', 's', 'u'],
|
||||
string: ['H', 'c'],
|
||||
string: ['H', 'c', 'n'],
|
||||
default: {
|
||||
c: 'nuxt.config.js'
|
||||
}
|
||||
@ -36,6 +37,7 @@ if (argv.help) {
|
||||
Options
|
||||
--port, -p A port number on which to start the application
|
||||
--hostname, -H Hostname on which to start the application
|
||||
--unix-socket, -n Path to a UNIX socket
|
||||
--spa Launch in SPA mode
|
||||
--universal Launch in Universal mode (default)
|
||||
--config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
|
||||
@ -77,8 +79,8 @@ if (nuxt.options.render.ssr === true) {
|
||||
}
|
||||
}
|
||||
|
||||
const { port, host } = nuxt.options.server
|
||||
const { port, host, socket } = getLatestHost(argv)
|
||||
|
||||
nuxt.listen(port, host).then(() => {
|
||||
nuxt.listen(port, host, socket).then(() => {
|
||||
nuxt.showReady(false)
|
||||
})
|
||||
|
@ -16,6 +16,7 @@ export default {
|
||||
|
||||
// Server options
|
||||
server: {
|
||||
https: false,
|
||||
port: process.env.NUXT_PORT ||
|
||||
process.env.PORT ||
|
||||
process.env.npm_package_config_nuxt_port,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Module from 'module'
|
||||
import { resolve, join } from 'path'
|
||||
import https from 'https'
|
||||
|
||||
import enableDestroy from 'server-destroy'
|
||||
import _ from 'lodash'
|
||||
@ -141,25 +142,62 @@ export default class Nuxt {
|
||||
this.readyMessage = null
|
||||
}
|
||||
|
||||
listen(port = 3000, host = 'localhost') {
|
||||
listen(port = 3000, host = 'localhost', socket = null) {
|
||||
return this.ready().then(() => new Promise((resolve, reject) => {
|
||||
const server = this.renderer.app.listen(
|
||||
{ port, host, exclusive: false },
|
||||
if (!socket && typeof this.options.server.socket === 'string') {
|
||||
socket = this.options.server.socket
|
||||
}
|
||||
|
||||
const args = { exclusive: false }
|
||||
|
||||
if (socket) {
|
||||
args.path = socket
|
||||
} else {
|
||||
args.port = port
|
||||
args.host = host
|
||||
}
|
||||
|
||||
let appServer
|
||||
const isHttps = Boolean(this.options.server.https)
|
||||
|
||||
if (isHttps) {
|
||||
let httpsOptions
|
||||
|
||||
if (this.options.server.https === true) {
|
||||
httpsOptions = {}
|
||||
} else {
|
||||
httpsOptions = this.options.server.https
|
||||
}
|
||||
|
||||
appServer = https.createServer(httpsOptions, this.renderer.app)
|
||||
} else {
|
||||
appServer = this.renderer.app
|
||||
}
|
||||
|
||||
const server = appServer.listen(
|
||||
args,
|
||||
(err) => {
|
||||
/* istanbul ignore if */
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
({ address: host, port } = server.address())
|
||||
if (host === '127.0.0.1') {
|
||||
host = 'localhost'
|
||||
} else if (host === '0.0.0.0') {
|
||||
host = ip.address()
|
||||
}
|
||||
let listenURL
|
||||
|
||||
const listenURL = chalk.underline.blue(`http://${host}:${port}`)
|
||||
this.readyMessage = `Listening on ${listenURL}`
|
||||
if (!socket) {
|
||||
({ address: host, port } = server.address())
|
||||
if (host === '127.0.0.1') {
|
||||
host = 'localhost'
|
||||
} else if (host === '0.0.0.0') {
|
||||
host = ip.address()
|
||||
}
|
||||
|
||||
listenURL = chalk.underline.blue(`http${isHttps ? 's' : ''}://${host}:${port}`)
|
||||
this.readyMessage = `Listening on ${listenURL}`
|
||||
} else {
|
||||
listenURL = chalk.underline.blue(`unix+http://${socket}`)
|
||||
this.readyMessage = `Listening on ${listenURL}`
|
||||
}
|
||||
|
||||
// Close server on nuxt close
|
||||
this.hook(
|
||||
@ -178,7 +216,11 @@ export default class Nuxt {
|
||||
})
|
||||
)
|
||||
|
||||
this.callHook('listen', server, { port, host }).then(resolve)
|
||||
if (socket) {
|
||||
this.callHook('listen', server, { path: socket }).then(resolve)
|
||||
} else {
|
||||
this.callHook('listen', server, { port, host }).then(resolve)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
3
test/fixtures/https/https.test.js
vendored
Normal file
3
test/fixtures/https/https.test.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { buildFixture } from '../../utils/build'
|
||||
|
||||
buildFixture('https')
|
11
test/fixtures/https/nuxt.config.js
vendored
Normal file
11
test/fixtures/https/nuxt.config.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
server: {
|
||||
https: {
|
||||
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
|
||||
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
|
||||
}
|
||||
}
|
||||
}
|
3
test/fixtures/https/pages/index.vue
vendored
Normal file
3
test/fixtures/https/pages/index.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<h1>Served over HTTPS!</h1>
|
||||
</template>
|
19
test/fixtures/https/server.crt
vendored
Normal file
19
test/fixtures/https/server.crt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDIjCCAougAwIBAgIJALww5SutcTujMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV
|
||||
BAYTAkJSMRIwEAYDVQQIEwlTYW8gUGF1bG8xETAPBgNVBAcTCEJhcnJldG9zMQ0w
|
||||
CwYDVQQKEwROdXh0MREwDwYDVQQLEwhGaXh0dXJlczESMBAGA1UEAxMJbG9jYWxo
|
||||
b3N0MB4XDTE4MDkwMTIzMTk0OVoXDTE4MTAwMTIzMTk0OVowajELMAkGA1UEBhMC
|
||||
QlIxEjAQBgNVBAgTCVNhbyBQYXVsbzERMA8GA1UEBxMIQmFycmV0b3MxDTALBgNV
|
||||
BAoTBE51eHQxETAPBgNVBAsTCEZpeHR1cmVzMRIwEAYDVQQDEwlsb2NhbGhvc3Qw
|
||||
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoFJlquH9KNTPS3E0jbdKWLVw+N
|
||||
oQaV+yPGPJb/IEAtg2cgMy62UlBS8eMTnMAv6JntuSuqS9wWdrvrTvcJkbbCRnKp
|
||||
P13OTPpzhXO8R9pgzsopaO0DfLM8mTpFi1UPhzRm5riRCVIcg/KYH5JybI7LVzVu
|
||||
v6LT3DhOtqp3tufRAgMBAAGjgc8wgcwwHQYDVR0OBBYEFIHCFtBMyB2w+os85zPR
|
||||
AkI05z4FMIGcBgNVHSMEgZQwgZGAFIHCFtBMyB2w+os85zPRAkI05z4FoW6kbDBq
|
||||
MQswCQYDVQQGEwJCUjESMBAGA1UECBMJU2FvIFBhdWxvMREwDwYDVQQHEwhCYXJy
|
||||
ZXRvczENMAsGA1UEChMETnV4dDERMA8GA1UECxMIRml4dHVyZXMxEjAQBgNVBAMT
|
||||
CWxvY2FsaG9zdIIJALww5SutcTujMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||
BQADgYEARaylCmK13yfaARc3utZLmD+vW7P1S4CO25skgaaQasKsKtABTURz92Ju
|
||||
fShBFvP6d8AQH3yvHEC2+QBUibg6tc9oT1hE1GXYczp11AvYry3hcbalB+V1vqN+
|
||||
/vMAWDmg5Y0cE/QnJ8YZi2fHFoxkxJdDIfx5/w19vvE5h18IMro=
|
||||
-----END CERTIFICATE-----
|
15
test/fixtures/https/server.key
vendored
Normal file
15
test/fixtures/https/server.key
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQC6BSZarh/SjUz0txNI23Sli1cPjaEGlfsjxjyW/yBALYNnIDMu
|
||||
tlJQUvHjE5zAL+iZ7bkrqkvcFna76073CZG2wkZyqT9dzkz6c4VzvEfaYM7KKWjt
|
||||
A3yzPJk6RYtVD4c0Zua4kQlSHIPymB+ScmyOy1c1br+i09w4Traqd7bn0QIDAQAB
|
||||
AoGAWZpBb0yQZ4tIllfZIi8TcOo9dXBzMAjuf7ztUo5xqnhB41rPTKDl5WsOuKKp
|
||||
zqlFEWBA4ZeWEt1/M+WUk8o4NU2M03Q5N7cubw2T6/q43pZkCjvdTScsP6sJgGK9
|
||||
zR0o4+Owu9J5j+X9e7ChfZFVeZa3WCX6dCB17AVfUdCh7EECQQDpPdkLirOsiu5x
|
||||
/b42+/dLpL4gq+mnAqLzaeHI0Eb2Gt9A8RyxPicdjZGOJ3bmGZPFWcu2xUbmEsic
|
||||
pSbAmZujAkEAzCvBLokZ2ETJN1pZJgT3luUDmd6LsaW8BJoJ42ECM/k8ARKMJfIS
|
||||
/tqZPJhdkZ6JhYc36m4lNwPaY7x4Cbxl+wJBAM1WBZ6DnWppZUI1gSAm8q9FeZyJ
|
||||
vEmrqIlizcNcmRxQy/sASaJAdW8vEtVzKNmp6s3zH8ToKGKkZriBLHyivsECQALF
|
||||
zVfOcNVpCbqAtZk4lAwui//477i34XfGh7/Yv2jpR5FUKScSxINFgLM79nlVx9RS
|
||||
Y8YBPOwkV0DnfFHVhyUCQFYYp2B8XgghJGapOcWvp7QogkDWqCra5mrSlI+jzi5W
|
||||
b1LjJqCCCq4kGK6nKEzT7gd75lb2LbcUdc5JfFHbcE0=
|
||||
-----END RSA PRIVATE KEY-----
|
7
test/fixtures/sockets/nuxt.config.js
vendored
Normal file
7
test/fixtures/sockets/nuxt.config.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
server: {
|
||||
socket: path.resolve(__dirname, 'nuxt.socket')
|
||||
}
|
||||
}
|
3
test/fixtures/sockets/pages/index.vue
vendored
Normal file
3
test/fixtures/sockets/pages/index.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<h1>Served over sockets!</h1>
|
||||
</template>
|
3
test/fixtures/sockets/sockets.test.js
vendored
Normal file
3
test/fixtures/sockets/sockets.test.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { buildFixture } from '../../utils/build'
|
||||
|
||||
buildFixture('sockets')
|
22
test/unit/https.test.js
Normal file
22
test/unit/https.test.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { loadFixture, getPort, Nuxt } from '../utils'
|
||||
|
||||
let nuxt = null
|
||||
|
||||
describe('basic https', () => {
|
||||
beforeAll(async () => {
|
||||
const options = await loadFixture('https')
|
||||
nuxt = new Nuxt(options)
|
||||
const port = await getPort()
|
||||
await nuxt.listen(port, '0.0.0.0')
|
||||
})
|
||||
|
||||
test('/', async () => {
|
||||
const { html } = await nuxt.renderRoute('/')
|
||||
expect(html.includes('<h1>Served over HTTPS!</h1>')).toBe(true)
|
||||
})
|
||||
|
||||
// Close server and ask nuxt to stop listening to file changes
|
||||
afterAll(async () => {
|
||||
await nuxt.close()
|
||||
})
|
||||
})
|
21
test/unit/sockets.test.js
Normal file
21
test/unit/sockets.test.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { loadFixture, Nuxt } from '../utils'
|
||||
|
||||
let nuxt = null
|
||||
|
||||
describe.skip.appveyor('basic sockets', () => {
|
||||
beforeAll(async () => {
|
||||
const options = await loadFixture('sockets')
|
||||
nuxt = new Nuxt(options)
|
||||
await nuxt.listen()
|
||||
})
|
||||
|
||||
test('/', async () => {
|
||||
const { html } = await nuxt.renderRoute('/')
|
||||
expect(html.includes('<h1>Served over sockets!</h1>')).toBe(true)
|
||||
})
|
||||
|
||||
// Close server and ask nuxt to stop listening to file changes
|
||||
afterAll(async () => {
|
||||
await nuxt.close()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user