grunt is not defined default not found - gruntjs

I want to create yoeman generator for html template project
when i try to launch grunt i ha this error Task 'default not found
grunt build give grunt is not defined
$> grunt
Loading "Gruntfile.js" tasks...ERROR
>> ReferenceError: grunt is not defined
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
Here is my code
var fs = require('fs');
var path = require('path');
var showdown = require('showdown');
var EJS = require('ejs');
var TemplateRender = function(file, destination, source, template) {
this.file = file;
this.destination = destination;
this.source = source;
this.template = template;
this.grunt = grunt;
};
TemplateRender.prototype = {
render: function() {
var file = this._read();
var html = this._convert(file);
var content = this._template(html);
this._write(content);
},
_read: function() {
var filepath = path.join(this.source,this.file);
grunt.file.read(filepath);
},
_convert: function(file) {
return new showdown.convertor().makeHtml(file);
},
_template: function(html) {
var template = this.grunt.file.read(this.template);
return EJS.render(template,{content:html});
},
_write: function() {
this.grunt.file.write(
path.join(this.destination, this.file),
page
);
}
};
'use strict';
module.exports = function(grunt) {
grunt.registerTask('build', function() {
var template = "app/index.ejs",
destination = path.join(process.cwd(),"dist"),
source = path.join(process.cwd(),"posts"),
files = fs.readdirSync(source);
files.forEach(function(file) {
new TemplateRender(file, destination, source, template, grunt).render();
read();
convert();
template();
write();
});
});
};
I need to know how to detect error in grunt and yeoman

At the top of your code, in the TemplateRender function, you have this line: this.grunt = grunt; But you don't actually have an argument by that name. Try this:
// ... (everything the same above here)
// *** Notice the new argument to this constructor function
var TemplateRender = function(file, destination, source, template, grunt) {
this.file = file;
this.destination = destination;
this.source = source;
this.template = template;
this.grunt = grunt;
};
TemplateRender.prototype = {
// ...
_read: function() {
var filepath = path.join(this.source,this.file);
// *** probably needs to be `this.grunt` ?
this.grunt.file.read(filepath);
},
// ...
};
module.exports = function(grunt) {
grunt.registerTask('build', function() {
// ... (mostly the same)
files.forEach(function(file) {
new TemplateRender(file, destination, source, template, grunt).render();
// *** where are these defined? Should they be: this._read(), etc?
this._read();
this._convert();
this._template();
this._write();
});
});
};

Related

Is there a way to get a callback from

I am downloading files to the client using Iron Router.
Router.route('zipfile', {
where: 'server',
path: '/zipfile/:name/:targetName',
action: function() {
var name = this.params.name;
var targetName = this.params.targetName;
var filename = `${ZIP_DIR}/${name}`;
var file = fs.readFileSync(filename);
var headers = {
'Content-type': 'application/zip',
'Content-disposition' : `attachment; filename=${targetName}.zip`,
};
this.response.writeHead(200, headers);
return this.response.end(file);
}
});
I wanted to know when the download has completed so I can then delete the source file on the server. Is there an easy way of doing that?
You could use the onAfterAction hook
Router.onAfterAction(function(req, res, next) {
// in here next() is equivalent to this.next();
}, {
only: ['zipfile'],
where: 'server
});

Gulp Watch is not working in gulp 4.0.2 until run gulp again

In my gulfile.js, I'm using watch to compile scss files to css files. It runs without error and when I run gulp in powershell, it says that it is watching, but whenever I define a style in my scss file, it doesn't affect the css file which is created and I have to stop gulp and run it again. Actually, it's not watching carefully !
Here is my code.
Thanks for any help.
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
task("compile_scss", function() {
gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
});
task("watch_scss", function() {
gulp.watch(SCSS_SRC, series(["compile_scss"]));
});
task("default", series("watch_scss"));
You missed a return. The gulp doesn't know the task has completed. In your case you have to return the stream. Here is how your code should be:
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
function compile_scss() {
return gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
function watch_scss() {
gulp.watch(SCSS_SRC, series(compile_scss));
}
exports.default = series(watch_scss);
I also took the liberty of removing the "task()"s since
Reminder: This API isn't the recommended pattern anymore - export your tasks.
as said here.
For the problem be solved, as #Gabriel mentioned and according this link, I changed my code to this and the problem solved. But when I ran npm start, the watch stopped working; Therefore, I installed "concurrently" through npm and changed my start in package.json as mentioned here:
npm install concurrently
"start": "concurrently \"react-scripts start \" \"gulp \"",
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
function compile_scss() {
return gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
function watch_scss() {
gulp.watch(SCSS_SRC, series(compile_scss));
}
exports.default = series(watch_scss);

What is wrong with my download of a zip file from an ASP ApiController with AngularJS?

I'm trying to do the following:
The user fill a form and send it in .JSON to the server
With the form, the server generate some .CSV files and put them all together in a .ZIP file.
The server send the .ZIP file and the user download it.
After some research I have wrote this code:
My Controller:
[HttpPost]
[Route("routeToMyAPI")]
public HttpResponseMessage Process(Form form)
{
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(<streamToMyGeneratedZipFile>)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "fileName.zip"
};
return result;
}
My Service:
angular.module('app')
.factory('MyService', function ($http) {
return {
Process: function (form) {
var req = $http.post('rest/example/process', form);
return req;
}
};
});
My Controller:
this.submit = function () {
var Form = {};
var formPost = MyService.Process(Form);
formPost.then(function (data) {
var a = document.createElement('a');
var blob = new Blob([data], { 'type': "application/octet-stream" });
a.href = URL.createObjectURL(blob);
a.download = "fileName.zip";
a.click();
}, function (error) {
alert('An error occured !');
});
};
I have parts 1 & 2 working, but I don't have find the way to call my ASP API to download the .ZIP file.
When I call the submit method of my Controller, I have a fileName.zip who is downloaded on my PC but when I try to open it Windows says to me that it's not a valid archive.
What did I do wrong ? I'm a rookie in angularjs and ASP so any help will be welcomed.
Thanks in advance.
Several issues with your code:
After ZipArchive does its work, the position of the stream will be at the end. So you must reset it to the beginning like this before sending it:
zipStream.Position = 0;
Since you're setting the content type and file name of the file on the server already, just parse it on the client side.
var headers = data.headers(); //$http resolves to data, status, headers, config
var regex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var match = regex.exec(headers["content-disposition"]);
var fileName = match[1] || "myZipFile.zip";
fileName = fileName.replace(/\"/g, ""); //replace trailing and leading slashes
var contentType = headers["content-type"] || "application/octet-stream";
IE will not allow you to open blobs directly. You must use msSaveOrOpenBlob or msSaveBlob.
var blob = new Blob([data.data], { type: contentType });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var a = document.createElement('a');
var objectUrl = URL.createObjectURL(blob);
a.href = URL.createObjectURL(blob);
a.download = match[1];
a.click();
}
One last thing: the previous code won't work on firefox because firefox doesn't support clic(). Thanks to this thread this can be solved by adding this little snippet of code:
HTMLElement.prototype.click = function() {
var evt = this.ownerDocument.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
this.dispatchEvent(evt);
}

Compile Less with Gulp - include variables

im working on a wordpress theme with less and gulp. Since i need to adjust some default paths and values for bootstrap + fontaweseome i have a less file with my custom vars (overwrite.less). but it doesnt affect the variables at all.
Less files get injected via mainBowerFiles, the docs say less vars support lazy load. (http://lesscss.org/features/#variables-feature-lazy-loading)
files get cached to speed up the build ( < 10 ms) but even without - no effect.
gulpfile.js:
'use strict';
var gulp = require('gulp');
var less = require('gulp-less');
var browserSync = require('browser-sync').create();
var util = require('gulp-util');
var sourceMaps = require('gulp-sourcemaps');
var del = require('del');
var cache = require('gulp-cached');
var remember = require('gulp-remember');
var concat = require('gulp-concat');
var minifyCss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var mainBowerFiles = require('main-bower-files');
var paths = {
target: '../vagrant/www/wordpress/wp-content/themes/themename',
bowerJs: mainBowerFiles('**/*.js'),
bowerLess: mainBowerFiles('**/*.less'),
lessFiles: ['overwrite.less','less/**.less'],
jsFiles: ['js/**.js']
};
var allLess = paths.bowerLess.concat(paths.lessFiles);
var allJs = paths.bowerJs.concat(paths.jsFiles);
function compileLess() {
var s = gulp.src(allLess);
s = s.pipe(sourceMaps.init());
s = s.pipe(cache('less'));
s = s.pipe(less());
s = s.pipe(remember('less'));
s = s.pipe(minifyCss());
s = s.pipe(concat('style.css'));
s = s.pipe(sourceMaps.write('maps/'));
return s.pipe(gulp.dest(paths.target));
}
function compileJs() {
var s = gulp.src(allJs);
s = s.pipe(sourceMaps.init());
s = s.pipe(cache('js'));
s = s.pipe(uglify());
s = s.pipe(remember('js'));
s = s.pipe(concat('app.js'));
s = s.pipe(sourceMaps.write('maps/'));
return s.pipe(gulp.dest(paths.target));
}
gulp.task('move', function() {
var filesToMove = ['./*.php', './assets/**', 'bower_components/**', './partial/**'];
gulp.src(filesToMove, { base: './' })
.pipe(gulp.dest('../vagrant/www/wordpress/wp-content/themes/codecampus')).once('end', function () {
browserSync.reload();
});
});
gulp.task('browser-sync', function() {
browserSync.init([], {
proxy: "http://vccw.dev/"
});
});
gulp.task('watch', function () {
gulp.watch('less/**/*.less', ['less']);
gulp.watch('js/**/*.js', ['js']);
gulp.watch(['./*.php', './assets/**', './partial/**'], ['move'])
});
gulp.task('less', function () {
util.log('Compile less ...');
browserSync.reload();
return compileLess();
});
gulp.task('js', function () {
util.log('Compile js ...');
browserSync.reload();
return compileJs();
});
gulp.task('clean', function (cb) {
util.log('Delete old less ...');
del([paths.target + '**/*'], {force: true}, cb);
});
//define tasks
gulp.task('default', [ 'clean', 'less', 'js' , 'move', 'watch', 'browser-sync'], function () {
return util.log('Gulp is running!');
});
Solution 1:
Splitting up the bower-less-files plus overwrite and your custom styles. so that you have 2 less tasks.
Solution 2:
Keep anything in one Task and inject modifyVars into your less task
s = s.pipe(less({
modifyVars: {
"fa-font-path" : '"../custom/path/"',
...
}
}));

How to access FS collections metadata in meteor

My question is solved:
It missed this line of code before the insert code:
var fileObj = new FS.File(file);
How to access FS collections metadata in meteor?
I tried: var result = Images.find({"metadata.gallery._id":curgallery})
(curgallery is the _id of a gallery object)
Here is my code:
helper:
images: function () {
if (Session.get('gallery')) {
var curgallery = Session.get('gallery')._id;
var result = Images.find({"metadata.gallery._id":curgallery})
console.log(result.fetch());//return an empty array
return result;
};
events:
//INSERT IMAGE
'change .fileInput': function(event, template) {
if (Session.get('gallery')) {
var collection = Session.get('gallery');
FS.Utility.eachFile(event, function(file) {
file.metadata = {owner: Meteor.user()._id,gallery:collection};
Images.insert(file, function (err, fileObj) { } );
console.log(file.metadata.gallery._id);//return the _id's gallery
});
};
},

Resources