Skip to content

Node.js shebang line and NODE_OPTIONS #109

Closed

Description

@megastef

Hi,

  1. I wonder if there is a better way to pass NODE_OPTIONS to node cli. It turned out we need in production custom memory settings or good defaults (lowering resource usage).

So I find myself in writing long shebang lines for node.js scripts, e.g.
https://github.com/sematext/logagent-js/blob/master/bin/logagent.js#L1-L5

#!/bin/sh
':' //; export MAX_MEM="--max-old-space-size=100"; exec "$(command -v node || command -v nodejs)" "${NODE_OPTIONS:-$MAX_MEM}" "$0" "$@" 

Is there something like .noderc, or interpretation of an environment variable like NODE_OPTIONS by the node executable to pass runtime options?

  1. Some people reported that options are given by option mames with underscore e.g. --max_old_space_size=100 (Maybe on CentOS ...). How could I find out which naming scheme (dash vs. underscore) is used?
  2. I ignore windows .. for now :)

Activity

  1. megastef commented on Mar 31, 2016

    @megastef
    Author

    Should i open an issue in node/node repository?

  2. MylesBorins commented on Mar 31, 2016

    @MylesBorins

    hey @megastef I help maintain canary in the gold mine, a cli + library for testing node packages. You might find some of the patterns we use in there useful

    https://github.com/nodejs/citgm/

    I'm not 100% I'm following what you shebang logic is doing, but I usually start a bin with #!/usr/bin/env node as you can see here https://github.com/nodejs/citgm/blob/master/bin/citgm#L1

    If you want to include arguments to node you can just append them on that line

    in your case

    #!/usr/bin/env node --max_old_space_size=100
    console.log('sup 100');

    This was the correct place to ask the question, thanks for your patience!

  3. megastef commented on Mar 31, 2016

    @megastef
    Author

    I want to give the user full control on node Options - /bin/env node might fail on ubuntu, the binary might be named 'nodejs'. My shebang line tries to catch this case. The second problem is that options might have underscore or dash (i assume this is a compile time config e.g on CentOS). Well, this migh be a fight with legacy node versions. Thx.

  4. martinheidegger commented on Mar 31, 2016

    @martinheidegger

    To answer let me explore the functionality of the shebang a little: The shebang is a reference to the application that launches the current script file. #!/bin/bash refers to a bash application. Interestingly - unlike bash - the node binary is not at the same place in every system. #!/usr/bin/env on the other hand is a binary on the same place and it knows how to start a local command so #!/usr/bin/env node passes in the argument node to env and env is so cool to start this for us.

    Recap: #!<command> <args> is the signature of a shebang

    It would be easy if you could just pass in the arguments like #!/usr/bin/env node $@ but a test.sh with this content: #!echo $@ will print $@ test.sh That means: the shebang can not take arguments from the command line

    The only option to start node with dynamic arguments is to start it in a child process. Now: We could make this complicated and write it in a separate file or we could do something like this:

    #!/bin/bash
    
    content () {
    cat <<JavaScript
    
      console.log("hi")
    
    JavaScript
    }
    
    content | /usr/bin/env node $@

    This way all the parameters are passed in to the node sub process. If you add some parameter check's to the bash script you could even decide which node parameters are okay to pass-in and which are not.

    If you can tell env to use an alias of node instead of node, then you are all setup already! Unfortunately I have not yet figured out how. more here

  5. megastef commented on Mar 31, 2016

    @megastef
    Author

    Hi @martinheidegger, long time not seen :)
    My shebang line works fine. Setting memory default, detecting node binary name, and taking custom NODE_OPTIONS.

    #!/bin/sh
    ':' //; export MAX_MEM="--max-old-space-size=100"; exec "$(command -v node || command -v nodejs)" "${NODE_OPTIONS:-$MAX_MEM}" "$0" "$@" 
    

    Actually I had the hope that the Node.js binary could take options from an (undocumented?) environment variable or resource file. But it looks we have to live with shell tricks to inject this parameters.

    I think it would be a good feature for node to respect e.g. NODE_OPTIONS environment variable.

  6. martinheidegger commented on Mar 31, 2016

    @martinheidegger

    A test.sh script with the shebang

    #!echo $FOO

    would result in $FOO test.sh when called using env FOO=bar. As such I assume that you can't simply pass in environment variables as NODE_OPTIONS would not do much help in the shebang.

    I also think that it might be a bad idea to have this option in a file since the properties would apply to any node process running. I kind-of still think that the current way to do it seems right.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions