Skip to content

Use shebang if installing locally? #639

Closed

Description

@Taytay

I just discovered that shebang support wasn't working on my build machine because I have installed ts-node locally, and then was running the .ts file with a shebang like: #!/usr/bin/env ts-node as referenced in #73

That works if you have ts-node installed globally, or if you have it installed locally, and have ./node_modules/.bin on your path, but if you don't have node_modules/.bin on your path, it doesn't appear to work, and this makes sense. My current workaround would be to rely upon npx and use the shebang #!npx ts-node, since npx is installed with ts-node. I just wanted to make sure I'm not missing anything since #73 claims that the /usr/bin/env shebang should "just work".

Activity

  1. blakeembrey commented on Jul 13, 2018

    @blakeembrey
    Member

    You’re right, it definitely needs to be global and in your path (just like any other globally installed node.js module). I personally wouldn’t recommend it as a feature, but that issue asks if it’s possible and it certainly is - using npx or just running the script directly from ts-node would make it more resilient, possible to use local versions from package.json and better support cross platform.

  2. added
    questionSupport requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.
    on Jul 14, 2018
  3. samuela commented on Feb 3, 2019

    @samuela

    I also really need this!

  4. samuela commented on Feb 3, 2019

    @samuela

    Using #!npx ts-node doesn't work for me:

    -bash: ./yarn-run-all.ts: npx: bad interpreter: No such file or directory
    
  5. gabemeola commented on Apr 2, 2019

    @gabemeola

    @samuela Pointing to the env file worked for me

    #!/usr/bin/env npx ts-node
  6. b1zzu commented on Oct 7, 2019

    @b1zzu

    @samuela Pointing to the env file worked for me

    #!/usr/bin/env npx ts-node

    This is not working for me:

    /usr/bin/env: ‘npx ts-node’: No such file or directory
    /usr/bin/env: use -[v]S to pass options in shebang lines
    

    I've fixed it in this way:

    #!/usr/bin/env -S npx ts-node
    
  7. matheo commented on Oct 2, 2020

    @matheo

    Sadly npx ts-node didn't work on a colleage's MacOs out of the box
    so I compiled the typescript files to js but they doesn't detect the local dependencies with #!/usr/bin/env node

    I hope that #!/usr/bin/env npx works on Mac as it does on my Linux :)

  8. bradymholt commented on Jul 23, 2021

    @bradymholt

    I have been searching for a way to use a shebang with locally installed ts-node but also in a portable way, so that it works on macOS and Linux. Since you can't pass multiple args in a shebang on Linux, using !/usr/bin/env npx ts-node does not work.

    After messing around a bit, I came up with an ugly way to do this but it works and is a one-liner:

    #!/usr/bin/perl -e$_=$ARGV[0];exec("/usr/bin/env\x20npx\x20ts-node\x20-s\x20@ARGV")
    

    So, if you have a script called foo.ts that looks like this:

    #!/usr/bin/perl -e$_=$ARGV[0];exec("/usr/bin/env\x20npx\x20ts-node\x20-s\x20@ARGV")
    
    const foo: string = `Hello ts-node: ${process.argv.splice(2).join(", ")}`;
    console.log(foo);
    

    You can use it like this:

    chmod +x ./foo.ts;
    ./foo.ts --foo --boo
    > Hello ts-node: --foo, --boo
    

    Benefits:

    • Works on macOS and Linux
    • Will use local or globally installed ts-node or install it on the fly with npx if missing (no need to globally install ts-node)
    • Does not use a relative shebang path so cwd does not matter
  9. ThePlenkov commented on Nov 29, 2021

    @ThePlenkov

    #!/usr/bin/env ts-node-script works for me on Windows

  10. kyr0 commented on Dec 9, 2021

    @kyr0

    The way it actually works on all platforms is to use plain node/JS with a standard shebang for node (this executable is always globally available), run execSync from child_process, and do npm run start:ts -- in your package.json put a script called "start:ts" like that:

    {
        scripts: {
            "start:ts": "ts-node yourCommand.ts"
        }
    } 

    Point is, that npm will take care for the lookup then internally with node-resolve algo and this also works on any platform and of course also with npx -- which gives you headaches because npx would install in different directory stuctures because of caching

  11. cspotcode commented on Dec 10, 2021

    @cspotcode
    Collaborator

    #!/usr/bin/env ts-node-script works for me on Windows

    FYI ts-node does ts-node-script behavior by default now, so assuming you're running a recent version of ts-node, you can use ts-node in your shebangs.


    Globally-installed ts-node is smart enough to use locally-installed versions of typescript and @types/node, so generally you can install the most recent version of ts-node globally and then use ts-node in your shebangs. It will still respect your local typescript version and local tsconfig.

    Here is an example of a project configured to be installed and run via npx: https://github.com/cspotcode/code-workspace-launcher/ It might require a globally-installed ts-node, I'm not sure; I haven't tested that in a while.


    The way it actually works on all platforms is to use plain node/JS with a standard shebang for node (this executable is always globally available), run execSync from child_process, and do npm run start:ts -- in your package.json put a script called "start:ts" like that

    You can avoid the overhead of npm by spawning ts-node directly if you can get the path to ./node_modules/.bin/ts-node or ./node_modules/ts-node/dist/bin.js

    Even better, you can avoid the overhead of child_process by using our API.

    #!/usr/bin/env node
    require('ts-node').register({
      projectSearchDir: __dirname // tell ts-node where to find our local tsconfig.json and local typescript version
    });
    require('./my-bin-script.ts'); // now that ts-node has been installed, our code will compile
    

    https://typestrong.org/ts-node/api/index.html#register
    https://typestrong.org/ts-node/api/interfaces/RegisterOptions.html#projectSearchDir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionSupport requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions