Watching folder for change in Node.js - javascript

Im looking for a way to notice changes in a directory in Node.js. I read THIS and was thinking thats exactly what i want. But chokidar spawns to many events.
My code looks like this:
chokidar = require('chokidar');
var watcher = chokidar.watch('./Update', {ignored: /[\/\\]\./, persistent: true});
var count=0;
watcher
.on('add', function(path)
{
count++;
console.log('File ' + path + ' has been added' + count);
})
.on('error', function(error) {console.error('Error happened', error);})
When i run it and move a file in the Update directory i get the following output:
File Update\Neues Textdokument.txt has been added1
File Update\Neues Textdokument.txt has been added2
File Update\Neues Textdokument.txt has been added3
In the future i want to replace the console output with code that actualy does something, so i cant have moving one file spawning 3 events. Am I using the libary wrong? Or is the libary just not suited for what I want to do? If so what libary should i use instead?

try the following patch:
https://github.com/paulmillr/chokidar/pull/124
as stated in
https://github.com/paulmillr/chokidar/issues/104

In the end I am using version 0.7.1 of chokidar. It works fine as long the folder is empty at the moment the file is added, but im still looking for a better solution

Related

I'm using Gulp and failing to produce the final development script for production.

So I'm having a slight problem with producing production ready scripts for my project. I'm using gulp to concatenate and minify my css and js, and while the css is working fine the gulp js function isn't generating my final file. Please refer to my code below:
gulp.task('js', function() {
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(gulp.dest(source + 'js'))
.pipe(rename({
basename: 'production',
suffix: '-min',
}))
.pipe(uglify())
.pipe(gulp.dest(source + 'js/'))
.pipe(notify({ message: 'Scripts task complete', onLast: true }));
});
If anyone has encountered a similar problem or has any tips it would be much appreciated :)
There is nothing wrong with your gulpfile. I tested it and it works perfectly.
The only thing I can guess is that your source is not set correctly. Did you forget the trailing slash '/' ?
I would suggest 2 things to figure it out. Include node path library to check where source is actually pointing to like this:
var path = require('path');
// in gulp task ...
path.resolve(path.resolve(source + 'js/app'));
Make sure it points where you think it does.
Secondly, you could use gulp-debug to establish that any files are found:
npm install gulp-debug
Then
var debug = require('gulp-debug');
// in gulp task ...
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(debug())
.pipe(gulp.dest(source + 'js'))
.pipe(debug())
// etc.
Good luck!
Based on additional infomation in the comments I realise you are generating JS files in a separate process ...
gulp is asynchronous by default. What this boils down to is that all functions try to run at the same time - if you want a specific order it must be by design. This is great because it's very fast but can be a headache to work with.
Problem
Here is what's basically happening:
// SOME TASK THAT SHOULD BE RUN FIRST
gulp.task('copy-vendor-files-to-tempfolder', function (done) {
// copy files to vendor folder
done()
})
// SOME TASKS THAT DEPEND ON FIRST TASK
gulp.task('complile-styles', function () { /* independent task */ })
gulp.task('concat-vendor-files', function () { /* concat files in vendor folder. depends on vendor files existing */ })
// GENERAL TASK WHICH STARTS OTHERS
gulp.task('ready', ['copy-vendor-files-to-tempfolder', 'compile-styles', 'concat-vendor-files])
When you try to run:
$ gulp ready
GULP TASK WILL FAIL! Folder is being created at the same time!!
NOWHERE TO COPY FILES!
Solution
There are many solutions but the following module has come in handy for me again and again:
npm install run-sequence
Then in your gulpfile.js:
var runSequence = require('run-sequence')
gulp.task('ready', function (done) {
runSequence(
'create-folders', // do this first,
[
'copy-css-files',
'copy-html-files'
], // do these AFTER but in parallel
done // callback when ready
)
})
This will guarantee the folder exists when you try to run the other functions.
In your specific case, you should make sure the task that concatenates the JS files is run after the task that copies them out of vendor.
Note: I'm leaving other answer because it contains useful help for debugging similar issues.
HTH!

Copy files with Yeoman generator doesn't work

I'm developing my own generator with Yeoman. When I try to copy some files, nothing happens. No error, the process continues until it reach the end, but no files are copied. The generator has a /templates dir with a bunch of html files, each file has a few html lines, at the moment quite simple stuff.
This is my copy method:
copyMainFiles: function(){
console.log('copyMainFiles dir:' + process.cwd() + '+++++');
console.log('file exists? '+fs.existsSync('_footer.html') );
this.copy("_footer.html", "app/footer.html");
console.log('footer copied');
this.copy("_gruntfile.js", "Gruntfile.js");
console.log('gruntfile copied');
this.copy("_package.json", "package.json");
console.log('package copied');
this.copy("_main.css", "app/css/main.css");
console.log('main.css copied');
var context = {
site_name: this.appName
};
console.log('all files copied');
//template method makes the replacement and then copy
this.template("_header.html", "app/header.html", context);
console.log('header template processed');
},
this is the console output:
$ yo trx
method 1 just ran
method 2 just ran
? What is your app's name ?
Kosheen
? Would you like to generate a demo section ? Yes
all dirs created
copyMainFiles dir:C:\cygwin\Applications\MAMP\htdocs\prueba-trx+++++
file exists? false
footer copied
gruntfile copied
package copied
main.css copied
all files copied
header template processed
running npm
and that's it. Never returns to system prompt.
Besides the fact that fs.existsSync returns false (the file exists: htdocs\generator-trx\generators\app\templates_footer.html ), if I try to copy a non-existent file I get the typical error.
Folders are created previously with no issue. There's a .yo_rc.json file with {} in the root of the destination folder. The Yeoman version is 1.4.8, working on Windows 7.
Is copy() the proper way to do this or is no longer valid? How can I copy a simple file in this scenario?
Beside the fact of I was using deprecated methods, the proper way to achive this task is as follow:
this.fs.copy(
this.templatePath('_bower.json'),
this.destinationPath('bower.json')
);
Not sure what your issue is, but you should read the Yeoman official documentation on how to handle files: http://yeoman.io/authoring/file-system.html
You're using old and deprecated methods.

Node JS Error when copying file across partition. How to resolve this issue? [duplicate]

I'm trying to move a file from one partition to another in a Node.js script. When I used fs.renameSync I received Error: EXDEV, Cross-device link. I'd copy it over and delete the original, but I don't see a command to copy files either. How can this be done?
You need to copy and unlink when moving files across different partitions. Try this,
var fs = require('fs');
//var util = require('util');
var is = fs.createReadStream('source_file');
var os = fs.createWriteStream('destination_file');
is.pipe(os);
is.on('end',function() {
fs.unlinkSync('source_file');
});
/* node.js 0.6 and earlier you can use util.pump:
util.pump(is, os, function() {
fs.unlinkSync('source_file');
});
*/
I know this is already answered, but I ran across a similar problem and ended up with something along the lines of:
require('child_process').spawn('cp', ['-r', source, destination])
What this does is call the command cp ("copy"). Since we're stepping outside of Node.js, this command needs to be supported by your system.
I know it's not the most elegant, but it did what I needed :)
One more solution to the problem.
There's a package called fs.extra written by "coolaj86" on npm.
You use it like so:
npm install fs.extra
fs = require ('fs.extra');
fs.move ('foo.txt', 'bar.txt', function (err) {
if (err) { throw err; }
console.log ("Moved 'foo.txt' to 'bar.txt'");
});
I've read the source code for this thing. It attempts to do a standard fs.rename() then, if it fails, it does a copy and deletes the original using the same util.pump() that #chandru uses.
to import the module and save it to your package.json file
npm install mv --save
then use it like so:
var mv = require('mv');
mv('source_file', 'destination_file', function (err) {
if (err) {
throw err;
}
console.log('file moved successfully');
});
I made a Node.js module that just handles it for you. You don't have to think about whether it's going to be moved within the same partition or not. It's the fastest solution available, as it uses the recent fs.copyFile() Node.js API to copy the file when moving to a different partition/disk.
Just install move-file:
$ npm install move-file
Then use it like this:
const moveFile = require('move-file');
(async () => {
await moveFile(fromPath, toPath);
console.log('File moved');
})();

Traversing directory in Node (Grunt)

Having a strange issue when building a grunt plugin.
Basically, I'd like to use a node_module in my grunt task itself. To do this, I want to traverse a level up, then down into the node modules to call their one file specifically.
Originally, I wanted to do this:
../node_modules/github-changes/bin/index.js
However, I get the following error:
Warning: Command failed: /bin/sh: 1: ../node_modules/github-changes/bin/index.js: not found
Use --force to continue.
So, for now I have a hack on using Node's __dirname variable, but it's not very pretty:
var dirHack = __dirname.replace("/tasks", ""), // Terrible hack, need to fix
ghC = dirHack + '/node_modules/github-changes/bin/index.js';
This works, but I'd love to avoid it.
You can see the line here.
What's missing that's causing that error? Am I missing something here?
If github-changes is a dependency, you can resolve a path to file within the package using ghC = require.resolve('github-changes/bin/index.js').
But you're getting that error because you're trying to run that file as a shell script, which it is not. You need to run it with node. The easiest way to find the path to the node executable is process.execPath. See http://nodejs.org/api/process.html#process_process_execpath
Here is an example:
var exec = require('child_process').exec;
var ghC = require.resolve('github-changes/bin/index.js');
exec(process.execPath + ' ' + ghC, function(error) {});

How do I move file a to a different partition or device in Node.js?

I'm trying to move a file from one partition to another in a Node.js script. When I used fs.renameSync I received Error: EXDEV, Cross-device link. I'd copy it over and delete the original, but I don't see a command to copy files either. How can this be done?
You need to copy and unlink when moving files across different partitions. Try this,
var fs = require('fs');
//var util = require('util');
var is = fs.createReadStream('source_file');
var os = fs.createWriteStream('destination_file');
is.pipe(os);
is.on('end',function() {
fs.unlinkSync('source_file');
});
/* node.js 0.6 and earlier you can use util.pump:
util.pump(is, os, function() {
fs.unlinkSync('source_file');
});
*/
I know this is already answered, but I ran across a similar problem and ended up with something along the lines of:
require('child_process').spawn('cp', ['-r', source, destination])
What this does is call the command cp ("copy"). Since we're stepping outside of Node.js, this command needs to be supported by your system.
I know it's not the most elegant, but it did what I needed :)
One more solution to the problem.
There's a package called fs.extra written by "coolaj86" on npm.
You use it like so:
npm install fs.extra
fs = require ('fs.extra');
fs.move ('foo.txt', 'bar.txt', function (err) {
if (err) { throw err; }
console.log ("Moved 'foo.txt' to 'bar.txt'");
});
I've read the source code for this thing. It attempts to do a standard fs.rename() then, if it fails, it does a copy and deletes the original using the same util.pump() that #chandru uses.
to import the module and save it to your package.json file
npm install mv --save
then use it like so:
var mv = require('mv');
mv('source_file', 'destination_file', function (err) {
if (err) {
throw err;
}
console.log('file moved successfully');
});
I made a Node.js module that just handles it for you. You don't have to think about whether it's going to be moved within the same partition or not. It's the fastest solution available, as it uses the recent fs.copyFile() Node.js API to copy the file when moving to a different partition/disk.
Just install move-file:
$ npm install move-file
Then use it like this:
const moveFile = require('move-file');
(async () => {
await moveFile(fromPath, toPath);
console.log('File moved');
})();

Categories

Resources