gulp-task output in console is not printing expected result - javascript

I have the following gulp task which inserts .css and .js files in the html file:
gulp.task('inject', function () {
log('Injecting the JS and CSS files into index.html');
var wiredep = require('wiredep').stream;
var options = config.getWiredepDefaultOptions();
return gulp.src(config.index)
.pipe(wiredep(options))
.pipe($.inject(gulp.src(config.customFiles), {ignorePath: options.ignorePath}))
.pipe(gulp.dest(config.client));
});
and my gulp.config.js:
module.exports = function () {
var client = './public';
var config = {
allJS: [
'*.js',
'public/js/*.js',
'public/js/**/*.js'
],
client: client,
index: client + '/index.html',
customFiles: [
'./public/css/*.css',
'./public/js/*.js',
'./public/js/**/*.js'
],
bower: {
json: require('./bower.json'),
directory: './public/lib',
ignorePath: '/public/'
},
};
config.getWiredepDefaultOptions = function () {
var options = {
bowerJson: config.bower.json,
directory: config.bower.directory,
ignorePath: config.bower.ignorePath
};
return options;
};
return config;
};
This works as expected, but when I run the task I get this:
It always says gulp-inject 3 files into index.html, even though no new files was added.
Is there something wrong with my gulp file?

Well if you are using gulp-inject this is what I found.
If you look at the code in gulp-inject you can see it just spits out the file count unless it gets opt.quiet set. I didn't see a option in the docs for this setting but if you look at the tests it shows an example it being used.
Enabling quiet mode link line 505
inject(sources, {quiet: true});
Source where it generates the log statement. link line 109
function getNewContent(target, collection, opt) {
var logger = opt.quiet ? noop : function (filesCount) {
if (filesCount) {
log(cyan(filesCount) + ' files into ' + magenta(target.relative) + '.');
} else {
log('Nothing to inject into ' + magenta(target.relative) + '.');
}
};

Related

How can I add to a data array from multiple files?

I've got a folder structure that looks like this:
.
├── Gruntfile.js
└── src
└── assets
└── blocks
└── content.js
└── buttons
└── buttons1.js
└── buttons2.js
└── images
└── images.js
Within my content.js file there is an empty array:
var data = {
'snippets': []
};
And within each of the files i.e buttons1.js buttons2.js and images.js there is an array, example:
var snippet = [
{
'thumbnail': 'preview/button-01.png',
'category': '119',
'html':
'<div>' +
'Read More ' +
'\nBuy Now' +
'</div>'
}
]
Is there a way with Grunt (or any other process runner) to loop through all the .js files within the folder and read the value of the snippet array and then add it to the snippets in the content.js file?
So I'd end up with an array that looks like this (plus any other from the other files appended)
var data = {
'snippets': [
{
'thumbnail': 'preview/button-01.png',
'category': '119',
'html':
'<div>' +
'Read More ' +
'\nBuy Now' +
'</div>'
}
]
};
I tried out the grunt-contrib-concat with the following configuration which simply creates a file with multiple snippet variables, not sure if there is a way to amend how it concats? Or if there is a different plugin available
concat: {
options: {
separator: ';',
},
dist: {
src: 'src/assets/blocks/*/*.js',
dest: 'src/assets/blocks/content.js',
},
},
In HTML (add paths):
<script src="content.js"></script> // we get data == { 'snippets': [] }
<script src="buttons1.js"></script> // we get snippet == [...]
<script>data.snippets.push(snippet);</script>
<script src="buttons2.js"></script> // we get snippet == [...]
<script>data.snippets.push(snippet);</script>
<script src="buttons3.js"></script> // we get snippet == [...]
<script>data.snippets.push(snippet);</script>
// we have each snippet in snippets
Basically, we load the container (data), then we load the buttons one by one, adding their snippet to data's snippets.
Addendum: How about dynamically adding scripts?
dataScript=document.body.createElement("script");
dataScript.src="content.js";
document.body.append(dataScript);
buttonSrcs=["buttons1.js", "buttons2.js", "buttons3.js"]; // etc...
for(buttonSrc of buttonSrcs) {
buttonScript=document.body.createElement("script");
buttonScript.src=buttonSrc;
document.body.append(buttonScript);
data.snippets.push(snippet);
};
I've typed from memory and I hope I got the spellings right...
I ended up writing a custom task for Grunt which does what I want it to
merge_blocks: {
build: {
src: 'src/assets/blocks/*/*.js',
dest: 'src/assets/blocks/content.js'
}
}
grunt.registerMultiTask('merge_blocks', 'Merge blocks', function () {
const fs = require('fs');
grunt.log.write('[Block Merge] Loaded dependencies...').ok();
// This is the main array
var data_basic = {
'snippets': []
};
this.files.forEach(function (file) {
grunt.log.writeln('Processing ' + file.src.length + ' files.');
//file.src is the list of all matching file names.
file.src.forEach(function (f) {
var data = require('./' + f);
data_basic.snippets.push(...data);
data = null;
});
grunt.log.writeln('Now saving file:' + file.dest);
fs.appendFileSync(file.dest, 'var data_basic = ' + JSON.stringify(data_basic, null, ' '));
});
});

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. C#

I'm trying to use the $.getJSON() function in javascript but I get this error:
"You may need an appropriate loader to handle this file type,
currently no loaders are configured to process this file."
Here's my javascript:
$(document).ready(function () {
console.log("Hello from riskanalysis.delete.js");
var categoryTd = $('#categoryId');
var categoryText = categoryTd.text();
var categoryInt = parseInt(categoryText);
console.log(categoryInt);
console.log(categoryText);
// Send an AJAX request
$.getJSON("/riskanalysis/getCategoryNameById?id=" + categoryInt)
console.log("Hello before");
.done(function (categoryName) {
// On success
console.log("Category name is: " + categoryName);
categoryTd.text(categoryName);
});
console.log("Hello after");
});
Here's my webpack.config.js file:
module.exports = {
entry:
{
shared: './src/shared.js',
home: './src/home/home.js',
riskanalysisSearch: './src/riskanalysis/riskanalysis.search.js',
riskanalysisCreate: './src/riskanalysis/riskanalysis.create.js',
riskanalysisDelete: './src/riskanalysis/riskanalysis.delete.js',
dropdown: './src/dropdown/dropdown.js',
actionplan: './src/actionplan/actionplan.js'
},
output: {
filename: '../wwwroot/js/[name].js'
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/](jquery)[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
}
};
Here's the error:
The weird thing is that in all my other javascript files it is working perfectly.
Does anyone have an idea what could be wrong? Thanks already!
The cause of the error is the line console.log("Hello before");, move this line above $.getJSON("/riskanalysis/getCategoryNameById?id=" + categoryInt) so that it looks like this:
console.log("Hello before");
$.getJSON("/riskanalysis/getCategoryNameById?id=" + categoryInt)
.done(function (categoryName) {
// On success
console.log("Category name is: " + categoryName);
categoryTd.text(categoryName);
});
console.log("Hello after");
The line that shows this error is: Module parse failed: Unexpected token (13:12)
Regarding the error You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. this is because the full file extension for this file is .delete.js which makes webpack think that this isn't a normal .js file. Webpack will try to find a file loader for .delete.js files, as one doesn't exist it will fall back to the .js file loader. Due to the above error the js parser will fail resulting in this error.

Can Some give an elaborate example of using Custom Jasmine Reporter for protractor. I am unable to understand Tutorial

Can Some give an elaborate example of using Custom Jasmine Reporter . I would like someone to help me with a sample test with two assertions . how to add the reporter in protractor conf.js and how it can help me . No where in the internet there is a example apart from just the reference .
check the one I use:
First check if all the necessary dependencies are installed (check the begin of the code)
Then copy+paste this to you Conf.js:
//In my case I installed the dependencies locally thats why comes from lib folder
var jasmineReporters = require('./lib/node_modules/jasmine-reporters');
var HTMLReport = require('./lib/node_modules/protractor-html-reporter-2');
var fs = require('./lib/node_modules/fs-extra');
onPrepare: function () {
fs.emptyDir('./Execution_Results/reports/xml/', function (err) {
if (err != ""){
console.log(err);
}
});
fs.emptyDir('./Execution_Results/reports/results/screenshots', function (err) {
if (err != ""){
console.log(err);
}
});
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: './Execution_Results/reports/xml/',
filePrefix: 'xmlresults'
}));
jasmine.getEnv().addReporter({
specDone: function (result) {
//if (result.status == 'failed') {
browser.getCapabilities().then(function (caps)
{
var browserName = caps.get('browserName');
browser.takeScreenshot().then(function (png) {
var stream = fs.createWriteStream('./Execution_Results/reports/results/screenshots/' + browserName + '-' + result.fullName + '.png');
stream.write(new Buffer(png, 'base64'));
stream.end();
});
});
//}
}
});
},
//HTMLReport called once tests are finished
onComplete: function() {
var browserName, browserVersion;
var capsPromise = browser.getCapabilities();
capsPromise.then(function (caps) {
browserName = caps.get('browserName');
browserVersion = caps.get('version');
platform = caps.get('platform');
testConfig = {
reportTitle: 'Protractor Test Execution Report',
outputPath: './',
outputFilename: 'Execution_Results/reports/results/IV2_Test_Results',
screenshotPath: './screenshots/',
testBrowser: browserName,
browserVersion: browserVersion,
modifiedSuiteName: false,
screenshotsOnlyOnFailure: true,
testPlatform: platform
};
new HTMLReport().from('./Execution_Results/reports/xml/xmlresults.xml', testConfig);
});
},
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
// If true, display spec names.
isVerbose: true,
},
the folders will be created automatically inside the folder where your conf.js is located so after the execution just access the 'Execution_Results/reports' and open the html report
OnPrepare will generate the xml file with all the results
OnComplete will transform the xml into html report
I'm using this reporter, Just follow the steps from this link to set the conf.js https://www.npmjs.com/package/protractor-jasmine2-screenshot-reporter

grunt load dynamic JSON file

Is it possible to load a JSON file from a dynamic source? I want to do some localisation
grunt.file.readJSON('src/locales/<%= grunt.task.current.args[0] %>/i18n.json');
A fuller example of the Gruntfile looks like:
module.exports = function(grunt) {
var i18n = {
locales: ['en', 'fr', 'de', 'es'],
default: 'en',
replacements: function(locale){
var content = grunt.file.readJSON('src/locales/<%= grunt.task.current.args[0] %>/i18n.json');
var arr = [];
for(i in content){
var replacement = {
from: i,
to: content[i].value
};
arr.push(replacement);
}
return arr;
}
};
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
replace: {
build: {
src: ['local/en/**/*.html'], // source files array (supports minimatch)
dest: 'local/<%= grunt.task.current.args[0] %>/', // destination directory or file
replacements: i18n.replacements('<%= grunt.task.current.args[0] %>')
}
},
While registering the task looks like:
grunt.registerTask('localise', function(){
var tasks = [];
for(i in i18n.locales){
if(i18n.locales[i] !== i18n.default){
tasks.push('replace:build:' + i18n.locales[i]);
}
}
grunt.task.run(tasks);
});
Everything works as I'd hoped except loading the JSON to actually do the replacements.
I've also tried:
grunt.file.readJSON('src/locales/'+locale+'/i18n.json');
which didn't work either, leaving me a little stumped.
Anyone able to help?
Thanks
Try:
'src/locales/' + grunt.task.current.args[0] + '/i18n.json'
Ok, I got it working after much trial and error:
I updated the function returning the data to:
var i18n = {
locales: ['en', 'fr', 'de', 'es'],
default: 'en',
replacements: function(locale){
var content = grunt.file.readJSON('src/locales/'+ locale +'/i18n.json');
var arr = [{from: "/" + locale, to: "/en"}, {from: "Test", to: locale}];
for(i in content){
var replacement = {
from: i,
to: content[i].value
};
arr.push(replacement);
}
console.log(arr);
return arr;
}
};
Then set an empty array in the default task:
replace: {
build: {
src: ['local/en/**/*.html'], // source files array (supports minimatch)
dest: 'local/<%= grunt.task.current.args[0] %>/', // destination directory or file
replacements: []
}
},
Which is updated using it's own task
grunt.registerTask('updateConf', function(locale){
var content = i18n.replacements(locale);
grunt.config('replace.build.replacements', content);
});
That is run just before the replace task:
grunt.registerTask('localise', function(){
var tasks = [];
for(i in i18n.locales){
if(i18n.locales[i] !== i18n.default){
tasks.push('updateConf:' + i18n.locales[i]);
tasks.push('replace:build:' + i18n.locales[i]);
}
}
grunt.task.run(tasks);
});
Giving the right output. Probably not the most elegant of solutions but it works!

Can I use a Gulp task with multiple sources and multiple destinations?

I have the following in my gulpfile.js:
var sass_paths = [
'./httpdocs-site1/media/sass/**/*.scss',
'./httpdocs-site2/media/sass/**/*.scss',
'./httpdocs-site3/media/sass/**/*.scss'
];
gulp.task('sass', function() {
return gulp.src(sass_paths)
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest(???));
});
I'm wanting to output my minified css files to the following paths:
./httpdocs-site1/media/css
./httpdocs-site2/media/css
./httpdocs-site3/media/css
Am I misunderstanding how to use sources/destinations? Or am I trying to accomplish too much in a single task?
Edit: Updated output paths to corresponding site directories.
I guess that the running tasks per folder recipe may help.
Update
Following the ideas in the recipe, and oversimplifying your sample just to give the idea, this can be a solution:
var gulp = require('gulp'),
path = require('path'),
merge = require('merge-stream');
var folders = ['httpdocs-site1', 'httpdocs-site2', 'httpdocs-site3'];
gulp.task('default', function(){
var tasks = folders.map(function(element){
return gulp.src(element + '/media/sass/**/*.scss', {base: element + '/media/sass'})
// ... other steps ...
.pipe(gulp.dest(element + '/media/css'));
});
return merge(tasks);
});
you are going to want to use merge streams if you would like to use multiple srcs but you can have multiple destinations inside of the same one. Here is an example.
var merge = require('merge-stream');
gulp.task('sass', function() {
var firstPath = gulp.src(sass_paths[0])
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('./httpdocs-site1/media/css'))
.pipe(gulp.dest('./httpdocs-site2/media/css'));
var secondPath = gulp.src(sass_paths[1])
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('./httpdocs-site1/media/css'))
.pipe(gulp.dest('./httpdocs-site2/media/css'));
return merge(firstPath, secondPath);
});
I assumed you wanted different paths piped here so there is site1 and site2, but you can do this to as many places as needed. Also you can specify a dest prior to any of the steps if, for example, you wanted to have one dest that had the .min file and one that didn't.
You can use gulp-rename to modify where files will be written.
gulp.task('sass', function() {
return gulp.src(sass_paths, { base: '.' })
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename(function(path) {
path.dirname = path.dirname.replace('/sass', '/css');
path.extname = '.min.css';
}))
.pipe(gulp.dest('.'));
});
Important bit: use base option in gulp.src.
For the ones that ask themselves how can they deal with common/specifics css files (works the same for scripts), here is a possible output to tackle this problem :
var gulp = require('gulp');
var concat = require('gulp-concat');
var css = require('gulp-clean-css');
var sheets = [
{ src : 'public/css/home/*', name : 'home.min', dest : 'public/css/compressed' },
{ src : 'public/css/about/*', name : 'about.min', dest : 'public/css/compressed' }
];
var common = {
'materialize' : 'public/assets/materialize/css/materialize.css'
};
gulp.task('css', function() {
sheets.map(function(file) {
return gulp.src([
common.materialize,
file.src + '.css',
file.src + '.scss',
file.src + '.less'
])
.pipe( concat(file.name + '.css') )
.pipe( css() )
.pipe( gulp.dest(file.dest) )
});
});
All you have to do now is to add your sheets as the object notation is constructed.
If you have additionnal commons scripts, you can map them by name on the object common, then add them after materialize for this example, but before the file.src + '.css' as you may want to override the common files with your customs files.
Note that in the src attribute you can also put path like this :
'public/css/**/*.css'
to scope an entire descendence.
I had success without needing anything extra, a solution very similar to Anwar Nairi's
const p = {
dashboard: {
css: {
orig: ['public/dashboard/scss/style.scss', 'public/dashboard/styles/*.css'],
dest: 'public/dashboard/css/',
},
},
public: {
css: {
orig: ['public/styles/custom.scss', 'public/styles/*.css'],
dest: 'public/css/',
},
js: {
orig: ['public/javascript/*.js'],
dest: 'public/js/',
},
},
};
gulp.task('default', function(done) {
Object.keys(p).forEach(val => {
// 'val' will go two rounds, as 'dashboard' and as 'public'
return gulp
.src(p[val].css.orig)
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(autoPrefixer())
.pipe(cssComb())
.pipe(cmq({ log: true }))
.pipe(concat('main.css'))
.pipe(cleanCss())
.pipe(sourcemaps.write())
.pipe(gulp.dest(p[val].css.dest))
.pipe(reload({ stream: true }));
});
done(); // <-- to avoid async problems using gulp 4
});
Multiple sources with multiple destinations on gulp without using any extra plugins just doing concatenation on each js and css. Below code works for me. Please try it out.
const gulp = require('gulp');
const concat = require('gulp-concat');
function task(done) {
var theme = {
minifiedCss: {
common: {
src : ['./app/css/**/*.min.css', '!./app/css/semantic.min.css'],
name : 'minified-bundle.css',
dest : './web/bundles/css/'
}
},
themeCss:{
common: {
src : ['./app/css/style.css', './app/css/responsive.css'],
name : 'theme-bundle.css',
dest : './web/bundles/css/'
}
},
themeJs: {
common: {
src: ['./app/js/jquery-2.1.1.js', './app/js/bootstrap.js'],
name: 'theme-bundle.js',
dest: './web/_themes/js/'
}
}
}
Object.keys(theme).map(function(key, index) {
return gulp.src(theme[key].common.src)
.pipe( concat(theme[key].common.name) )
.pipe(gulp.dest(theme[key].common.dest));
});
done();
}
exports.task = task;
Using gulp-if helps me a lot.
The gulp-if first argument. is the gulp-match second argument condition
gulp-if can be found in gulp-if
import {task, src, dest} from 'gulp';
import VinylFile = require("vinyl");
const gulpif = require('gulp-if');
src(['foo/*/**/*.md', 'bar/*.md'])
.pipe(gulpif((file: VinylFile) => /foo\/$/.test(file.base), dest('dist/docs/overview')))
.pipe(gulpif((file: VinylFile) => /bar\/$/.test(file.base), dest('dist/docs/guides')))
});
I think we should create 1 temporary folder for containing all these files. Then gulp.src point to this folder
The destination will have the same directory structure as the source.

Categories

Resources