Open rogerxu opened 7 years ago
process.exit
process.on('exit', function () {
});
process.exit();
process.exit(1);
You need to send the command a SIGTERM
singal, and handle that with the process signal hander.
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('hi');
});
const server = app.listen(30000, () => console.log('Server ready'));
process.on('SIGTERM', () => {
server.close(() => {
console.log('Process terminated');
});
});
SIGTERM
is the signals that tells a process to gracefully terminate. It is the signal that's sent from process managers like upstart
or supervisord
and many others.
You can send this signal from inside the program, in another function:
process.kill(process.pid, 'SIGTERM');
The process
core module of Node provides the env
property which hosts all the environment variables that were set at the moment the process was started.
process.env.NODE_ENV // 'production'
node app.js name=roger
process.argv
- Array
The first argument is the full path of the node
command.
The second element is the full path of the file being executed.
All the additional argumetns are present from the third position going forward.
const args = process.argv.slice(2);
args[0] // name=roger
The best way to parse it is by using the minimist
package.
const minimist = require('minimist');
const args = minimist(process.argv.slice(2));
args['name'] // roger
console.log()
console.log('My %s has %d years', 'cat', 2);
console.count()
console.count(msg);
const foo = () => console.trace();
const bar = () => foo();
bar();
const doSomething = () => console.log('test');
const measure = () => {
console.time('doSomething');
doSomething();
console.timeEnd('doSomething');
};
measure();
process.stdout
process.stdout.write('hello world');
process.stdin
process.stdin.on('data', function (data) {
console.log(data.toString().trim());
});
You can color the output of your text in the console by using escape sequences.
console.log('\x1b[33m%s\x1b[0m', 'hi!');
chalk
package
const chalk = require('chalk');
console.log(chalk.yellow('hi!'));
progress
package
const ProgressBar = require('progress');
const bar = new ProgressBar(':bar', {
total: 10,
});
const timer = setInterval(() => {
bar.tick();
if (bar.complete) {
clearInterval(timer);
}
}, 100);
Node readline
module.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('What is your name?', (name) => {
console.log(`Hi ${name}!`);
rl.close();
});
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('What is your name? ', (answer) => {
person.name = answer;
rl.setPrompt(`What would ${person.name} say? `);
rl.prompt(); // write a new line
rl.on('line', (saying) => {
person.sayings.push(saying.trim());
if (saying.toLowerCase().trim() === 'exit') {
rl.close();
} else {
rl.setPrompt(`What else would ${person.name} say? ('exit' to leave) `);
rl.prompt();
}
});
});
rl.on('close', () => {
process.exit();
});
inquirer
package
cosnt inquirer = require('inquirer');
const questions = [{
type: 'input',
name: 'name',
message: 'What is your name?',
}];
inquirer.prompt(questions).then(answers => {
console.log(`Hi ${answers['name']}!`);
});
global
objectglobal
- The global namespace object.__dirname
- The directory name of the current module.__filename
- The file name of the current module.const path = require('path');
path.basename(__filename); // abc.js
setTimeout
clearTimeout
setInterval
clearInterval
function writeWaitingPercent(percent) {
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(`waiting ... ${percent}%`);
}
var interval = setInterval(function () {
currentTime += waitInterval;
percentWaited = Math.floor((currentTime / waitTime) * 100);
writeWaitingPercent(percentWaited);
}, waitInterval);
setTimeout(function () {
clearInterval(interval);
writeWaitingPercent(100);
console.log('\n\ndone');
}, waitTime);
const exec = require('child_process').exec;
exec('git version', function(err, stdout) {
if (err) {
throw err;
}
console.log('Git Version Executed');
console.log(stdout);
});
const spawn = require('child_process').spawn;
const cp = spawn('node', ['--version']);
cp.stdout.on('data', function (data) {
console.log(`STDOUT: ${data.toString()}`);
});
cp.on('close', function () {
console.log('Child process has ended');
process.exit();
});
var dirUploads = path.join(__dirname, 'www', 'files', 'uploads');
v8.getHeapStatistics()
const EventEmitter = require('events').EventEmitter;
const emitter = new EventEmitter();
emitter.on('customEvent', function (message, status) {
console.log(`${status}: ${message}`);
});
emitter.emit('customEvent', 'Hello World', 200);
fs.readFile('./files.js', 'UTF-8', function (err, contents) {
if (err) {
throw err;
}
console.log(contents);
});
fs.readFile('sample.md', `# Sample Title`, function (err) {
if (err) {
throw err;
}
console.log('File Created');
});
fs.unlink('sample.md', function (err) {
if (err) {
throw err;
}
console.log('File removed');
});
fs-extra
const fs = require('fs-extra');
(async () => {
const exists = await fs.pathExists(file);
await fs.ensureFile(file);
await fs.ensureDir(path);
})();
var files = fs.readdir('./lib', function (err, files) {
if (err) {
throw err;
}
console.log(files);
});
fs.mkdir('temp');
fs.rmdir('temp');
const stream = fs.createReadStream('temp.log', 'UTF-8');
let data = '';
stream.once('data', function () {
console.log('Started reading file');
});
stream.on('data', function (chunk) {
process.stdout.write(`chunk: ${chunk.length} | `);
data += chunk;
});
stream.on('end', function () {
console.log(`Finished reading file ${data.length}`);
});
const stream = fs.createWriteStream('temp.log');
stream.write((new Date()).toString());
stream.close();
fs
functions?4 + 1 ways for making HTTP requests with Node.js: async/await edition
const options = {
hostname: 'en.wikipedia.org',
port: 443,
path: '/wiki/Git',
method: 'GET',
};
const req = https.request(options, function (res) {
let responseBody = '';
console.log('Response from server started');
console.log(`Server Status: ${res.statusCode}`);
console.log('Response Headers: %j', res.headers);
res.setEncoding('UTF-8');
res.on('data', function (chunk) {
console.log(`--chunk-- ${chunk.length}`);
responseBody += chunk;
});
res.on('end', function () {
fs.writeFile('Git.html', responseBody, function (err) {
if (err) {
throw err;
}
console.log('File downloaded');
});
});
});
req.on('error', function (err) {
console.log(`problem with request: ${err.message}`);
});
req.end();
node-fetch
const fetch = require('fetch');
const fs = require('fs-extra');
(async () => {
const url = 'https://en.wikipedia.org/wiki/Git';
const res = await fetch(url);
const dest = fs.createWritesStream(file);
res.body.pipe(dest);
})();
const server = http.createServer(function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/html',
});
res.end(`
<!DOCTYPE html>
<html>
<head>
<title>HTML Response</title>
</head>
<body>
<p>${req.url}</p>
<p>${req.method}</p>
</body>
</html>
`);
});
server.listen(8080);
console.log('Server listening on port 8080');
http.createServer(function (req, res) {
console.log(`${req.method} request for ${req.url}`);
if (req.url === '/') {
fs.readFile('./public/index.html', 'UTF-8', function (err, html) {
res.writeHead(200, {
'Content-Type': 'text/html',
});
res.end(html);
});
} else if (req.url.match(/.css$/)) {
const cssPath = path.join(__dirname, 'public', req.url);
const cssStream = fs.createReadStream(cssPath, 'UTF-8');
res.writeHead(200, {
'Content-Type': 'text/css',
});
cssStream.pipe(res);
} else {
res.writeHead(404, {
'Content-Type': 'text/plain',
});
res.end('404 Not Found');
}
}).listen(8080);
console.log('File server running on port 8080');
http.createServer(function (req, res) {
console.log(`${req.method} request for ${req.url}`);
if (req.url === '/') {
res.writeHead(200, {
'Content-Type': 'text/json',
});
res.end(JSON.stringify(data));
} else {
res.writeHead(404, {
'Content-Type': 'text/plain',
});
res.end('File not found');
}
}).listen(8080);
console.log('Server listening on port 8080');
http.createServer(function (req, res) {
if (req.method === 'GET') {
res.writeHead(200, {
'Content-Type': 'text/html',
});
fs.createReadStream('./public/form.html', 'UTF-8').pipe(res);
} else if (req.method === 'POST') {
let body = '';
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
res.writeHead(200, {
'Content-Type': 'text/html',
});
res.end(`
<!DOCTYPE html>
<html>
<head>
<title>Form Results</title>
</head>
<body>
<h1>Your Form Results</h1>
<p>${body}</p>
</body
</html>
`);
});
}
}).listen(8080);
console.log('Form server listening on port 8080');
Introduction to Node & Express – JavaScript Scene – Medium
req.baseUrl
=> '/proxy'
req.url
=> '/lib/test.js'
, inherit from Node http modulereq.originalUrl
=> '/proxy/lib/test.js'
const app = express();
app.use((req, res, next) => {
console.log(`${req.method} request for '${req.url}' - ${JSON.stringify(req.body)}`);
next();
});
app.use('/app', express.static('./public'));
app.listen(8080, () => {
console.log('Express app running on port 8080');
});
module.exports = app;
app.get('/api', (req, res) => {
res.json(items);
});
app.post('/api', (req, res) => {
items.push(req.body);
res.json(items);
});
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/api', (req, res) => {
items.push(req.body);
res.json(items);
});
app.delete('/api/:id', (req, res) => {
items = items.filter(item => item.id.toLowerCase() !== req.params.id.toLowerCase());
res.json(items);
});
const proxy = require('express-http-proxy');
// '/proxy/lib/test.js' => '/new/lib/test.js'
app.use('/proxy', proxy(servers.remote, {
proxyReqPathResolver: (req) => '/new' + req.url,
}));
// req.baseUrl => '/proxy'
// req.url => '/lib/test.js', inherit from Node http module
// req.originalUrl => '/proxy/lib/test.js'
Server
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({
port: 3000,
});
wss.on('connection', (ws) => {
ws.on('message', (message) => {
if (message === 'exit') {
ws.close();
} else {
// broadcast
wss.clients.forEach((client) => {
client.send(message);
});
}
})
ws.send('Welcome to chat');
});
Client
const ws = new WebSocket('ws://localhost:3000');
ws.onopen = () => {
setStatus('CONNECTED');
};
ws.onclose = () => {
setStatus('DISCONNECTED');
};
ws.onmessage = (payload) => {
printMessage(payload.data);
};
Server
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const app = express();
const server = http.Server(app);
const io = socketIO(server);
app.use(express.static('./public'));
io.on('connection', (socket) => {
console.log('connected');
socket.on('chat', (message) => {
// send to everyone
io.emit('message', message);
// send to everyone except this socket
// socket.broadcast.emit('message', message);
});
socket.on('disconnect', () => {
console.log('disconnected');
});
socket.emit('message', 'Welcome to chat');
});
server.listen(3000, () => {
console.log('Starting Socket App on *:3000');
});
Client
const socket = io('htpp://localhost:3000');
socket.on('connect', () => {
setStatus('CONNECTED');
});
socket.on('disconnect', () => {
setStatus('DISCONNECTED');
});
socket.on('message', (message) => {
printMessage(message);
});
Test a Node RESTful API with Mocha and Chai | Scotch
$ node --inspect index.js
In node v7+, you can use --inspect-brk
for --inspect
& --debug-brk
combo.
$ node --inspect-brk index.js
Open chrome://inspect
in Chrome.
Use inspect-process
to open a Chrome window automatically.
https://github.com/jaridmargolin/inspect-process
# install inspect-process globally
npm install -g inspect-process
# start the debugger with inspect
inspect index.js --debug-exception=true
Update: This tool is mostly obsolete as much of the philosophy has been brought into Node/DevTool core, see here for details.
Debugging Node.js in Chrome DevTools
$ npm install -g devtool
Watch:
$ devtool app.js --watch
Debug:
$ devtool app.js --break
$ npm install -g node-inspector
const querystring = require('querystring');
querystring.escape(str)
querystring.unescape(str)
querystring.parse(str, sep, eq)
seq
- &
eq
- =
const path = require('path');
path.basename(path, ext)
- returns the last portion of a path
path.dirname(path)
- returns the directory name of a path
.path.extname(path)
- returns the extension of the path
. => .js
path.parse(path)
- returns an object whose properties represent significant elements of the path
.
root
- /
dir
- /home/user/dir
base
- file.txt
ext
- .txt
name
- file
path.join(...paths)
- joins all give path
segments together, then normalizes the resulting path.path.normalize(path)
- normalize the given path
, resolving '..'
and '.'
segments.path.resolve(...paths)
- resolves a sequence of paths into an absolute path.$ choco install -y nodist
Debugging
$ set DEBUG=nodist:*
Mirror Server
$ set NODIST_NODE_MIRROR=http://npm.taobao.org/mirrors/node
Proxy
$ set HTTPS_PROXY=http://127.0.0.1:8080
$ nodist ls
$ nodist ds
$ nodist latest
$ nodist + 8.2
$ nodist global 14
$ nodist npm ls
$ nodist npm latest
$ nodist npm match
$ nodist npm global latest
$ nodist npm add ^6
$ nodist npm remove 6.x
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/<tag>/install.sh | bash
Verify installation
$ command -V nvm
nvm is a shell function from /home/user/.nvm/nvm.sh
$ nvm --version
0.38.0
Auto start
Add these lines to your ~/.bashrc
, ~/.profile
, or ~/.zshrc
file to have it automatically sourced upon login.
# nvm
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
List
$ nvm ls
$ nvm ls-remote
$ nvm which 10
Install
$ nvm install --lts
$ nvm install node # latest
$ nvm install 10
Uninstall
$ nvm uninstall --lts
Set default node version
$ nvm alias default node
Use
$ nvm use --lts
$ nvm use node
$ nvm use 10
Cluster | Node.js v9.5.0 Documentation
A single instance of Node.js runs in a single thread. To take advantage of multi-core systems, the user will sometimes want to launch a cluster of Node.js processes to handle the load.
The cluster module allows easy creation of child processes that all share server ports.
"scripts": {
"start": "yarn dev:start",
"dev:start": "nodemon --ignore lib --exec babel-node src/server",
"prod:build": "rimraf lib && babel src -d lib --ignore .test.js",
"prod:start": "cross-env NODE_ENV=production pm2 start lib/server && pm2 logs",
"prod:stop": "pm2 delete server",
"test": "eslint src && flow && jest --coverage",
"precommit": "yarn test",
"prepush": "yarn test"
}
$ nvs ls
$ nvs ls-remote
$ nvs add latest
$ nvs rm latest
$ nvs use latest
Events | Node.js v11.3.0 Documentation
const {EventEmitter} = require('events');
const emitter = new EventEmitter();
emitter.on('customEvent', function (message, status) {
console.log(`${status}: ${message}`);
});
emitter.emit('customEvent', 'Hello World', 200);
emit()
on()
once()
removeListener()
/ off()
removeAllListeners()
nodesource/distributions: NodeSource Node.js Binary Distributions
Add apt source repository
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
Replace with mirror server
/etc/apt/sources.list.d/nodesource.list
deb https://mirrors.ustc.edu.cn/nodesource/deb/node_10.x bionic main
deb-src https://mirrors.ustc.edu.cn/nodesource/deb/node_10.x bionic main
Install package
sudo apt install -y nodejs
Add apt source repository
curl -sL https://deb.nodesource.com/setup_10.x | bash -
Replace with mirror server
/etc/apt/sources.list.d/nodesource.list
deb https://mirrors.ustc.edu.cn/nodesource/deb/node_10.x bionic main
deb-src https://mirrors.ustc.edu.cn/nodesource/deb/node_10.x bionic main
Install package
apt install -y nodejs
curl -sL https://rpm.nodesource.com/setup_10.x | bash -
Node.js 如何处理 ES6 模块 - 阮一峰的网络日志 (ruanyifeng.com)
module.mjs
await import('module.mjs');
import package from 'cjs-module';
import { method } from 'cjs-module';
maxogden/art-of-node: a short introduction to node.js
Tutorials
NodeSchool
Best Practices
goldbergyoni/nodebestpractices: The Node.js best practices list (March 2020)
19 things I learnt reading the NodeJS docs – Hacker Noon