Node.js scripting
Update node
Use node version manager (nvm) to manage node versions:
nvm install --ltsDifferent options are discussed here.
Install stable lts version and set it as default
nvm install stable
nvm alias default stableWeb Server
Example of a simple web server:
/* Load the HTTP library */
var http = require("http");
/* Create an HTTP server to handle responses */
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);NODE_PATH
NODE_PATHis like the windows path environment variable. Whenever node can’t find a file, it looks through the paths in the paths stored in the NODEPATH variable. So in this case, if you require something from the shared folder, node will know how to locate it. In windows you can’t set NODEPATH in this way, you’ll have to set it before you run the node command, or use the cross-env module, which allow setting node environment variables unix style in windows:
"dev": "cross-env NODE_PATH=$NODE_PATH:./shared node --harmony .",
Taken from this nice answer.
Modules
The modules object is local, not global.
Examples
Default export
// Monkey.js (export)
var React = require('react');
require('./Monkey.css');
var Color = require('./Shapes');
class Monkey extends React.Component {
...
}
module.exports = Monkey;
// Some other file (import)
const Monkey = require('./Monkey.js');Multiple exports: Named exports/imports
// Animals.js (export)
module.exports = {
Monkey,
Bear
}
// Some other file (import)
const { Monkey } = require('./Animals');
const { Bear } = require('./Animals');Alternative
// Animals.js (export)
module.exports.Monkey = Monkey;
module.exports.Bear = Bear;
// Some other file (import)
const { Monkey } = require('./Animals');
const { Bear } = require('./Animals');Examples taken from this nice article for the most part.
Execute JS from command line
Example
node -e "console.log('My environment variables: ', process.env)"Run node.js scripts
Call script
Use ES6 syntax with the --harmony flag:
node --harmony my_script.jsor
babel-node my_script.jsPass arguments via npm:
In package.json the script is defined as such:
"scripts": {
"myScript": "node --harmony my_script.js"
},When running the script, arguments can be passed with an additional --:
npm run myScript -- --name "Jonas" --hobby cyclingUseful packages
-
commanderCreates help file and flags etc. and also parses them.
import * as program from 'commander'; program .version('0.0.2') .usage('[options] <relative-path-to-JSON-file>') .description( 'Convert given file with sentences into a great novel.' ) .parse(process.argv); ... if (_.isEmpty(program['args'])) { program.help(); // this exits }Also useful: Catch errors on
processvariableunhandledRejection:process.on('unhandledRejection', function(reason: any, p: any) { /* tslint:disable-next-line:no-console */ console.error('Possibly Unhandled Rejection at: Promise ', p, ' reason: ', reason); }); -
minimistparses arguments and flags.
Here it parses the argument
app-name:const parseArgs = require('minimist'); const argv = parseArgs(process.argv.slice(2));console.dir(argv); const appName = argv['app-name'];Some more work with results of
parseArgsif (typeof argv.flavor !== 'string') { throw Error('--flavor option required'); } const options = { appName: argv['app-name'] || '', appIdentifier: argv['app-id'] || `com.my-company.${argv.flavor}`, api: { token: argv['api-token'] || '', host: argv['api-host'] || '', }, codepush: { ios: {}, android: {}, }, };
Create a workplan
Example: flavor-copy.js
const parseArgs = require('minimist');
const _ = require('lodash');
const fs = require('fs');
const fse = require('fs-extra');
const path = require('path');
const async = require('async');
// ---------------------------
// SETTINGS
// ---------------------------
const argv = parseArgs(process.argv.slice(2));
const cwd = process.cwd();
if (typeof argv.flavor !== 'string') {
throw Error('--flavor option required');
}
const flavorDir = path.join(cwd, 'flavor', argv.flavor);
const outputDir = path.join(cwd, 'data');
const workplan = [];
// check if a flavor with that name exists
try {
fs.statSync(flavorDir);
} catch (e) {
throw Error(`flavor '${argv.flavor}' doesn't exists`);
}
// ---------------------------
// copy options file
// ---------------------------
workplan.push((next) => {
fse.copy(
path.join(flavorDir, 'options.json'),
path.join(outputDir, 'options.json'),
next
);
});
// ---------------------------
// copy platform files
// ---------------------------
if (argv.platform) {
workplan.push((next) => {
fse.copy(
path.join(flavorDir, argv.platform),
path.join(cwd, argv.platform),
next
);
});
}
// ---------------------------
// copy img files
// ---------------------------
workplan.push((next) => {
fs.stat(path.join(flavorDir, 'img'), (err) => {
if (!err) {
fse.copy(
path.join(flavorDir, 'img'),
path.join(outputDir, 'img'),
next
);
} else {
next();
}
});
});
// ---------------------------
// merge i18n files
// ---------------------------
workplan.push((next) => {
const i18nDir = path.join(outputDir, 'i18n');
const flavorI18nDir = path.join(flavorDir, 'i18n');
const mergeI18nFiles = (fileName) => {
const src = path.join(i18nDir, fileName);
let i18nSrc;
let i18nFlavor;
Promise.resolve()
.then(() => new Promise((resolve, reject) => {
fs.readFile(src, 'utf8', (err, data) => {
if (err) reject(err);
else resolve(JSON.parse(data));
});
}))
.then((data) => { i18nSrc = data; })
.then(() => new Promise((resolve, reject) => {
fs.readFile(path.join(flavorI18nDir, fileName), 'utf8', (err, data) => {
if (err) reject(err);
else resolve(JSON.parse(data));
});
}))
.then((data) => { i18nFlavor = data; })
// merge contents
.then(() => _.merge(i18nSrc, i18nFlavor))
// save to src
.then((data) => new Promise((resolve, reject) => {
fs.writeFile(src, JSON.stringify(data, null, 2), 'utf-8', (err, data) => {
if (err) reject(err);
else resolve();
});
}));
};
fs.readdir(flavorI18nDir, (err, items) => {
// folder exists
if (!err) {
//
items.reduce(
(sequence, fileName) => (
sequence.then(() => mergeI18nFiles(fileName))
),
Promise.resolve()
).then(() => next());
} else {
next();
}
});
});
// ---------------------------
// Execute the workplan
// ---------------------------
async.series(workplan, (err) => {
if (err) {
console.error('%s', err.stack || err.message || err.toString());
return;
}
console.info('Finished copying flavor');
});Read write with (pimped) fs
Wrap inside Promise:
export function promisify1<ARG1, RESULT>(
toWrap: (a: ARG1, cb: (e: any, r: RESULT) => void) => void
): (a: ARG1) => Promise<RESULT> {
return (a: ARG1) =>
new Promise<RESULT>((resolve, reject) =>
toWrap(a, (err, result) => {
err != null ? reject(err) : resolve(result);
})
);
}
export function promisify2<ARG1, ARG2, RESULT>(
toWrap: (a1: ARG1, a2: ARG2, cb: (e: any, r: RESULT) => void) => void
): (a1: ARG1, a2: ARG2) => Promise<RESULT> {
return (a1: ARG1, a2: ARG2) =>
new Promise<RESULT>((resolve, reject) =>
toWrap(a1, a2, (err, result) => {
err != null ? reject(err) : resolve(result);
})
);
}
export const readFile = promisify2<string, string, string>(fs.readFile);
export const writeFile = promisify2<string, string, void>(fs.writeFile as any);Commands
Print out all documents in the ‘test’ collection:
db.collection('test').find().toArray(console.log);console.log is callback for find().toArray function.
Discuss on Twitter ● Improve this article: Edit on GitHub