0

Problem

I have a script that worked by running node index.js. As I am attempting to emulate the structure of an AWS Lambda function, I moved the running logic of the code into a function defined as export async function handler(...) {. This function can be executed via the command line with the command node -e "import('./index.js').then(module => module.handler())".

Desired outcome

I would like to run the command: node -e "import('./index.js').then(module => module.handler())" by defining it in the npm scripts. Preferably it would be run by executing npm start.

Attempted Solutions

In package.json:

{
  ...
  "scripts": {
    "start": "...",
  },
  ...
}

Attempts were made with "start": "..." set to these, returned errors when executing:

  • "node -e 'import(\\'./index.js\\').then(module => module.handler())'"
  • "node -e 'import(\\'./index.js\\').then(function (module) { module.handler(); })'"
  • "node --eval='import(\\'./index.js\\').then(module => module.handler())'"
  • "node --eval='import(\\'./index.js\\').then(function (module) { module.handler(); })'"

Attempts made with these seemed to not evaluate:

  • "node -e 'import(\\'./index.js\\').handler()'"
  • "node --eval='import(\\'./index.js\\').handler()'"
  • "node -e 'require(\\'./index.js\\').handler()'"
  • "node --eval='require(\\'./index.js\\').handler()'"

I understand these above are redundant, I'm trying to be thorough. Any help would be much appreciated.

CollinD
  • 7,304
  • 2
  • 22
  • 45
holtkampjs
  • 17
  • 6
  • Put the code that you struggle to run using `node -e` into a JavaScript file and run that JS file using `npm start`. Or directly with `node`. – axiac Mar 16 '23 at 19:33
  • I appreciate the answers supplied! @Konrad Your post did answer my question in the way that I envisioned as a solution. Is there an industry standard here that could guide me in the future making decisions between the `node -e ...` and writing a start script for the future? – holtkampjs Mar 16 '23 at 19:49
  • Use `node -e` if the script is short and does not need escaping and explanations. Switch to a bootloader script otherwise. You can put in it as much code is needed and, bonus, you can add comments, format it nicely etc. – axiac Mar 16 '23 at 20:30

3 Answers3

2

I would just create scripts/start.js

import { handler } from './index.js'
handler()

and then...

{
  ...
  "scripts": {
    "start": "node scripts/start.js"
  },
  ...
}
Charlie Martin
  • 8,208
  • 3
  • 35
  • 41
1

This should work:

"start": "node -e \"import('./index.js').then(module => module.handler())\""
Konrad
  • 21,590
  • 4
  • 28
  • 64
0

Based on this answer https://stackoverflow.com/a/68848622/5089567

You can add this code to your script:

import { pathToFileURL } from 'url'

if (import.meta.url === pathToFileURL(process.argv[1]).href) {
  handler()
}

And then just run the file like

node index.js
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • This is a bad idea. The file now contains a component. A component must not try to detect how it is executed and to make decisions based on that. It is the responsibility of the caller to provide the information that the component needs to make decisions. – axiac Mar 16 '23 at 19:35
  • 1
    That's a pretty common pattern in other languages like [python](https://docs.python.org/3/library/__main__.html) – Konrad Mar 16 '23 at 19:38