UNPKG

@ima/cli

Version:

IMA.js CLI tool to build, develop and work with IMA.js applications.

200 lines (199 loc) 7.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.builder = exports.handler = exports.describe = exports.command = void 0; const path_1 = __importDefault(require("path")); const logger_1 = require("@ima/dev-utils/logger"); const better_opn_1 = __importDefault(require("better-opn")); const chalk_1 = __importDefault(require("chalk")); const kill_port_1 = __importDefault(require("kill-port")); const nodemon_1 = __importDefault(require("nodemon")); const webpack_1 = __importDefault(require("webpack")); const devServer_1 = require("../dev-server/devServer"); const cli_1 = require("../lib/cli"); const compiler_1 = require("../lib/compiler"); const languages_1 = require("../webpack/languages"); const utils_1 = require("../webpack/utils"); /** * Starts ima server with nodemon to watch for server-side changes * (all changes in server/ folder), to automatically restart the application * server in case any change is detected. */ function startNodemon(args, environment) { let serverHasStarted = false; (0, nodemon_1.default)({ script: path_1.default.join(args.rootDir, 'server/server.js'), watch: ['server', 'build/static/public/spa.html'].map(p => path_1.default.join(args.rootDir, p)), args: args.verbose ? [`--verbose=${args.verbose}`] : [], nodeArgs: args.inspect ? [`--inspect`] : [], cwd: args.rootDir, }) .on('start', () => { logger_1.logger.info(`${serverHasStarted ? 'Restarting' : 'Starting'} application server${!serverHasStarted && args.forceSPA ? ` in ${chalk_1.default.black.bgCyan('SPA mode')}` : ''}...`); if (process.env.IMA_CLI_OPEN !== 'false' && args.open && !serverHasStarted) { serverHasStarted = true; const port = environment.$Server.port; const openUrl = args.openUrl ?? process.env.IMA_CLI_OPEN_URL ?? `http://localhost:${port}`; try { (0, better_opn_1.default)(openUrl); } catch (error) { logger_1.logger.error(`Could not open ${openUrl} inside a browser, ${error}`); } } }) .on('crash', () => { logger_1.logger.error('Application watcher crashed unexpectedly.'); }); } /** * Builds ima application in watch mode * while also starting the webserver itself. * * @param {ImaCliArgs} args * @returns {Promise<void>} */ const dev = async (args) => { process.env.IMA_CLI_WATCH = 'true'; // Set write to disk flag, so we can disable static proxy in the application if (args.writeToDisk) { process.env.IMA_CLI_WRITE_TO_DISK = 'true'; } // Set force SPA flag so server can react accordingly if (args.forceSPA) { process.env.IMA_CLI_FORCE_SPA = 'true'; } // Set lazy server flag according to CLI args if (args.lazyServer) { process.env.IMA_CLI_LAZY_SERVER = 'true'; } // Set legacy argument to true by default when we're forcing legacy if (args.forceLegacy) { args.legacy = true; } try { // Do cleanup await (0, utils_1.cleanup)(args); // Load ima config & env const imaConfig = await (0, utils_1.resolveImaConfig)(args); const environment = (0, utils_1.resolveEnvironment)(args.rootDir); /** * Set public env variable which is used to load assets in the SSR error view. * CLI Args should always override the config values. */ const devServerConfig = (0, utils_1.createDevServerConfig)({ imaConfig, args }); process.env.IMA_CLI_DEV_SERVER_PUBLIC_URL = devServerConfig.publicUrl; // Kill processes running on the same port await Promise.all([ (0, kill_port_1.default)(environment.$Server.port), (0, kill_port_1.default)(devServerConfig.port), ]); // Run preProcess hook on IMA CLI Plugins await (0, utils_1.runImaPluginsHook)(args, imaConfig, 'preProcess'); // Compile language files logger_1.logger.info(`Compiling language files...`, { trackTime: true }); await (0, languages_1.compileLanguages)(imaConfig, args.rootDir, true); logger_1.logger.endTracking(); // Generate webpack config const config = await (0, utils_1.createWebpackConfig)(args, imaConfig); logger_1.logger.info(`Running webpack watch compiler${args.legacy ? ` ${chalk_1.default.black.bgCyan(`in${args.forceLegacy ? ' forced' : ''} legacy mode`)}` : ''}...`); // Create compiler const compiler = (0, webpack_1.default)(config); // Start watch compiler & HMR dev server await Promise.all([ (0, compiler_1.watchCompiler)(compiler, args, imaConfig), (0, devServer_1.createDevServer)({ args, config: imaConfig, compiler: compiler.compilers.find(({ name }) => // Run dev server only for client compiler with HMR enabled name === 'client.es'), hostname: devServerConfig.hostname, port: devServerConfig.port, publicUrl: devServerConfig.publicUrl, rootDir: args.rootDir, environment, }), ]); // Start nodemon and application server startNodemon(args, environment); } catch (error) { if (args.verbose) { console.error(error); } else { (0, compiler_1.handleError)(error); } process.exit(1); } }; const CMD = 'dev'; exports.command = CMD; exports.describe = 'Run application in development watch mode'; exports.handler = (0, cli_1.handlerFactory)(dev); exports.builder = { ...(0, cli_1.sharedArgsFactory)(CMD), open: { desc: 'Opens browser window after server has been started', type: 'boolean', default: true, }, openUrl: { desc: 'Custom URL used when opening browser window ', type: 'string', }, legacy: { desc: 'Runs application in legacy mode', type: 'boolean', default: false, }, forceLegacy: { desc: 'Forces runner.js to execute legacy client code', type: 'boolean', default: false, }, forceSPA: { desc: 'Forces application to run in SPA mode', type: 'boolean', default: false, }, writeToDisk: { desc: 'Write static files to disk, instead of serving it from memory', type: 'boolean', default: false, }, reactRefresh: { desc: 'Enable/disable react fast refresh for React components', type: 'boolean', default: true, }, lazyServer: { desc: 'Enable/disable lazy init of server app factory', type: 'boolean', default: true, }, port: { desc: 'Dev server port (overrides ima.config.js settings)', type: 'number', }, hostname: { desc: 'Dev server hostname (overrides ima.config.js settings)', type: 'string', }, publicUrl: { desc: 'Dev server publicUrl (overrides ima.config.js settings)', type: 'string', }, ...(0, cli_1.resolveCliPluginArgs)(CMD), };