Write output file from gulp task using through - javascript

I am new to gulp and JS in general. But I have this gulp file that uses protagonist to validate a file. The task was written by someone else and it works correctly. Now I need the output of Protagonist to build a file from the parsed structure but I can't understand where in the script should I get it. Also the package through makes things harder for me to understand.
What would I need to do in order to write the result of the function protagonist.parse() to a file from within gulp.
Gulp file
var through = require('through2');
var protagonist = require('protagonist');
gulp.task('protagonist', function () {
gulp.src(paths.build_blueprint)
.pipe(gulpProtagonist({type: 'ast'}))
.on('error', gutil.log);
});
function gulpProtagonist(options) {
return through.obj(function (file, enc, cb) {
protagonist.parse(file.contents.toString(), {type: options.type}, function (error, result) {
if (error) {
return cb(new PluginError('gulp-protagonist', error));
}
try {
if (result['warnings'].length > 0) {
var msgs = result['warnings'].map(buildWarningMsg);
var args = ['error'].concat(msgs.map(genError));
self.emit.apply(self, args);
}
cb(null, file);
} catch (e) {
cb(new PluginError('gulp-protagonist', e));
}
});
});
}

Related

rimraf Error: invalid rimraf options. Unable to delete files automatically

I have an issue of multer depositing some files after it has been uploaded to cloudinay. I then found a post In Node, delete all files older than an hour? that introduced me to rimraf. I have not been able to implement it and this is the error I have from the console
Please have a look at the code, the error is line 16 from the stack trace which is => return rimraf(path.join(uploadsDir, file), function (err)
const rimraf = require("rimraf");
const path = require("path");
const fs = require("fs");
var uploadsDir = path.normalize(__dirname + "/public/images");
fs.readdir(uploadsDir, function (err, files) {
files.forEach(function (file, index) {
fs.stat(path.join(uploadsDir, file), function (err, stat) {
var endTime, now;
if (err) {
return console.error(err);
}
now = new Date().getTime();
endTime = new Date(stat.ctime).getTime() + 3600000;
if (now > endTime) {
return rimraf(path.join(uploadsDir, file), function (err) {
if (err) {
return console.error(err);
}
console.log("successfully deleted");
});
}
});
});
});
I am quiet amazed because I can't find the issue and not one has reported my experience. Please help
from the documentation, it seems the second parameter( if you are using version 4) that should be passed to the function is the options object, while you are passing a function, check this URL

Can't writeFile to the dist folder using Promise, catch and gulp

I'm mapping an index.html file to scrape the tag content and save as a file called fonts.css
This is my style:
<style>#font-face{font-family:Averti;src:url(https://services.serving-sys.com/HostingServices/custdev/site-140253/Averti/Averti-Bold.woff) format('truetype');font-weight:700;font-style:normal}#font-face{font-family:Averti-Light;src:url(https://services.serving-sys.com/HostingServices/custdev/site-140253/Averti_Webfonts/Averti-Light.woff) format('truetype');font-weight:400;font-style:normal}</style>
There is no major errors with the function, but the console.log is showing me that
{ [Error: ENOENT: no such file or directory, open './dist/css/fonts.css']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: './dist/css/fonts.css' }
I'm not sure if that is right as the file is not even created yet.
See my function below and let me know what I am missing.
Thank you in advance.
async function createStyle(){
var jsonObject = []
setTimeout(function(){
fs.readFile('./dist/index.html', 'utf8', function(err, html){
if (!err){
const $ = cheerio.load(html)
var cssScript = $('head > style').map(( i, x ) => x.children[0])
.filter(( i, x ) => x && x.data.match(/#font-face/)).get(0);
jsonObject.push(cssScript)
exportStyle(jsonObject)
}
})}, 2000);
async function exportStyle(_json) {
const stylePromise = new Promise(function(resolve, reject) {
fs.writeFile('./dist/css/fonts.css', _json, err => {
if (err) {
reject();
} else {
resolve();
console.log('Created: fonts.css');
}
console.log(err);
});
});
(async function() {
try {
await stylePromise;
} catch(err) {
console.log(err);
}
})();}}
I created the css and js folder inside the ./dist folder and the code worked like a charm. Other than that, the error message appears in the console.

Error: ENOENT: no such file or directory, uv_chdir at process.chdir when creating a directory and changing into it

I'm trying to write a small app that installs some files and modules in a new folder, but I keep getting this error:
{ Error: ENOENT: no such file or directory, uv_chdir
at process.chdir (/home/aboardwithabag/LaunchProject/node_modules/graceful-fs/polyfills.js:20:9)
at cd (/home/aboardwithabag/LaunchProject/index.js:26:13)
Below is my code. Can someone help me out?
// node LaunchProject projectName
// Installs a server, node modules, and index page.
// not working due to issues with chdir.
const cp = require('child_process');
const fse = require('fs-extra');
// const path = require('path');
const project = process.argv[2];
let server ="";
let home = "";
function make (cb){
fse.mkdirs(project, function(err){
if (err){
console.error(err);
}
});
cb;
}
function cd(cb){
try{
process.chdir('/'+project);
cb;
} catch (err) {
console.error(err);
return;
}}
function install(cb){
cp.exec('npm install express', function(err){
if (err){
console.error(err);
} else {
console.log('Express Installed.');
cp.exec('npm install ejs', function(err){
if (err){
console.error(err);
} else{
console.log('Ejs Installed.');
fse.outputFile('index.js', server);
fse.outputFile('public/index.html', home);
}});
}
});
cb;
}
make(cd(install(console.log(project + ' created.'))));
unless the folder name you assign to the project variable (in this case it seems to be "uv_chdir") is located at the root folder of your HDD, below line will give the error:
process.chdir('/'+project);
make sure you give correct path to the program arguments. (in this case argv[2])
Or you may remove the leading '/' and make the path relative.
It seems there are some issues with this code.
cb callbacks provided as function arguments need to be called not after the async calls, but inside the callbacks of these calls. For example:
function make (cb){
fse.mkdirs(project, function(err){
if (err){
console.error(err);
}
cb();
});
}
The last call chain make(cd(install(console.log(project + ' created.')))); would work only with sync calls in reversed order and only if they returned needed callbacks.
That is why your new dir is not ready when you try to use it: your async functions do not actually wait for each other.
You do not call your callbacks as cb(), just mention them as cb. You should call them.
With minimal changess, your code can be refactored in this way:
'use strict';
const cp = require('child_process');
const fse = require('fs-extra');
const project = process.argv[2];
let server = '';
let home = '';
make(cd, install, () => { console.log(project + ' created.'); });
function make(cb1, cb2, cb3) {
fse.mkdirs(project, (err) => {
if (err) {
console.error(err);
}
cb1(cb2, cb3);
});
}
function cd(cb1, cb2) {
try {
process.chdir('/' + project);
cb1(cb2);
} catch (err) {
console.error(err);
}
}
function install(cb1) {
cp.exec('npm install express', (err) => {
if (err) {
console.error(err);
} else {
console.log('Express Installed.');
cp.exec('npm install ejs', (err) => {
if (err) {
console.error(err);
} else {
console.log('Ejs Installed.');
fse.outputFile('index.js', server);
fse.outputFile('public/index.html', home);
cb1();
}
});
}
});
}
But it is rather brittle and unnecessarily complicated in this form. Maybe it would be simpler to inline your functions each in other.
when I use PM2,i got this error "no such file or directory, uv_chdir"
the resolvent is :
first,I use 'pm2 delete' to delete old process
second,I use 'pm2 start',then ok
ps : just change your code or use 'pm2 reload' or 'pm2 restart' would not be ok.
more detail , you can see "https://blog.csdn.net/u013934914/article/details/51145134"

How to write multiple strings into a file in protractor(js)

I am using protractor cucumber framework.I need to write some data into a file and read that data also.But it is not working as expected.The code i have tried is given below.
const fs = require('fs');
After(function(){
var content = ["kerala","asam"];
var str=content.toString();
var content1 = ["india","usa","uk"];
var str1=content1.toString();
if(str){
fs.writeFile('test.txt', str, (err) => {
if (err) {
console.error(err);
return
}
});
}
if(str1){
fs.writeFile('test.txt', str1, (err) => {
if (err) {
console.error(err);
return
}
});
}
});
AfterAll(function(callback){
console.log("afterall");
fs.readFile('test.txt', 'utf-8', function(err, buf) {
console.log(buf.toString());
});
callback();
});
some time the arrays may be empty(depending on the test execution).so if the array having data, i need to write that data into a file and read also.But the after writing into the file the, the file having data as given below
india,usa,uk
it should be
kerala,asam
india,usa,uk
How can i do this .Thanks in advance.

How can I write a simple gulp pipe function?

I've been trying for a day to write two pipe functions, one that compiles less files and another one that concats these files. I want to learn how to write transform streams/pipes for more complex plugins.
So I want to know how to read data from another pipe, and how to alter that data and send it to the next pipe. This is what I have so far:
gulp.src(sources)
.pipe(through.obj(function (chunk, enc, cb) {
var t = this;
// console.log("chunk", chunk.path);
fs.readFile(chunk.path, enc, function (err,data) {
if (err) { cb(err); }
less.render(data, {
filename : chunk.path,
sourceMap : {
sourceMapRootpath : true
}
})
.then(function (outputCss) {
// console.log("less result",outputCss);
t.push(chunk);// or this.push(outputCss) same result
cb();
});
});
}))
.pipe(through.obj(function (chunk, enc, cb) {
console.log("chunk", chunk.path); // not event getting called.
cb();
}))
I can't get the outputCSS for each file in the second pipe. How can I send it?
Well, you don't need to use fs here, you already got the stream of file (here your chunk).
Another point, you're not sending back to the pipe the files, so I guess that's why nothing is called on your second one.
const through = require('through2')
gulp.src(sources)
.pipe(through.obj((chunk, enc, cb) => {
console.log('chunk', chunk.path) // this should log now
cb(null, chunk)
}))
In ES2015:
import through from 'through2'
gulp.src(sources)
.pipe(through.obj((chunk, enc, cb) => cb(null, chunk)))
And for your specific example:
.pipe(through.obj((file, enc, cb) => {
less.render(file.contents, { filename: file.path, ... }) // add other options
.then((res) => {
file.contents = new Buffer(res.css)
cb(null, file)
})
}))
This is still pretty basic, I don't check for errors, if it's not a stream and so on, but this should give you some hint on what you've missed.

Categories

Resources