import * as fs from 'fs'; import * as path from 'path'; import sade from 'sade'; import colors from 'kleur'; import prettyMs from 'pretty-ms'; import * as pkg from '../package.json'; const prog = sade('sapper').version(pkg.version); prog.command('dev') .describe('Start a development server') .option('-p, --port', 'Specify a port') .option('-o, --open', 'Open a browser window') .option('--dev-port', 'Specify a port for development server') .option('--hot', 'Use hot module replacement (requires webpack)', true) .option('--live', 'Reload on changes if not using --hot', true) .option('--bundler', 'Specify a bundler (rollup or webpack)') .action(async (opts: { port: number, open: boolean, 'dev-port': number, live: boolean, hot: boolean, bundler?: string }) => { const { dev } = await import('./cli/dev'); dev(opts); }); prog.command('build [dest]') .describe('Create a production-ready version of your app') .option('-p, --port', 'Default of process.env.PORT', '3000') .option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)') .option('--legacy', 'Create separate legacy build') .example(`build custom-dir -p 4567`) .action(async (dest = 'build', opts: { port: string, legacy: boolean, bundler?: string }) => { console.log(`> Building...`); process.env.NODE_ENV = process.env.NODE_ENV || 'production'; process.env.SAPPER_DEST = dest; const start = Date.now(); try { const { build } = await import('./cli/build'); await build(opts); const launcher = path.resolve(dest, 'index.js'); fs.writeFileSync(launcher, ` // generated by sapper build at ${new Date().toISOString()} process.env.NODE_ENV = process.env.NODE_ENV || 'production'; process.env.SAPPER_DEST = __dirname; process.env.PORT = process.env.PORT || ${opts.port || 3000}; console.log('Starting server on port ' + process.env.PORT); require('./server.js'); `.replace(/^\t+/gm, '').trim()); console.error(`\n> Finished in ${elapsed(start)}. Type ${colors.bold.cyan(`node ${dest}`)} to run the app.`); } catch (err) { console.log(`${colors.bold.red(`> ${err.message}`)}`); process.exit(1); } }); prog.command('start [dir]') .describe('Start your app') .option('-p, --port', 'Specify a port') .option('-o, --open', 'Open a browser window') .action(async (dir = 'build', opts: { port: number, open: boolean }) => { const { start } = await import('./cli/start'); start(dir, opts); }); prog.command('export [dest]') .describe('Export your app as static files (if possible)') .option('--build', '(Re)build app before exporting', true) .option('--build-dir', 'Specify a custom temporary build directory', '.sapper/prod') .option('--basepath', 'Specify a base path') .option('--timeout', 'Milliseconds to wait for a page (--no-timeout to disable)', 5000) .option('--legacy', 'Create separate legacy build') .option('--bundler', 'Specify a bundler (rollup or webpack, blank for auto)') .action(async (dest = 'export', opts: { build: boolean, legacy: boolean, bundler?: string, 'build-dir': string, basepath?: string, timeout: number | false }) => { process.env.NODE_ENV = 'production'; process.env.SAPPER_DEST = opts['build-dir']; const start = Date.now(); try { if (opts.build) { console.log(`> Building...`); const { build } = await import('./cli/build'); await build(opts); console.error(`\n> Built in ${elapsed(start)}`); } const { exporter } = await import('./cli/export'); await exporter(dest, opts); console.error(`\n> Finished in ${elapsed(start)}. Type ${colors.bold.cyan(`npx serve ${dest}`)} to run the app.`); } catch (err) { console.error(colors.bold.red(`> ${err.message}`)); process.exit(1); } }); // TODO upgrade prog.parse(process.argv); function elapsed(start: number) { return prettyMs(Date.now() - start); }