kentcdodds / cross-env

πŸ”€ Cross platform setting of environment scripts

Home Page:https://www.npmjs.com/package/cross-env

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Variable assignement is not working when the assignment requires a command execution

bemipefe opened this issue Β· comments

  • cross-env version: 5.2.0
  • node version: 6.14.4
  • npm (or yarn) version: 3.10.10

Relevant code or config

"scripts": {
    "preinstall": "cross-env modarch=\"node -e console.log(process.arch)\" npm run install",
    "install": "cross-env-shell echo The variable content is $modarch",

What you did:
npm install

What happened:

The command printed the following output:
The variable content is node -e console.log(process.arch)

The expected output was:

The variable content is x64

or

The variable content is ia32

Problem description:

Instead of the command output the variable is filled with the command itself ("node -e console.log(process.arch)"). Removing the double-quotes gives syntax error.
The command runs just fine if a space character is put after "modarch=" but of course the result is never assigned to modarch.

Did you find a solution to this? I want to assign a commit hash to an environment variable in a build script also but cannot get this to work.

I tried doing cross-env PWD=$CWD so that I can use one variable to refer to the current directory but it does not work.

@bemipefe @buddythumbs After wasting a full day going down this rabbit hole I figured it out. The issue is that npm uses cmd on windows for it's default shell (even though it's deprecated!), and cmd doesn't support command substitution. Powershell does, so the trick is to set the npm script-shell to powershell. You can create an .npmrc in the project or use the global config.

#in .npmrc
script-shell = "C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"

#using the CLI
npm config set script-shell = "C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"

Then you can use command substitution.

//in package.json
{
  "scripts": {
    "start": "cross-env HASH=$(git show --no-patch --format=%h) node echo.js"
  }
}

// echo.js
console.log(process.env.HASH) 
C:\Users\me\my-project>npm start

> my-project@1.0.0 start C:\Users\me\my-project
> cross-env cross-env HASH=$(git show --no-patch --format=%h) node echo.js

0fbd4ad

πŸŽ‰ πŸ˜„

Now I have to figure out how to use a different .npmrc per platform so every developer doesn't have to create their own config file. πŸ˜•

commented

@parkerault
You're a lifesaver, changingscript-shell worked for me! I think setting script-shell = powershell is sufficient, but I could be wrong.

Is this a bug in npm then?

EDIT: Looks like changing the shell interferes with installations. For example npm install nodemon causes an error due to a double pipe operator.

@Rovyko Yeah, this feels like fighting the platform, which makes me think that once you need to do more than set static variables it's time to break out the javascript.

I agree. I recommend folks use cross-env for setting environment variables and calling into scripts. Keep it simple.

Using ; did it

"config":{
    env:{
        "debug"package:*" 
    }
},
"set:env": "cross-env-shell DEBUG=${npm_package_config_env_debug} ",
"set:env2":"npm run set:env ; echo 'DEBUG=${DEBUG}'",
                            ↑

@parkerault thanks, this is great!

For anyone having trouble with Powershell I'm using this JS solution: https://stackoverflow.com/a/55284054/2771889