2

I would like to create npm TypeScript module that can be used both as command line utility and export methods to be used in other modules.

The problem is that command line utility module needs to contain node shebang (#!/usr/bin/env node) in the first line of index.ts. When such module is imported and referenced in another module the code starts to execute before any exported method is actually called. Example:

#!/usr/bin/env node

const arg1: number = parseFloat(process.argv[2]);
const arg2: number = parseFloat(process.argv[3]);

console.log (superCalc(arg1, arg2)); // this gets called when superCalc() is referenced in another module

export function superCalc(arg1: number, arg2: number) : number {
    return arg1 + arg2;
}
  • The code isn't being executed because of the shebang, it's being executed because that's how modules work, they are executed immediately upon require/import. – Jake Holzinger Sep 23 '19 at 23:39

1 Answers1

4

You could put the source code in a different file and allow importing from that file. For example:

src/index.ts

export function superCalc(arg1: number, arg2: number) : number {
    return arg1 + arg2;
}

src/cli.ts

#!/usr/bin/env node

const arg1: number = parseFloat(process.argv[2]);
const arg2: number = parseFloat(process.argv[3]);

console.log (superCalc(arg1, arg2));

package.json

{
  // Additional settings
  "bin": { "your-script": "./dist/cli.js" },
  "main": "dist/index.js",
}

Now the user can execute the CLI (npm run your-script) but also import from index.js (assuming you're compiling the TypeScript for distribution) via import { superCalc } from "your-package". This doesn't include examples for also exporting the methods, but for more details on creating a CLI with TypeScript.

skovy
  • 5,430
  • 2
  • 20
  • 34
  • thanks a lot, the approach you described works as expected, also for packages npm linked and run without invoking 'npm run' explicitly. I own you a beer :) – T. Jastrzębski Sep 24 '19 at 19:22