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

run npm script with cross-env and && not working properly

LironEr opened this issue · comments

  • cross-env version: 5.1.4
  • node version: 8.9.0
  • npm version: 5.7.1
  • macos version: 10.13.4

part of my package.json:

  "scripts": {
    "greet": "cross-env FOR_TESTING=Hi && ./test.sh",
    "greet2": "cross-env FOR_TESTING=Hi  ./test.sh",
  },

test.sh:
echo "value: $FOR_TESTING"

Command Output
npm run greet value:
npm run greet2 value: Hi

Why with && the variable FOR_TESTING not working?

Thanks (:

You have to use cross-env-shell like explained in the readme to have the env var in all commands.

Though I believe there is still a bug related to this:

  "scripts": {
    "test": "cross-env NODE_ENV=test npm run test:lint && npm run test:test",
    "test:lint": "cross-env-shell \"echo $NODE_ENV\"",
    "test:test": "cross-env-shell \"echo $NODE_ENV\""
  },

outputs:

C:\Projects\app>npm test

> @b/app@0.0.1 test C:\Projects\app
> cross-env NODE_ENV=test npm run test:lint && npm run test:test


> @b/app@0.0.1 test:lint C:\Projects\app
> cross-env-shell "echo $NODE_ENV"

test

> @b/app@0.0.1 test:test C:\Projects\app
> cross-env-shell "echo $NODE_ENV"

ECHO is on.

So the combination with && (where the solution is to use the shell) and child scripts (where the solution is cross-env and cross-env-shell in child) is not working.

While trying different things, managed to get this working:

  "scripts": {
    "test": "cross-env-shell NODE_ENV=test \"npm run test:lint && npm run test:test\"",
    "test:lint": "cross-env-shell \"echo $NODE_ENV\"",
    "test:test": "cross-env-shell \"echo $NODE_ENV\""
  },

I think more examples and better explaining of the usage with && and child-scripts is needed, as I believe this is a common practice...

Thank u 👍

I'm having trouble running cd foo && npm run build. The cd command mustn't be working as I'm getting npm ERR! missing script: build.

@dietergeerts I use the variable except NODE_ENV that doesnt work. I use process.env.NODE_ENV, it works.

@Crazometer you're changing directories, are you sure there's a package.json file under the foo directory with a build command? Pretty sure that's what npm is complaining about.

@Faultless yup! The project has a base folder with a package.json and then a sub folder with another. The same command works if run from the console in the base folder 😕 .

I'm also not able to change folders to update the version of another package.json. It keeps updating the version of the package.json in the base folder. Is there any other way to communicate with the other package.json without changing folders?

Check out the --prefix option.

From my example above cd foo && npm run build becomes npm run build --prefix foo.

If anyone would ever run in the same issue I had, hope this sometime saves someone a lot of headache.

If you were to pass a variable to your initial script with cross-env, this variable will not automagically appear on the child command.

Here's what I was trying

  "scripts": {
    "child": "cross-env-shell webpack --config ./config/webpack.config.js",
    "parent": "cross-env env.VARIABLE=myvar yarn child"
  },

I somehow expected all the variables passed to cross-env would be passed into its child scripts, and was thus expecting my child script to come down to webpack --config ./config/webpack.config.js --env.VARIABLE=myvar, which was incorrect.

Instead, I had to pass the variable to the child script, like this

  "scripts": {
    "child": "cross-env-shell webpack --config ./config/webpack.config.js --env.VARIABLE=$VARIABLE",
    "parent": "cross-env VARIABLE=myvar yarn child"
  },

So this appears to work, and makes your scripts extensible. E.g.

  "scripts": {
    "child": "cross-env-shell webpack --config ./config/webpack.config.js --env.VARIABLE=$VARIABLE",
    "parent": "cross-env VARIABLE=myvar yarn child",
    "parent2": "cross-env VARIABLE=myothervar yarn child"
  },

And running yarn parent2 will now pass myothervar to webpack.

Another bonus I noticed: if you were to have even deeper levels of scripts, you don't need to recursively pass in the parameters. This works:

  "scripts": {
    "grandchild": "cross-env-shell webpack --config ./config/webpack.config.js --env.VARIABLE=$VARIABLE",
    "child": "yarn firstscript && yarn secondscript && yarn grandchild",
    "parent": "cross-env VARIABLE=myvar yarn child"
  },

As you can see, I don't need to pass VARIABLE to the child script, as grandchild picks this up via cross-env-shell. This also prevents me from having to wrap my calls in the \" wrapper, because grandchild is only 1 script.

If wanted, I can always shoot a PR to document this behaviour, as I think this is something that is widely used.

Sorry for not responding to this earlier. It's been long enough that I'm going to close this issue. If you're still experiencing problems, please open a new issue.

@kentcdodds @JDansercoer updating the docs about this would make a lot of sense!