Create a node script to replace a complex npm script

Elijah Manor
InstructorElijah Manor

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

In this lesson we will look at pulling out complex npm script logic into an external JavaScript file. Instead of writing bash scripts you can leverage your JavaScript abilities to automate your build process. We’ll use some helper node modules such as shelljs, opn-cli, and babel-cli.

Instructor: [00:00] Referencing an external JavaScript file in your npm scripts can be a good way to gain more control and flexibility in your scripts. It can help with better organization, too. Let's convert our three sets of npm scripts to JavaScript files, a TestScript, BuildScripts, and ServerScripts.

[00:17] From our terminal, we'll make a scripts folder. Then, we'll quickly create three JavaScript files, test, build, and server.js. Now, let's go back to our package JSON file and copy the TestScript. Then, we'll open up the test JS file that we just created.

[00:34] We'll go ahead and paste the results, and just comment it up for later. The first thing that we'll do is, we're going to import the exact function from a shell JS, which is a cross-platform implementation of Unix shell commands on top of node JS.

[00:52] Before we start using it, let's install that on the command line, as a dev dependency. Now, let's uncomment our code and we'll surround it with our exact function. If we wanted this script to be cross-platform in npm scripts, we could have used cross-env for the babel_env environment variable.

[01:14] However, since we're writing JavaScript in node, we've many more options. In our case, let's create a constant called isWindows. We'll take a look at the process platform and see if it equals Win32.

[01:28] Then, we'll create another variable called environment. If we're on Windows, then we'll use set babel_env to test. Then, we'll use the && which is the correct way to do that in Windows. Otherwise, we'll just say babel_env equals test.

[01:50] Now, we can use string templates to say environments and run our mocha command. Now, we'll go back to our package JSON file and we'll update our TestScript. Since we're using the import statement in our test JS file to acquire our dependencies, we'll need to use babel-node to auto-compile and run our code.

[02:11] I've already set up a babelrc file that we'll need when running babel-node. All we need to do here is to say babel-node and run our scripts test file. However, in order to use babel-node, we'll need to install babel-cli. We'll install that as dev dependency.

[02:35] If we run our tests, it will run all our linting and our tasks. Next, we'll convert our BuildScript. Let's copy our prebuild, our build:html, build:css, and build:JavaScript.

[02:51] Then, we'll open our build JS file. We'll paste in the results, commented out for now. Like we did before, we'll import the exact function from a shell JS. Then, we'll need to determine the version of our application.

[03:06] We can grab that from process.env.npm_package_version. Another we've a version, we could uncomment our code and do a little clean up. We'll call our exact function. Then wherever we have npm_package_version, we could use string templates and just say version.

[03:39] Since we're trying to make our scripts cross-platform, instead of executing RMRF to delete our version folder, let's go up to shell JS and pull up the RM function as well. Then, we'll come over here and instead of saying exact, we'll say remove.

[03:54] In the first parameter I'll remove are the flag, so we'll say recursively force delete, and we'll tell at the path. Now, let's go to our package JSON file and we could safely delete our prebuild, build:html, build:css, and build:js scripts.

[04:12] We'll update our BuildScript to be babel-node scripts/build JS. Then, we come to our current node and run npm, run build, and we'll remove our version folder and build our assets.

[04:28] Now, let's convert our ServerScripts. We'll grab server:create and server:launch. We'll copy that and open up our server.js. We'll paste the results, comment them out.

[04:39] Just like before, we'll import exe from shell JS. We're going to destructure some things from process.env. We're going to ink out the npm_package_version and map that to version. Then, we're going to pull out package_config_port and map that to port.

[05:04] Then, we'll uncomment our scripts, add our execute function, and we can use string templates to inject our version, and anywhere there is npm_package_config_port, we can replace that with port.

[05:32] For HTTP server, we'll need to provide a second argument to signify that this is an async operation. In the spirit of cross-platform friendliness, instead of using the open command, we'll use the opn node module. Let's install that npm i opn-cli as dev dependency.

[05:55] Now, let's go back to our package JSON. We could delete the server:create and server:launch, and we could simply replace our ServerScript with babel-node scripts server.js.

[06:09] Now if we come to our terminal, we could say npm run server. We'll kick up a HTTP server and it'll open our browser, and sure enough it did. There is one last thing we need to do before you try these new scripts add-on Windows.

[06:23] Since having single quotes inside of npm scripts does not work on Windows, we'll need to replace them with double quotes. Since we're already using double quotes around our scripts, we'll go ahead and escape them.

[06:34] Now, we'll save our changes and run these scripts on Windows. Now that we're in the command prompt on Windows, we could npm run our tasks, and it'll run our linting in our tests. We can npm run build and that will remove our version folder and regenerate our assets.

[06:55] Then, we could run npm run server and it'll kick up an HTTP server and launch the browser without website, and sure enough it worked.

~ 4 years ago

Nice series! I really like the videos about cross system compatibility. So far I have never thought about that. I also like the extraction into js-scripts. I personally prefer making executable node.js scripts. That way I can skip transpiling the scripts to es2015 and babel-cli as another dependency.