import { promises as fs } from 'fs' import { join, extname, basename } from 'path' import connect from 'connect' import serveStatic from 'serve-static' import compression from 'compression' import { getNuxtConfig } from '@nuxt/config' import { TARGETS } from '@nuxt/utils' import { common, server } from '../options' import { showBanner } from '../utils/banner' import * as imports from '../imports' export default { name: 'serve', description: 'Serve the exported static application (should be compiled with `nuxt build` and `nuxt export` first)', usage: 'serve ', options: { 'config-file': common['config-file'], version: common.version, help: common.help, ...server }, async run (cmd) { let options = await cmd.getNuxtConfig({ dev: false }) // add default options options = getNuxtConfig(options) try { // overwrites with build config const buildConfig = require(join(options.buildDir, 'nuxt/config.json')) options.target = buildConfig.target } catch (err) {} if (options.target === TARGETS.server) { throw new Error('You cannot use `nuxt serve` with ' + TARGETS.server + ' target, please use `nuxt start`') } const distStat = await fs.stat(options.generate.dir).catch(err => null) // eslint-disable-line handle-callback-err if (!distStat || !distStat.isDirectory()) { throw new Error('Output directory `' + basename(options.generate.dir) + '/` does not exists, please run `nuxt export` before `nuxt serve`.') } const app = connect() app.use(compression({ threshold: 0 })) app.use( options.router.base, serveStatic(options.generate.dir, { extensions: ['html'] }) ) if (options.generate.fallback) { const fallbackFile = await fs.readFile(join(options.generate.dir, options.generate.fallback), 'utf-8') app.use((req, res, next) => { const ext = extname(req.url) || '.html' if (ext !== '.html') { return next() } res.writeHeader(200, { 'Content-Type': 'text/html' }) res.write(fallbackFile) res.end() }) } const { port, host, socket, https } = options.server const { Listener } = await imports.server() const listener = new Listener({ port, host, socket, https, app, dev: true, // try another port if taken baseURL: options.router.base }) await listener.listen() const { Nuxt } = await imports.core() showBanner({ constructor: Nuxt, options, server: { listeners: [listener] } }, false) } }