Basics In Node.js, spawn is a method provided by the child_process module it used to launch a new process and execute a command in that process spawn function returns a new ChildProcess object, which allows you to interact with the spawned process ChildProcess emits various events, such as stdout (standard output), stderr (standard error), and close (when the process exits). we can interact with the spawned process through its stdin , stdout , and stderr streams. This allows you to send input to the process and capture its output const { spawn } = require('child_process'); const ls = spawn('ls', ['-l', '/usr']); // Event listeners for the spawned process ls.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); ls.stderr.on('data', (data) => { console.error(`stderr: ${data}`); }); ls.on('close', (code) => { console.log(`child process exited with code ${code}`); }); promise version const { red, white, grey } = require('chalk') // const { spawn } = require('node:child_process') const { spawn } = require('cross-spawn') // https://nodejs.org/api/child_process.html#child_processspawncommand-args-options const currentDir = __dirname const runCommand = ({ command = 'echo "looks like you forgot to provide the terminal command"', args = [], options = { cwd: currentDir, shell: true, stdio: 'inherit' } }) => { return new Promise((resolve, reject) => { const process = spawn(command, args, options) process.on('message', (msg) => { console.log(`🔈 ${white(msg)}`) }) process.on('close', async (code) => { if (code !== 0) { console.log(grey('❌ command is failed')) console.log(grey(JSON.stringify({ command, args, options, code }, null, 2))) return reject(new Error(`Execution of command "${command}" failed with status ${code}. CWD: ${options.cwd}`)) } console.log(grey('✅ command is finished')) return resolve() }) process.on('error', (err) => { console.log(`😤 err: ${red(err.toString())}`) console.log(red(JSON.stringify({ command, args, options, err }, null, 2))) return reject(new Error(`Execution of command "${command}" failed (in ${options.cwd}): ${err.message}`)) }) process.stdout?.on('data', (data) => { console.log(`${white('🗣️ stdout:')} ${grey(data.toString())}`) }) process.stderr?.on('data', (data) => { console.log(`🤬 stderr: ${red(data.toString())}`) }) }) } module.exports = { runCommand } remove folders const { underline, yellow, grey, green } = require('chalk') const { runCommand } = require('../utils/runCommand') const { getLambdasFromFileSystem } = require('./getLambdasFromFileSystem') const { chooseLambdaFolderPaths } = require('../prompts') const deleteNodeModules = async () => { const lambdas = await getLambdasFromFileSystem() const lambdaFolderPaths = await chooseLambdaFolderPaths({ lambdas }) await Promise.all(lambdaFolderPaths.map(async (dir) => { console.log(`> [${yellow('~')}] 🗂️ ${dir}/node_modules: ${grey('delete')}`) await runCommand({ command: 'rm', args: ['-rf', 'node_modules'], options: { cwd: dir } }) console.log(`> [${green('+')}] 🗂️ ${dir}/node_modules: ${grey('delete')}`) })) } deleteNodeModules() module.exports = { deleteNodeModules } npm ci const { runCommand } = require('../utils/runCommand') const npmCiFromRoot = async () => { await runCommand({ command: 'npm', args: ['ci'] }) } npmCiFromRoot() npm i in folders const { runCommand } = require('../utils/runCommand') const npmI = async ({ dirs }) => { await Promise.all(dirs.map(async (dir) => { await runCommand({ command: 'npm', args: ['i'], options: { cwd: dir } }) })) } module.exports = { npmI } run tests in folders const { runCommand } = require('../utils/runCommand') const test = async ({ lambdaFolderPaths }) => { await Promise.all(lambdaFolderPaths.map(async (dir) => { await runCommand({ command: 'npm', args: ['run', 'test'], options: { cwd: dir, stdio: 'inherit' } }) })) } module.exports = { test } run command from node modules const { runCommand } = require('../utils/runCommand') const builtTemplateYaml = async () => { await runCommand({ command: './node_modules/.bin/cfbuild', args: ['template', '-t', 'template.yaml', '-o', 'built_template.yaml'], options: { stdio: 'inherit' } }) } module.exports = { builtTemplateYaml } create cloudformaton package const { runCommand } = require('../utils/runCommand') const { getAppRootDir } = require('../utils/getAppRootDir') const { getPackageName } = require('../utils') const packagedTemplateYaml = async () => { const packageName = await getPackageName() await runCommand({ command: 'aws', args: [ 'cloudformation', 'package', '--template-file', 'built_template.yaml', '--s3-bucket', 'heeros-cloudformation-build', '--s3-prefix', packageName, '--output-template-file', 'packaged_template.yaml' ], options: { cwd: getAppRootDir() } }) } module.exports = { packagedTemplateYaml }