Make npm scripts cross-environment friendly

Elijah Manor
InstructorElijah Manor
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 5 years ago

Unfortunately not all shell commands work across various environments. Two main techniques to support cross-environment scripts is to either use cross-platform commands or to use normalized node packages. In this lesson, we will look at updating an existing set of npm scripts and make sure they work on Mac OS X, Linux, and Windows.

[00:01] If you need your MPM scripts to work on Mac, Linux and Windows then there are several things you'll need to consider. If we run MPM start on a Windows machine things won't work out so well. Some of the code will run but the output isn't quite what we expected. It can't finish all the necessary scripts.

[00:19] You'll notice here that it aired out. If we look at out get status, it wasn't able to determine the version that we wanted. Let's go through our scripts and make them cross environment friendly. Our start script looks lined, as does post start and pretest, however, our test script needs a little attention.

[00:38] Setting bubble_nv to a test environment like this only works on Mac and Linux. To get this to work on Windows, we need to say set bubble nv test, and then without a space we need to say double [inaudible] to split the two statements.

[00:53] Now this will work on Windows, however it's kind of brittle because it won't work in both environments. We'd like something to work both on Mac, Linux and Windows at the same time. Let's put our code back the way it was. Thankfully there's a node package we could use, called cross ENV. We'll save it as a devDependency.

[01:13] This will solve all the scenarios that we want. Let's go back to our code. All we have to do here is just say cross ENV. It's smart enough to figure out how to set this environment variable for each environment that we're running it in.

[01:26] If we look at our cover script it's perfectly fine, but we'll need to update our post cover script. Mac and Linux understand the rm command through move files, but some versions of Windows do not. Thankfully there's a node package called rimraf that will allow you to delete across different platforms.

[01:44] We'll install that as a devDependency, and then we'll come back to our script, and all we need to do is say rimraf and it will delete our NYC output file in a way that will work on Windows, Linux and the Mac. There's also a problem with our cover open script.

[02:03] The open command that we're using is very specific to the Mac and Linux, but thankfully there's another node package that we could use to solve this problem. There's one called opn-coi, we'll save that as a devDependency.

[02:15] Now, we're going to come back to our scripts, all we have to do is replace open with opn. If we look at our length scripts it looks fine, as well as our length JS. However we have a problem with our length CSA script.

[02:31] Mac and Linux are just fine with single quotes but unfortunately that won't work very well on Windows. Instead of a single quote, we'll need a double quote instead, but the problem with double quotes is since we're already using double quotes to surround our script, we'll need to escape them.

[02:46] We'll come over here, make an escaped quote, and that should fix our problem. We also need to update our watch length script to fix the same thing. We'll remove the single quotes with a double quote and we'll escape them.

[03:02] If we go down a little further we'll notice that the pre-bill uses rm -rf, so we can replace that with rimraf. However, we have another problem here as well. We're using a dollar sign to reference an environment variable that is very specific to Mac and Linux.

[03:20] The way you do this on Windows is to use the percent sign instead. You have to put it before and after the variable. We could update our script like this, but then it would only work on Windows. Instead we'd rather have a way that would work on all platforms.

[03:34] Let's revert the code back to the way it was before, and then we're going to install another package called crossver an install it as a devDependency. Now we'll go update our script, and all we have to do is prepend crossver to our script.

[03:50] It will go through our script, replacing any variables it sees with the appropriate variable for the environment that it's on. We can make the same change to the billed HTML scripts, since it's also using environment variables.

[04:01] We'll say crossver. You might be tempted to add crossver on your billed csa script as well. However there's a problem. Just prepending cross bar won't work in cases where a variable is part of a pipe or an output redirection.

[04:17] You'll notice here that we are piping to post css and then we're also piping to cssmin. We're also redirecting to our public folder. It's in our public folder where we actually want to reference the variable name.

[04:30] Thankfully there's a workaround through this. All we have to do is to pass crossver one big string so that it could replace all the variables, and then run it as one big command. We'll also need to do the same thing for our bill JS script.

[04:45] We'll say crossver and then we'll pass one big string for it to manipulate for us. The server script is just fine but the server create script will need crossver since it's using an environment variable as well as our server launch.

[05:04] Instead of open we'll use opn. At this point we should be all done converting our script so that it can work on Mac, Windows and Linux. Let's go test it. Now we're in our Windows environment and we're going to install the new dependencies that we just added.

[05:20] Now we should be able to say MPM start to kick off our process. It should run our node script to gather all the file size information for react. Then it will build our HTML asset, our css asset, and our JavaScript asset. It will kick off the server and open up our website in a new browser. Now, our MPM scripts will run in multiple platforms.

~ 5 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today