UNPKG

varan

Version:

A webpack starter kit for offline-first bring-your-own-code apps with server side rendering

174 lines 8.58 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const path_1 = __importDefault(require("path")); const detect_port_alt_1 = __importDefault(require("detect-port-alt")); const listr_1 = __importDefault(require("listr")); const chalk_1 = __importDefault(require("chalk")); const wait_on_1 = __importDefault(require("wait-on")); const emojis_1 = __importDefault(require("./emojis")); const getConfigs_1 = __importDefault(require("./getConfigs")); const buildAndRunDevServer_1 = __importDefault(require("./buildAndRunDevServer")); const buildServer_1 = __importDefault(require("./buildServer")); const getCompilerStats_1 = __importDefault(require("./getCompilerStats")); const runServer_1 = __importDefault(require("./runServer")); const createServerConfig_1 = __importDefault(require("../webpack/createServerConfig")); const createClientConfig_1 = __importDefault(require("../webpack/createClientConfig")); // Init const getOpts = (options) => lodash_1.defaults({}, options, { verbose: false, configs: [createServerConfig_1.default, createClientConfig_1.default], devServerProtocol: 'http', devServerHost: process.env.HOST || 'localhost', devServerPort: process.env.DEV_PORT ? parseInt(process.env.DEV_PORT, 10) : 3000, serverHost: process.env.HOST || 'localhost', serverPort: process.env.PORT ? parseInt(process.env.PORT, 10) : undefined, env: 'development', appDir: process.cwd(), args: process.argv.includes('--') ? process.argv.slice(process.argv.indexOf('--') + 1) : [], openBrowser: false, waitForServer: true, }); // Exports async function watch(options) { const opts = getOpts(options); // Load configs if (opts.configs.length > 2) { throw new Error('Too many config files provided. Maximum two config files are supported in `watch` mode.'); } const configs = getConfigs_1.default(opts.configs, opts); const clientConfig = configs.find((c) => !c.target || c.target === 'web'); const serverConfig = configs.find((c) => c.target === 'node'); // Check if config is valid if (configs.length >= 2 && (!clientConfig || !serverConfig)) { throw new Error('One or more invalid config files provided. Maximum of one config file per target is supported.'); } const taskOptions = { showSubtasks: true, renderer: opts.verbose ? 'default' : 'silent', nonTTYRenderer: opts.verbose ? 'verbose' : 'silent', }; const tasks = new listr_1.default([ { title: 'Prepare', task: async () => { // Prepare opts.devServerPort = await detect_port_alt_1.default(opts.devServerPort, opts.devServerHost); opts.serverPort = await detect_port_alt_1.default((opts.serverPort && opts.serverPort !== opts.devServerPort && opts.serverPort) || opts.devServerPort + 1, opts.serverHost); process.env.HOST = opts.serverHost; opts.serverHost = process.env.HOST; opts.devServerWSPort = await detect_port_alt_1.default(opts.devServerPort + 10, opts.devServerHost); process.env.PORT = opts.serverPort.toString(); process.env.BABEL_ENV = opts.env; return `${chalk_1.default.green(emojis_1.default.success)} Preparations completed successfully`; }, }, { title: 'Build', task: () => new listr_1.default([ { title: 'Build and start client development server', enabled: () => !!clientConfig, task: async (ctx) => { opts.devServerProxy = !!serverConfig; const devServerOpts = Object.assign(Object.assign({}, opts), { waitForPromise: new Promise((resolve, reject) => { if (opts.waitForServer && !!serverConfig) { wait_on_1.default({ resources: [`tcp:${opts.serverHost}:${opts.serverPort}`], }, (err) => { if (err) return reject(err); return resolve(); }); } else resolve(); }) }); ctx.client = await buildAndRunDevServer_1.default(clientConfig, opts.devServerHost, opts.devServerPort, devServerOpts); return `${chalk_1.default.green(emojis_1.default.success)} Development server built successfully!`; }, }, { title: 'Build server', enabled: () => !!serverConfig, task: async (ctx) => { const serverOpts = Object.assign({}, opts); ctx.server = await buildServer_1.default(serverConfig, serverOpts); return `${chalk_1.default.green(emojis_1.default.success)} Server built successfully!`; }, }, ], { showSubtasks: true, concurrent: true, renderer: opts.silent ? 'silent' : 'default', }), }, { title: 'Calculate statistics', task: (ctx) => { ctx.totals = getCompilerStats_1.default([ctx.server && ctx.server.stats, ctx.client && ctx.client.stats].filter(Boolean)); return `${chalk_1.default.green(emojis_1.default.success)} Build statistics calculated successfully`; }, }, { title: 'Start server', enabled: (ctx) => !!ctx.server, task: async (ctx) => { const rootPath = lodash_1.get(ctx, 'server.compiler.options.output.path', null); const entryFile = lodash_1.get(ctx, 'server.compiler.options.output.filename', null); if (rootPath && entryFile) { const serverOpts = Object.assign(Object.assign({}, opts), { entry: path_1.default.resolve(rootPath, entryFile) }); const { server } = (await runServer_1.default(serverOpts)); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ctx.server.runner = server; } return `${chalk_1.default.green(emojis_1.default.success)} Server started successfully`; }, }, ], taskOptions); /** * Watch project */ // Set up the task queue const result = await tasks.run(); // Create watching helpers const clientWatcher = result.client ? { warnings: result.client.warnings, compiler: result.client.compiler, runner: result.client.runner, async close() { return Promise.all([ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.client && result.client.runner && new Promise((resolve) => result.client.runner.close(resolve)), ].filter(Boolean)); }, } : null; const serverWatcher = result.server ? { warnings: result.server.warnings, compiler: result.server.compiler, runner: result.server.runner, watcher: result.server.watcher, async close() { return Promise.all([ new Promise((resolve) => result.server && result.server.watcher.close(resolve)), new Promise((resolve) => { if (result.server) { result.server.runner.once('close', resolve); result.server.runner.kill(); } }), ]); }, } : null; const close = async () => Promise.all([serverWatcher && serverWatcher.close(), clientWatcher && clientWatcher.close()].filter(Boolean)); return { close, client: clientWatcher, server: serverWatcher, totals: result.totals, options: opts }; } exports.default = watch; //# sourceMappingURL=watch.js.map