PhantomJS copy file with overwrite - javascript

Reading from their document:
copy(source, destination)
Currently, the way I cope with this is to check fs.exist('myfile') and manual delete it prior to copy:
var fs = require('fs');
var fileName = 'myfile-backup.txt';
if (fs.exists(fileName)) {
fs.remove(fileName);
}
fs.copy('myfile.txt', fileName);
phantom.exit();
I don't know if there is any better way to overwrite the file. Checking for existing file may have a potential problem when I can't remove the file. I will probably need to do more error handling with this approach. It seems to be a common task, so I would like to know what solution people come up with.

I have written a small extension to the fs module. If you try to overwrite a file with fs.copy it will throw an exception which you can catch to do some error handling like removing an existing file.
I also added an optional maxTrials argument if there is a problem that the file is created every time in between the copy trial and the remove.
var fs = require('fs');
fs.overwrite = function(source, destination, maxTrials){
var overwritten = false;
var trials = 0;
maxTrials = parseInt(maxTrials)
maxTrials = !!maxTrials ? maxTrials : null;
while(!overwritten) {
if (maxTrials && trials > maxTrials) {
return -1;
}
try {
this.copy(source, destination);
overwritten = true;
} catch(e) {
if (fs.exists(destination)) {
fs.remove(destination);
} else {
return -2;
}
}
trials++;
}
return trials;
};

Related

How to avoid can't find module

I have reactjs script which use .jpg
However jpg filename is dynamically changed.
const img_require = require(id + ".jpg");
it works well when file exists, but when there is not file,
throwing error like this below
Error: Cannot find module './12.jpg'
I want to avoid this error message and use dummy.jpg.
But this code doesn't work on browser side(of course)
fs = require('fs')
if (fs.exitsSync('./12.jpg')){
// ok
}else {
const img_require = 'dummy.jpg';
}
Is there any idea??
You can use try-catch block for require file like this :
I am not expert in react but this might be basic hack 😅.
var fs;
try {
fs = require(id + ".jpg")
} catch (error) {
fs = require("dummy.jpg")
}
One more way to handle error that is provided by require.js using ErrorCallback
here is the fallback answer for module load.
Catching module loading errors and processing them
require([path], function(content){
//need to catch errors as this will not be called;
}, function (err) {
//display error to user
});
const dynamicid = id || 'dummy'
const img_require = require(`${dynamicid} + .jpg`);
var dynamicId = id ? id : 'dummy'
var img = require(`${dynamicId} + .jpg`);

javascript read .ini file

I tried searching . How do i do it? I'm create html and i want to read .ini file by javascript on the client Not in the server.
I copy code from javascript parser for a string which contains .ini data
error Uncaught ReferenceError: require is not defined var fs = require('fs')
function parseINIString() {
var fs = require('fs')
var data = fs.readFileSync('C:\\test.ini', 'utf8');
var regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,
param: /^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/
};
var value = {};
var lines = data.split(/\r\n|\r|\n/);
var section = null;
alert(lines);
for (x = 0; x < lines.length; x++) {
if (regex.comment.test(lines[x])) {
return;
} else if (regex.param.test(lines[x])) {
var match = lines[x].match(regex.param);
if (section) {
value[section][match[1]] = match[2];
} else {
value[match[1]] = match[2];
}
} else if (regex.section.test(lines[x])) {
var match = lines[x].match(regex.section);
value[match[1]] = {};
section = match[1];
} else if (lines.length == 0 && section) {//changed line to lines to fix bug.
section = null;
};
}
return value;
}
Let's say the javascript running in a browser is so called 'client script'. There are lots of limitation while writing client script, one of them is that it's not allowed to visit the user file on disk. This is to prevent any injected hacker script from reading private data. And the explicit error you see is about the new key word 'require' which is well known as 'commonjs' module which is introduced by Nodejs usually. The 'fs' is one of the internal module of Nodejs as well.
So if you still consist using client script to get the job done, you have to rewrite the script, not 'require' the 'fs' module. And use the file reader to get the content of a file object, which is generated by a file input usually.
A detailed introduction about how to read local files.

Syncing files from one directory to another in Node?

I was using cpy with a globbing pattern to find and copy all the files in src/main/css and place them in ./dist.
However now I also have sub directories below src/main/css (For example src/main/css/margins/index.css) and cpy does not include these when copying the files.
Is there an API in Node (fs or path?) that handles this case, or anyone know of a handy package?
Try this.
const fs = require('fs');
const path = require('path');
var mkdir = function (dir) {
// making directory without exception if exists
try {
fs.mkdirSync(dir, 0755);
} catch (e) {
if (e.code != "EEXIST") {
throw e;
}
}
};
var copy = function (src, dest) {
var readS = fs.createReadStream(src);
var writeS = fs.createWriteStream(dest);
readS.pipe(writeS);
readS.on("end", function () {
// Operation done
});
};
var copyDir = function (src, dest) {
mkdir(dest);
var files = fs.readdirSync(src);
for (var i = 0; i < files.length; i++) {
var current = fs.lstatSync(path.join(src, files[i]));
if (current.isDirectory()) {
copyDir(path.join(src, files[i]), path.join(dest, files[i]));
} else if (current.isSymbolicLink()) {
var symlink = fs.readlinkSync(path.join(src, files[i]));
fs.symlinkSync(symlink, path.join(dest, files[i]));
} else {
copy(path.join(src, files[i]), path.join(dest, files[i]));
}
}
};
copyDir('./src', './dest');
This piece of code is inspired from https://gist.github.com/tkihira/3014700. I have made some modifications in the original code to get it working as util.pump is obsolete now.
I ended up using using copy-dir
require('copy-dir').sync(PLI.src.main.css, PLI.DIST);
If anyone has a way to do the same thing with the Node and avoiding dependencies please do tell.

Simple JavaScript code does not work with nodejs

I am an experienced JavaScript programmer, but am just starting to learn node.js.
Using node, I want to read the contents of a directory, and print out files of only a specific extension. Both the directory and file-extension will be given by command-line arguments.
But, I also want to push myself and explore JavaScript programming concepts as I solve these puzzles, so I wanted to create a File object to store information about a file, and use that to solve the problem.
Becaause of this, my approach is overly-complex, and I know that there are simpler ways of doing this, but I just want an answer which solves my current problem:
Why does node.js throw the following error
this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
^
TypeError: Cannot read property '0' of null
in this code:
function File(file){
if (file instanceof File) return file;
if (!(this instanceof File)) return new File(file);
if (typeof file !== "string") throw new Error("Useful error." + typeof(file));
this.fullName = file;
/*vvvvvvvvvvvv Important Bit vvvvvvvvvvvvvv*/
this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
this.extension = /[^.]+(?=$)/.exec(file)[0];
}
File.prototype = {
isOfType: function(ext){
return ext === this.extension;
}
}
var fs = require('fs');
var argv = process.argv;
fs.readdir(argv[2], function(err, list){
var res = list.filter(function(element, index, array){
var file = new File(element);
return file.isOfType(argv[3]);
});
console.log(res);
});
but, in a Chrome js console, it runs fine (with simulated process and fs objects of course).
To me (inexperienced me) it looks like node could be making several mistakes:
Not handling the regex properly (I've done tests and this seems likely)
Using square brackets to find key '0' within object, instead of index 0 within array.
Or I could be making several mistakes:
Not understanding fs.readdir and its necessary callback.
Not understanding possible differences between constructors in JavaScript and Node
Please help, I'd like an answer that solves or explains my current problem, not one that works around it.
Thanks.
Node has a built in way to check for valid files
function File(file){
if (file instanceof File) return file;
if (!(this instanceof File)) return new File(file);
if (typeof file !== "string") throw new Error("Useful error." + typeof(file));
var stat = fs.statSync(file);
if ( stat && stat.isFile() ) {
this.fullName = file;
/*vvvvvvvvvvvv Important Bit vvvvvvvvvvvvvv*/
this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
this.extension = /[^.]+(?=$)/.exec(file)[0];
}
}
Node also has a built in way to get extensions and path names
var path = require('path');
var basename = path.basename(file);
var extension = path.extname(file);
Why does node.js throw the following error
this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
^
TypeError: Cannot read property '0' of null
Because file doesn't match the regular expression, and so exec returns null; then you're doing null[0], which throws the exception. That would happen for a name like a or a., for instance, or the . and .. pseudo-directories.
Use the NodeJS debugger or just console.log file` immediately prior, an you'll see the value that's causing trouble.
It's because any file names which don't match your regular expression, such as many directory names (which are included in your list variable), will then return null here:
/.+(?=\.[^.]+)/.exec(file)
so you are trying to do
null[0]
which will not work.
I solved this by simply checking for a period within the file name:
var file = (element.indexOf(".") > -1) ? new File(element) : false;
return (file) ? file.isOfType(argv[3]) : false;
within the filter, so final code resembles:
fs.readdir(argv[2], function(err, list){
var res = list.filter(function(element, index, array){
var file = (element.indexOf(".") > -1) ? new File(element) : false;
return (file) ? file.isOfType(argv[3]) : false;
});
for (var i = 0; i < res.length; console.log(res[i++]));
});

Create plugin gulp with stream

I created plugin for send json data in json file.
But I don't understand why send my object json in pipe, and not write file directly in my plugin.
I want use my plugin whit this syntax:
gulp.task('js-hash', function()
{
// Get all js in redis
gulp.src('./build/js/**/*.js')
.pipe(getHashFile('/build/js/'))
.pipe(gulp.dest('./build/js/hash.json'));
});
And not that:
gulp.task('js-hash', function()
{
// Get all js in redis
gulp.src('./build/js/**/*.js')
.pipe(getHashFile('./build/js/hash.json', '/build/js/'));
});
This is my plugin:
var through = require('through2');
var gutil = require('gulp-util');
var crypto = require('crypto');
var fs = require('fs');
var PluginError = gutil.PluginError;
// Consts
const PLUGIN_NAME = 'get-hash-file';
var json = {};
function getHashFile(filename, basename)
{
if (!filename) {
throw PluginError(PLUGIN_NAME, "Missing filename !");
}
// Creating a stream through which each file will pass
var stream = through.obj(function (file, enc, callback) {
if (file.isNull()) {
this.push(file); // Do nothing if no contents
return callback();
}
if (file.isBuffer()) {
var hash = crypto.createHash('sha256').update(String(file.contents)).digest('hex');
json[file.path.replace(file.cwd+basename, '')] = hash;
return callback();
}
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Stream not supported!'));
return callback();
}
}).on('finish', function () {
fs.writeFile(filename, JSON.stringify(json), function(err) {
if (err) {
throw err;
}
});
});
// returning the file stream
return stream;
}
// Exporting the plugin main function
module.exports = getHashFile;
Your are idea
Nothing prevents you from doing this... besides not respecting plugins guidelines!
Users actually assume a plugin will stream files and that they can pipe them to other plugins.
If I get your code right, you're trying to generate a file that contains all sha hashes of inbound files. Why not let users take this file and pipe it to other plugins? You'd be surprised what people could do.
While this question looks a bit opinion-based, you could definitely put the focus on how to deal with files that may not belong to the main stream of files. Issues like this can be found in many plugins; for example, gulp-uglify authors are wondering how they can add source-maps without mixing js and source map downstream.

Categories