How to check if folder/file is deleted at runtime? nodejs - node.js

At the beginning of a program, I can easily check if a folder exists or not and handle it.
But when it comes to runtime, thats a tricker question. If a folder is deleted, thats when a ton of data never gets to where it's supposed to go.
How do I check if a folder has been deleted at runtime?
How do I remake the folder if it's deleted?
(This is an nodejs question)

Well, this problem can be easily solved with some npm modules.
You need a npm module to track file deletions etc
https://github.com/paulmillr/chokidar is an great resource.
According to the npm module:
// Initialize watcher.
const watcher = chokidar.watch('file, dir, glob, or array', {
ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true
});
Then:
watcher
.on('unlinkDir', path => {
if (path == "/target/path/to/check/" && makeSureThisIfThisIsAnDirectory){
//do something to fix this before files never reach their destination
}
})

Related

npm package and git, how should I handle data file

I am working on building a npm package. In my package, I need to have a data folder which contains some json files to hold user data.
The issue is, I do want the user to have some blank data files when they first install the package. But I don't want:
When user used my package for a while and then do a version update, the newer version shouldn't overwrite user's existing data.
During development, my testing data in those files shouldn't be committed into git.
I have tried .gitignore for the second scenario, but once the file exists in the repository, it doesn't seem that .gitignore will work.
I am a bit confused here. How should I handle this?
The easiest solution here is to give your library an options object for specifying which directory to read those json files from, with a default location.
Assuming your library is based on some top-level class:
const DEFAULT_DATA_PATH= ...
export default class Library {
constructor(options={}) {
this.dataPath = options.dataPath || DEFAULT_DATA_PATH;
},
...
};
And if there is CLI invocation for your package, a runtime flag that lets you specify the location (like --data ./ignored/realdata) so that you can put your dev files in a dir that goes in your .gitignore and that you simply add as data dir flag in your npm run scripts.
const DEFAULT_DATA_PATH = ...
var dataPathOverride = process.argv.indexOf('--data') + 1;
dataPathOverride = dataPathOverride ? process.argv[dataPathOverride] : DEFAULT_DATA_PATH;
export default class Library {
constructor(options={}) {
this.dataPath = options.dataPath || dataPathOverride;
},
...
};

Module not found error when trying to use a module as a local module

I am trying to understand as how to make a local module. At the root of node application, I have a directory named lib. Inside the lib directory I have a .js file which looks like:
var Test = function() {
return {
say : function() {
console.log('Good morning!');
}
}
}();
module.exports = Test;
I have modified my package.json with an entry of the path to the local module:
"dependencies": {
"chat-service": "^0.13.1",
"greet-module": "file:lib/Test"
}
Now, if I try to run a test script like:
var greet = require('greet-module');
console.log(greet.say());
it throws an error saying:
Error: Cannot find module 'greet-module'
What mistake am I making here?
modules.export is incorrect. It should be module.exports with an s.
Also, make sure after you add the dependency to do an npm install. This will copy the file over to your node_modules and make it available to the require function.
See here for a good reference.
Update:
After going through some examples to figure this out I noticed, most projects have the structure I laid out below. You should probably format your local modules to be their own standalone packages. With their own folders and package.json files specifying their dependencies and name. Then you can include it with npm install -S lib/test.
It worked for me once I did it, and it'll be a good structure moving forward. Cheers.
See here for the code.

Where to store a node_package specific settings on the client machine?

I' have a node_package bookiza (installed globally) that POSTS/PATCHes values to a receiving substrate using credentials taken off a .rc file.
I'm currently saving the .rc file inside the module itself, at usr/lib/node_modules/bookiza, but I can do so anywhere I like. The problem in storing it inside the package is that the settings are overwritten whenever the user npm i -g installs again, to update the package.
function updateBookizaConfig(res) {
var bookizaConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.bookizarc')).toString());
bookizaConfig.token = res.body.key;
bookizaConfig.username = res.body.username;
bookizaConfig.email = res.body.email;
fs.writeFileSync(path.join(__dirname, '..', '.bookizarc'), JSON.stringify(bookizaConfig, null, 2));
// Move or copy the config file outside of package to retain credentials upon package update.
// cp('-R', path.join(__dirname, '..', '.bookizarc'), path.join(__dirname, '..', '..'));
console.log(chalk.bold.cyan('Registration successful'));
}
This works, but note that the .dotfile file is saved inside usr/lib/node_modules/ directory, as a sibling to other global packages installed on the machine. Now I could put the settings file anywhere else on the machine too, but what is the good practice/standard way of doing this?
Will it be better for me to put the settings file inside a usr/lib/node_modules/dots folder where in future other package writers could also probably put their .rc files?
Users in the comments have already hit on this solution, but here for the record anyway:
npm recommends you save user-specific config data in the user's home directory rather than in npm's modules directory, both because it is inconvenient to persist those settings, and because it is a problem in multi-user environments.
There are a number of modules that will find the user's home directory in a cross-platform way for you to put your files in; we like https://www.npmjs.com/package/osenv

Why can node not find my module?

I am using node v0.12.5 with nwjs and I have defined my own custom module inside of my project so that I can modularise my project (obviously).
I am trying to call my module from another module in my project but every time I attempt to require it I get the error could not find module 'uploader'.
My uploader module is currently very simple and looks like:
function ping_server(dns, cb) {
require('dns').lookup(dns, function(err) {
if (err && err.code == "ENOTFOUND") {
cb(false);
} else {
cb(true);
}
})
}
function upload_files()
{
}
module.exports.ping_server = ping_server;
module.exports.upload_files = upload_files;
With the idea that it will be used to recursively push files to a requested server if it can be pinged when the test device has internet connection.
I believe I have exported the methods correctly here using the module.exports syntax, I then try to include this module in my test.js file by using:
var uploader = require('uploader');
I also tried
var uploader = require('uploader.js');
But I believe node will automatically look for uploader.js if uploader is specified.
The file hierarchy for my app is as follows:
package.json
public
|-> lib
|-> test.js
|-> uploader.js
|-> css
|-> img
The only thing I am thinking, is that I heard node will try and source the node_modules folder which is to be included at the root directory of the application, could this be what is causing node not to find it? If not, why can node not see my file from test.js given they exist in the same directory?
UPDATE Sorry for the confusion, I have also tried using require('./uploader') and I am still getting the error: Uncaught Error: Cannot find module './uploader'.
UPDATE 2 I am normally completely against using images to convey code problems on SO, but I think this will significantly help the question:
It's clear here that test.js and uploader.js reside in the same location
When you don't pass a path (relative or absolute) to require(), it does a module lookup for the name passed in.
Change your require('uploader') to require('./uploader') or require(__dirname + '/uploader').
To load a local module (ie not one from node_modules) you need to prefix the path with ./. https://nodejs.org/api/modules.html#modules_modules
So in your case it would be var uploader = require('./uploader');
This problem stemmed from using Node Webkit instead of straight Node, as stated in their documentation all modules will be source from a node_modules directory at the root of the project.
Any internal non C++ libraries should be placed in the node_modules directory in order for Node webkit to find them.
Therefore to fix, I simply added a node_modules directory at the root of my project (outside of app and public) and placed the uploader.js file inside of there. Now when I call require('uploader') it works as expected.
If you're developing on a mac, check your file system case sensitivity. It could be that the required filename is capitalized wrong.

Remove all sub directories with rimraf on node.js

I have a directory structure where certain folder Data has sub directories. At some point I want those removed all at once and I've installed the otherwise awesome rimraf package for node.js
My code so far:
var dataPath === Path.normalize(__dirname + '/backend/data/');
rimraf(dataPath, function(error) {
console.log('Error: ', error);
});
I've tried with both /backend/data/ and /backend/data/ *, but none seems to do the trick - the first deletes the entire data folder and the second fires an error 'Can't delete null'
I guess I could scan the main directory, find all sub folders and delete them one by one, but if this can be done with rimraf or a similar package, I'd rather go with it.
The easiest solution is to just re-create the data directory after rimraf finishes deleting it. Depending on your use case, that can introduce a race condition, but I doubt rimraf itself is race-safe in any situations where that isn't.
Another option is to read the contents of the directory and rimraf each of those, but that is more work and doesn't avoid any race conditions that would affect the first option.
The current version of rimraf supports globs, so one could just add an asterisk to the end of the folder, like so:
rimraf( path.join(__dirname, "./uploads/*"), (err) => { ... });

Resources