diff --git a/lib/plugins/aws/dev/index.js b/lib/plugins/aws/dev/index.js index 71a19a137..5a95359d9 100644 --- a/lib/plugins/aws/dev/index.js +++ b/lib/plugins/aws/dev/index.js @@ -60,6 +60,8 @@ class AwsDev { await this.update(); + this._updateHooks(); + await this.serverless.pluginManager.spawn('deploy'); await this.restore(); @@ -67,6 +69,31 @@ class AwsDev { await this.connect(); } + /** + * When using devmode we are not actually building deploymentArtifacts and are instead + * using devmode specific hooks and plugins so we remove all createDeploymentArtifacts + * hooks when running dev mode + */ + _updateHooks() { + for (const hook of this.serverless.pluginManager.hooks[ + 'after:package:createDeploymentArtifacts' + ]) { + if (hook.pluginName === 'AwsDev') { + continue; + } + hook.hook = async () => {}; + } + + for (const hook of this.serverless.pluginManager.hooks[ + 'before:package:createDeploymentArtifacts' + ]) { + if (hook.pluginName === 'AwsDev') { + continue; + } + hook.hook = async () => {}; + } + } + /** * Build, bundle and package the dev mode shim responsible for routing events to the local machine.. * @@ -356,7 +383,7 @@ class AwsDev { process.on('SIGINT', () => { console.log(); console.log( - `Don't forget to run "serverless deploy" to remove dev mode from this stage and region` + 'Don\'t forget to run "serverless deploy" to remove dev mode from this stage and region' ); process.exit(0); }); diff --git a/lib/plugins/aws/dev/local-lambda/index.js b/lib/plugins/aws/dev/local-lambda/index.js index 3df09f3bc..ee57dadb7 100644 --- a/lib/plugins/aws/dev/local-lambda/index.js +++ b/lib/plugins/aws/dev/local-lambda/index.js @@ -150,15 +150,30 @@ class LocalLambda { context, }); + /** + * In some scenarios, like using tsx and typescript, you have to provide a PID using + * an intermediary logline instead of depending on the spawn process id + */ + let resultPID; + // Spawn a child process to execute the runtime wrapper and set the specified environment variables - const child = spawn(runtimeWrapper.command, [runtimeWrapper.path, argsString], { - env: this.environment, - cwd: this.serviceAbsolutePath, - }); + const child = spawn( + runtimeWrapper.command, + [...runtimeWrapper.arguments, runtimeWrapper.path, argsString], + { + env: this.environment, + cwd: this.serviceAbsolutePath, + } + ); // Write standard output child.stdout.on('data', (chunk) => { - process.stdout.write(chunk.toString()); + const logLine = chunk.toString(); + if (logLine.startsWith('RESULT_FILE: ')) { + resultPID = logLine.replace('/tmp/sls_', '').replace('.json', '').trim(); + } else { + process.stdout.write(chunk.toString()); + } }); // Write error output @@ -173,7 +188,7 @@ class LocalLambda { child.on('close', async (code) => { try { - const result = await getInvocationResult(child.pid); + const result = await getInvocationResult(resultPID ?? child.pid); resolve(result); } catch (error) { @@ -237,12 +252,14 @@ const fileExists = async (filePath) => { const runtimeWrappers = [ { command: 'node', + arguments: [], path: path.join(__dirname, 'runtime-wrappers/wrapper.js'), versions: ['nodejs14.x', 'nodejs16.x', 'nodejs18.x', 'nodejs20.x'], extensions: ['.js', '.mjs', '.cjs'], }, { - command: 'ts-node', + command: 'npx', + arguments: ['tsx'], path: path.join(__dirname, 'runtime-wrappers/wrapper.ts'), versions: ['nodejs14.x', 'nodejs16.x', 'nodejs18.x', 'nodejs20.x'], extensions: ['.ts', '.mts', '.cts'], diff --git a/lib/plugins/aws/dev/local-lambda/runtime-wrappers/wrapper.ts b/lib/plugins/aws/dev/local-lambda/runtime-wrappers/wrapper.ts index 909e63ad4..e5e059be5 100644 --- a/lib/plugins/aws/dev/local-lambda/runtime-wrappers/wrapper.ts +++ b/lib/plugins/aws/dev/local-lambda/runtime-wrappers/wrapper.ts @@ -107,6 +107,8 @@ const invokeFunction = async (handlerFunction: Function) => { // Import and invoke the handler function const response = await invokeFunction(await importFunction()); + console.log(`RESULT_FILE: ${path.join(os.tmpdir(), `sls_${process.pid}.json`)}`) + // Save the response for the parent process to fetch and return to Lambda saveInvocationResult({ response, error: null }); } catch (error: any) { diff --git a/package.json b/package.json index 8524eb62c..4cb802325 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "supports-color": "^8.1.1", "tar": "^6.1.15", "timers-ext": "^0.1.7", + "tsx": "^4.7.2", "type": "^2.7.2", "untildify": "^4.0.0", "uuid": "^9.0.0",