Author: Liu Guanyu, senior front-end engineer and technical manager of 360 Qi Dance Company, member of W3C CSS working group.

Creation silent but sentient beings, each in the cold do feel spring. Thousands of red and purple arrangements, only to wait for the first sound of new thunder. — Qing Zhang Weiping, New Thunder

origin

Many programs rooted in the Unix environment pursue the philosophy of Unix system design. Douglas McIlroy, inventor of the Unix plumbing mechanism, summed up the Unix philosophy in three points:

  1. Focus on one thing and do it really well.
  2. Programs work together.
  3. For general purpose interfaces, such as text data streams.

As Unix/Linux becomes more powerful on servers and cross-platform solutions evolve, this philosophy is being carried across platforms as well. When I first encountered NodeJS and its package management solution, NPM, a few years ago, I felt that its officially promoted style was a perfect fit with the Unix system philosophy. In recent years, with the continuous development of NodeJS in the field of server and front-end construction, the idea of NodeJS is rapidly penetrating into these fields.

In fact, NodeJS itself is an important tool for developing command-line programs. This article will cover several common NodeJs-related command-line programs, then some common components for developing the command line, and finally how to publish NPM packages and packages with scope.

How does the command line work

The command line is simply defined as a user interface and interaction mode based on text flow. Command-line programs often run in different ways by passing command-line arguments. And because all the commands are based on text, it also facilitates metaprogramming.

Command line programs can be compiled or interpreted. For compiled command line programs, they are executed directly in machine code. For most interpretive command line programs, command line interpreter is often needed to run.

The command line program mentioned in this article specifically refers to a command line program that requires an interpreter.

The ones that can act as command-line interpreters actually include the most common interpreters you’ve heard of, such as bash, ZSH, Perl, Python, Ruby, TCL, and of course NodeJS.

To open a command line program, it is standard to write the interpreter’s path in the first line, as in:

#! / usr/local/opt/python/bin/python3.6
Copy the code

Here #! Become shebang, usually at the beginning of the file. On Unix systems, #! The following part of the line is treated as an interpreter instruction. The path to the file is appended to the interpreter as a parameter. In case, if the file is/usr/local/bin/PIP, directly run/usr/local/bin/PIP effect, is equivalent to/usr/local/opt/python/bin/python3.6 / usr/local/bin/PIP.

This allows the user to run the corresponding command-line program without worrying about the interpreter or the language in which the code is written. That’s why Shebang exists. However, due to the system Settings, the use of Windows students may not enjoy this convenience, generally also need to manually specify the path of the interpreter. However, they can be double-clicked to run :-).

Try opening a NodeJS script such as Webpack with a text editing tool and see that the first line is #! The/usr/bin/env node. This sentence is not a direct NodeJS parser. Here, /usr/bin/env is a program that looks for the address of the named interpreter from the system’s PATH. At this point, the interpreter can be installed in a variety of paths, as long as the system PATH registered, can be found.

You may have encountered an error when running some NodeJS programs:

/usr/bin/env: node: No such file or directory

In this case, you can check whether the node file PATH exists in the system PATH and whether some versions of NodeJS are named node.

NodeJS related: A handy command-line tool

While NodeJS has become the main language of front-end workflow, Babel and Webpack have basically become important tools for front-end development, testing and publishing. There are also a number of toolkits and plug-ins around Babel and WebPack to assist developers in all aspects of daily development.

Meanwhile, the most popular front-end frameworks Angular, React, and Vue (in alphabetical order) come with their own scaffolding and development AIDS. Such as ng-CLI, create-react-app, vue-cli, and so on. There are also scaffolding tools like Poi that combine React and Vue.

Each of these sections can be explained separately. Interested readers can refer to the tools’ official website for more information.

Here are a few other nodeJs-related packages.

Multiple versions coexist with N/NVM

In most cases, we only have to deal with a single NodeJS version. When the time is right, upgrade to a higher NodeJS version.

However, I have come across a project that has fallen into disrepair and needs to be re-maintained. At this point, the NodeJS version needs to be cut to the older version. At the same time, we don’t want to abandon the new version of NodeJS environment that most projects run on.

In this case either N or NVM can be used. The following figure shows the process of downloading and switching to a new version with n.

In addition to downloading, n also provides a list way to switch between versions and a way to delete a version. The reader can use n-H to view all available parameters after installation.

N Write using bash. But it provides an entry point for NPM repository installation. You can use the traditional NPM installation method for global installation, as long as you have a running NodeJS environment.

npm install -g n

Or if NodeJS is not available, the n-install script can be used. Install just run: curl -l https://git.io/n-install | bash.

If you are a Windows user, you can install WSL under Windows 10 to obtain the Linux script runtime environment, an official repository of issues, there is a manual for this.

For users under windows10, consider playing around with Cygwin.

In addition to n, another management tool is NVM, also written in bash scripts. Installation can also be done using installation scripts. Such as: The curl – o – https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash or wget — qO https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash. V0.34.0 here is the release number, which may change with release iterations.

Windows readers, in addition to WSL and Cygwin mentioned above, may consider using nVM-Windows, a version written in Golang.

As of today’s latest releases, both n and NVM try to deal with common dependency libraries, but in different ways.

Both N and NVM will download the NodeJS version to the local directory when they use it for the first time. The difference is that N will try to replace the packages in the system path such as bin, lib, include, and share with the new version. NVM keeps a copy of each version and points the NodeJS system path to the sandbox address maintained by.nVM.

In terms of processing, NVM is lighter and more efficient, but you need to change the system’s PATH, which the NVM script does automatically. N In this case, you do not need to invade the system path. However, each change requires the operating system path. In this case, you are advised to run sudo N to avoid refusing to copy data to the system path due to insufficient permissions.

Because NVM changes the PATH address, if both NVM and N are installed by default, n will not work properly. One solution is to avoid simultaneous installation. Alternatively, you can manually change the PATH to make the default NodeJS PATH prior to the NVM system PATH. For example, change the PATH segment to:

/ usr/local/bin: / Users/Leon /. NVM/versions/node/v10.6.0 / bin:

Run the auxiliary Nodemon/NPX

Nodemon is an executor, meaning that if the version changes or the program changes, there is no need to restart. This is very useful in development.

Nodemon can also specify the port to run on, for example:

nodemon ./server.js localhost 8080

In addition to controlling the NodeJS package, Nodemon can also control non-NodeJS scripts. For example, nodemon –exec “python -v”./app.py will monitor the contents of app.py and call python -v for parsing at the beginning and when changes are made. Of course, if your app.py specifies shebang, you don’t need to specify the parsing function.

Nodemon has many flexible configurations. Through these configurations, you can set environment variables, delay startup, execute commands, monitor custom extensions, gracefully restart, and monitor events. You can provide the nodemon.json configuration in the directory where these configurations are required, or specify it in the package.json field by using the nodemonConfig field.

Here is a sample configuration file provided by the government for your reference.

Let’s talk about NPX. What is NPX? Simply put, you find a package, run it, and “run it out.”

There are two meanings here:

  1. To find it. Where to find: First the current dependency, then the PATH, can not find it to find online to install.
  2. Run out. Even if it is installed from the Internet, it will be deleted after running, leaving no running package. Readers can try running:npx github:piuccio/cowsay "awesome npx"Under the experience.

This is really home travel, development and debugging tool. For example, if I want to open an HTTP service in the current directory, I can directly run: NPX http-server

This address can then be accessed directly from the browser for debugging.

Alternatively, if you need to temporarily run a script with an older version of Node, you can also sacrifice NPX, which will be temporarily installed, temporarily used, and ready to go.

npx -p node@6 npm init

Switch the NodeJS registry NRM/YRM

NRM/YRM maintains a list of NPM masters and other mirrors. NRM/yRM use can be used to switch quickly for the fastest download speed. The NRM maintains the NPM registry, and the YRM maintains the YARN registry.

Assist in writing NodeJS packages

In addition to directly using the commands written by the gods, we can also customize the NodeJS package to our own needs. As we know, the command line is also a kind of human-computer interaction, so there are many effects that can be learned from the interaction. The author can use these interactions simply by pouring the package. Here the author recommends a few packages to everyone

The command line argument reads commander

A feature of the command line is to adjust the running policy according to different parameters. However, processing command line input and validation can be tedious. To this end, TJ created the Commander package. The most basic usage is as follows:


var program = require('commander');

program
  .version('0.1.0 from')
  .option('-p, --peppers'.'Add peppers')
  .option('-P, --pineapple'.'Add pineapple')
  .option('-b, --bbq-sauce'.'Add bbq sauce')
  .option('-c, --cheese [type]'.'Add the specified type of cheese [marble]'.'marble')
  .parse(process.argv);

console.log('you ordered a pizza with:');
if (program.peppers) console.log(' - peppers');
if (program.pineapple) console.log(' - pineapple');
if (program.bbqSauce) console.log(' - bbq');
console.log(' - %s cheese', program.cheese);

Copy the code

By default, Commander automatically creates a -h help file, which uses the input of each option to generate a help copy.

Each input from the user is placed in the hump form of the field corresponding to the long name of program option, or in the short name field if no long name is provided. In the preceding example, the testcommander -p 111-p 222-b 333 is stored on the peppers, pineapple, and bbqSauce of program.

Commander also provides multiple validation methods, such as regular expressions:

program.option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')

Specifies that only specific values can be entered.

At the same time, Commander provides a scheme that allows the user to set subcommands. Commander is called a Git-style subcommand.


var program = require('commander');

program
  .version('0.1.0 from')
  .command('install [name]'.'install one or more packages')
  .command('search [query]'.'search with optional query')
  .command('list'.'list packages installed', {isDefault: true})
  .parse(process.argv);

Copy the code

In this example, assuming the command line name is PM, when the user types pm-install, pm-search, or pm-list, commander will try to find install, search, or list at the same level of the entry file and give it to execute.

The progress bar progress

When writing web programs, people often display a progress bar. It can relieve users’ anxiety when they are waiting. In fact, this kind of interaction also occurs in command line programs. Wget, for example, gives you progress hints during the download process.

This effect can also be used in NodeJS. This is the Progress package. In the following code, the result is to download the CentOS installation disk. During the download, progress is printed in real time

const ProgressBar = require("progress")
const request = require("request")
const progress = require("request-progress")
const fs = require("fs")

const download = (url, headers, target, totalSize) = > {
    let percent = 0

    const bar = new ProgressBar('Download Middle: ├: Bar ┤ Completed: Percent estimated Completed Time: ETA Seconds Time: Elapseds', {
        total: 100.complete: "█".incomplete: "─".width: 60
    })

    let opt = {
        headers,
        url: url
    }

    return new Promise((resolve, reject) = > {
        progress(request.get(opt))
            .on('progress'.function (state) {
                let progressFix = ((state.percent) * 100).toFixed(2)
                delta = progressFix - percent
                bar.tick(delta)
                percent = progressFix
            })
            .on("error", () = > {return reject()
            })
            .on('end',  () => {
                bar.tick(100 - percent)
                console.log('\n')
                returnresolve(target) }) .pipe(fs.createWriteStream(target)); })}const foo = {
    getHeaders: (a)= > {
        const headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml; Q = 0.9 * / *; Q = 0.8 '.'Accept-Charset': 'UTF-8,*; Q = 0.5 '.'Accept-Encoding': 'gzip,deflate,sdch'.'Accept-Language': 'en-US,en; Q = 0.8 '.'User-Agent': 'the Mozilla / 5.0 (X11; Linux x86_64; The rv: 13.0) Gecko / 20100101 Firefox 13.0 / '
        }

        return Object.assign({}, headers)
    },

    download: function (url, target, totalSize){
        let headers = this.getHeaders()
        headers = Object.assign(headers)

        download(url, headers, target, totalSize)
    }
}


foo.download("http://mirrors.cmich.edu/centos/7.6.1810/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso"."CentOS-7-x86_64-DVD-1810.iso".4508876.8
    )

Copy the code

The result is shown in the following figure:

The core of this package is to print characters on the command line based on built-in and custom tokens for interaction.

Interactive coloring chalk

Chalk is a command line interactive coloring tool. A maximum of 16 bit gamut can be supported if the command line supports it (provided the command line terminal supports it). Generally, it can be used with console.log, for example:

const chalk = require('chalk');
const log = console.log;

// Combine styled and normal strings
log(chalk.blue('Hello') + ' World' + chalk.red('! '));
Copy the code

I once made a program to display images on the command line using chalk and console.log.

Interactive q&A with inquirer

Inquirer is a great tool to use in situations where you need to constantly interact with your users, validate and select paths based on their input. It has built-in single choice, multiple choice, question and answer and other interactive ways. You can feel it:

Suggest can even be implemented through plug-ins

Vue-cli, the scaffolding for the VUE framework, is a good example of inquire, which allows readers to read the source code and get a feel for the divine use of inquire.

Small icon ora

Ora prints out an elegant little text icon that is used to give users elegant and clear hints in various situations. The usage is simple:

const ora = require('ora');

const spinner = ora('Loading unicorns').start();

setTimeout((a)= > {
	spinner.color = 'yellow';
	spinner.text = 'Loading rainbows';
}, 1000);
Copy the code

Command line play with the browser puppeteer

Puppeteer is a headless browser developed by Google that enables command line manipulation of the browser and further manipulation based on the browser’s execution results. The developers of PhantomJS, a similar project, decided not to update Puppeteer because of its official origins.

Puppeteer is already widely used for front-end testing, end-to-end testing, and crawlers.

Since there is no space for an introduction, readers can refer to its official documentation. Meanwhile, this article by Huang Xiaolu and this article by Li Guangzhao in Qiwu Weekly have introduced the use of Puppeteer.

Release NodeJS package

The written NodeJS package needs to be published before it can be used by everyone. NPM Publish was created for this requirement. In order to publish you need to register with NPM, log in, and then publish. The NPM details page and images are automatically updated over time.

If your NodeJS package is written using a syntax that is not yet widely supported. Add prepublish to the script field of package.json and call precompiler processing such as Babel to make the program more compatible.

For commands that you want users to use globally, be careful to write entry files in the root directory, typically in the bin field in package.json, specifying entry files. At installation time, NPM will use symbolic links to link these files to prefix/bin if it is a global installation or./node_modules/.bin/ if it is a local installation.

In addition to the usual package, there is a package with scope, vue-CLI version 3.0 starts with @vue. This scope is the name of the organization. Each package with scope can be public or private, and the private must be paid to NPM.

The current read and write permission policies of NPM are as follows:

If you are an individual, consider adding a public namespace. If you are an enterprise paying user, you need to apply to be a member of this scope before releasing relevant packages.

For public scopes, first change the package name to @scope name/package name, and use NPM publish –access public when publishing.

summary

This article briefly introduces the significance and advantages of the command line, introduces the operation mechanism of the explanatory command line, introduces several NodeJs-related command line tools, recommends several packages commonly used to write command line programs, and finally Outlines the release of the package and the use of scope. Hope to give you NodeJS command-line related development and technology selection, to provide some useful help.

About Weird Dance Weekly

Qiwu Weekly is a front-end technology community operated by qiwu Group, a professional front-end team of 360 Company. After paying attention to the public number, directly send the link to the background can contribute to us.