I use gulp to run protractor and want one separate task for each browser, Chrome and Firefox. So by running gulp protractor:chrome or gulp protractor:firefox I would launch different browsers. But I get my capabilities through the getMultiCapabilities and it isn't as simple as --capabilites.browserName chrome then. This is how my getMultiCapabilities-function looks like for Firefox:
'use strict';
var FirefoxProfile = require('firefox-profile');
var bbPromise = require('bluebird');
exports.getMultiCapabilities = function () {
var deferred = bbPromise.defer();
var firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference('media.navigator.permission.disabled', true);
firefoxProfile.encoded(function (encodedProfile) {
var capabilities = [{
browserName: 'firefox',
firefox_profile : encodedProfile
}];
deferred.resolve(capabilities);
});
return deferred.promise;
};
And I want to use this function by passing it in the command line somehow. I tried just requiring the function in the config file and then doing --getMultiCapabilities firefoxCapabilitiesHelper.getMultiCapabilities. Didn't work. Also tried to "stringify" the function and wrote everything inside it on the command line. Didn't work either. The arguments are ignored.
Is it even possible to do what I want to achieve?
Related
Ok, so I am using the typical image minification process. I have functions for jpg, pngs and I have a separate function to convert those to webp.
I have the following gulpfile (only the relevant parts are here):
function clean(done) {
rimraf(folder.public_img, done);
}
function images() {
return gulp.src([folder.preimages+'/**/*.{gif,png,jpg,svg}'])
.pipe(cache(imagemin([
imageminPngquant({
speed: 1,
quality: [0.95, 1]
}),
imageminZopfli({
more: true
}),
imageminMozjpeg({
quality: 65
}),
])))
.pipe(gulp.dest(folder.public_img));
}
gulp.task('webp', () =>
gulp.src([folder.preimages+'/**/*.{gif,png,jpg}'])
.pipe(webp({
quality: 65,
method: 6
}))
.pipe(gulp.dest(folder.public_img))
);
function serve() {
gulp.watch(folder.preimages+"/**/*.{gif,png,jpg,svg}", images);
gulp.watch(folder.preimages+"/**/*.{gif,png,jpg}", webp);
}
gulp.task('clean', clean);
gulp.task('images', images);
gulp.task('serve', gulp.series('clean', 'images', 'webp', serve));
gulp.task('default', gulp.series('clean', 'images', 'webp', serve));
So, basically when I run gulp the first time, all the processes run fine and the webp images are generated. BUT, if I add a new image, the images() function runs, but for some reason the webp() function doesn't execute, it's as if it doesn't see changes, and I have it configured the same way as images.
I tried two alternatives:
I added the webp process directly inside the images() function, but that way my JPG and PNG files were directly converted to webp and I didn't have fallback images.
I tried to create the webp function with the same format as the others function webp() { ... }, but when I tried to run gulp it showed this error:
The following tasks did not complete: default,
Did you forget to signal async completion?
So I found that I could use the format above gulp.task('webp', () =>... and that works, but doesn't respect the watch function. I think it could be related to the function to name assignation in the end of the file, but I am not that familiar with the syntax.
What should I change so that it watches correctly?
I was able to recreate your code and get it to work as follows:
In creating your gulp tasks, something goofy seems to be happening because you've created a series of tasks to run with your gulp.task('serve'). Instead, you can write out your tasks like this:
gulp.task(clean);
gulp.task(images);
gulp.task(serve);
gulp.task('default', gulp.series(clean, images, webp, serve));
You may want to call your webp function something else - I was getting a conflict because of also importing gulp-webp as const = webp. You also don't need to put quotation marks around the name of the function in the task and then also reference it in the task again. So gulp.task(clean) works just fine. You don't need gulp.task('clean', clean).
You can probably also write your default task as follows:
gulp.task('default', gulp.series(clean, serve);
This had the same effect for me as also including the images and webp tasks in the series. This setup worked for me. Running gulp, it first ran the clean function to remove the public_img folder, then ran images followed by webp. It worked up the initial run as well as when I added a new image to the preimages folder.
Update
Here's the complete gulpfile I got to work:
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const rimraf = require('rimraf');
const webp = require('gulp-webp');
const folder = {
preimages: 'src/images',
public_img: 'src/public_img',
};
function clean(done) {
rimraf(folder.public_img, done);
}
function images() {
return gulp
.src([folder.preimages + '/**/*.{gif,png,jpg,svg}'])
.pipe(imagemin())
.pipe(gulp.dest(folder.public_img));
}
function webpTask() {
return gulp
.src([folder.preimages + '/**/*.{gif,png,jpg}'])
.pipe(webp())
.pipe(gulp.dest(folder.public_img));
}
function serve() {
gulp.watch(folder.preimages + '/**/*.{gif,png,jpg,svg}', images);
gulp.watch(folder.preimages + '/**/*.{gif,png,jpg}', webpTask);
}
gulp.task('clean', clean);
gulp.task('images', images);
gulp.task('default', gulp.series('clean', 'images', webpTask, serve));
Notes: I removed the gulp serve task. I couldn't get that to work under any configuration. I think you are running into a conflict by naming both the task and the function serve, although I'm not 100% positive. I changed the webp task name to webpTask, as I was getting a conflict by naming both the webp import and the webp function webp. I didn't include any of the webp() or imagemin() configuration options, but that shouldn't matter.
You should also be able to remove the calls for both the images and webpTask functions in the gulp default task, as running the serve function should trigger both of those.
This setup worked for me both when adding new images to my preimages folder while the gulp default task was running as well as when restarting the gulp default task.
FYI: I'm using gulp version 4.0.1., but I don't think that should make a difference for this.
I have a simple nodejs project that should load asynchronously the google maps api javascript, i followed this answer https://stackoverflow.com/a/15796543
and my app.js is like this:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
methodOverride = require("method-override");
https = require("https");
requirejs = require('requirejs');
requirejs.config({
waitSeconds : 500,
isBuild: true,
paths : {
'async': 'node_modules/requirejs-plugins/src/async',
}
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
var router = express.Router();
router.get('/', function(req, res) {
res.send("Hello World!");
});
requirejs(["async!http://maps.google.com/maps/api/js?key=mykey&sensor=false"], function() {
console.log(google);
});
app.listen(3000, function() {
console.log("asd");
});
package.json:
{
"name": "rest-google-maps-api",
"version": "2.0.0",
"dependencies": {
"express": "^4.7.1",
"method-override": "^2.1.2",
"body-parser": "^1.5.1",
"requirejs": "2.3.3",
"requirejs-plugins": "1.0.2"
}
}
i've got always the same error:
ReferenceError: google is not defined
The main issue here is that you are trying to run in Node code that is really meant to be used in a browser.
The async plugin
This plugin needs to be able to add script elements to document and needs window. I see you set isBuild: true in your RequireJS configuration. It does silence the error that async immediately raises if you do not use this flag, but this is not a solution because:
isBuild is really meant to be set internally by RequireJS's optimizer (or any optimizer that is compatible with RequireJS), not manually like you are doing.
isBuild means to indicate to plugins that they are running as part of an optimization run. However, your code is using the plugin at run time rather than as part of an optimization. So setting isBuild: true is a lie and will result in undesirable behavior. The async plugin is written in such a way that it effectively does nothing if isBuild is true. Other plugins may crash.
Google's Map API
It also expects a browser environment. The very first line I see when I download its code is this:
window.google = window.google || {};
Later in the code there are references to window.document and window.postMessage.
I don't know if it is possible to run the code you've been trying to load from Google in Node. I suspect you'd most likely need something like jsdom to provide a browser-like environment to the API.
assuming you did everything else correctly, which I am not testing here. The reason you are getting the error is because you call console.log(google) and there is no google variable. You need to pass google in as a reference in your call back function. This will either get rid of the error, or change the error if you have set up requirejs incorrectly.
requirejs(["async!http://maps.google.com/maps/api/js?key=mykey&sensor=false"],
function( **google** ) {
console.log(google);
});
see the requirejs docs http://requirejs.org/docs/node.html#1
Trying to integrate a plugin that is not available as a package into my Meteor app.
Here's the code:
import $ from "meteor/jquery";
import jQuery from "meteor/jquery"
(function($, window, document){
'use strict';
var doc = $(document);
window.notifyAlert = function(){
var $this = $(this),
onload = $this.data('onload');
if(onload !== undefined) {
setTimeout(function(){
notifyNow($this);
}, 800);
}
$this.on('click', function (e) {
e.preventDefault();
notifyNow($this);
});
}
function notifyNow($element) {
var message = $element.data('message'),
options = $element.data('options');
if(!message)
$.error('Notify: No message specified');
$.notify(message, options || {});
}
}(jQuery, window, document));
Here's the error:
Uncaught TypeError: $ is not a function
I wrapped the function to be immediately invoked in the context of the jQuery object, since I thought that will surely help solve the problem and prevent interference with the global namespace, but nope, same problem.
If you take take the immediate invocation out, obviously it won't work either. So I'm completely lost at what to do here.
I only have this error when working with Meteor and nowhere else.
Both $ and jQuery are accessible as properties of the package import, so import them using bracket notation:
import {$, jQuery} from 'meteor/jquery';
Note that depending on your file load order, you may also be able to access it from the window object inside your imported file:
const {$} = window;
I have something like this:
gulp.task('default', ['css', 'browser-sync'] , function() {
gulp.watch(['sass/**/*.scss', 'layouts/*.css'], function() {
gulp.run('css');
});
});
but it does not work, because it watches two directories, the sass and the layouts directory for changes.
How do I make it work, so that gulp watches anything that happens inside those directories?
gulp.task('default', ['css', 'browser-sync'] , function() {
gulp.watch(['sass/**/*.scss', 'layouts/**/*.css'], ['css']);
});
sass/**/*.scss and layouts/**/*.css will watch every directory and subdirectory for any changes to .scssand .css files that change. If you want to change that to any file make the last bit *.*
You can write a watch like this.
gulp.task('watch', function() {
gulp.watch('path/to/file', ['gulp task name for css/scss']);
gulp.watch('path/to/file', ['gulp task name for js']);
});
This way you can set up as many tasks as you want via the file path of what you want to watch followed by the name of the task you created. Then you can write your default like this:
gulp.task('default', ['gulp task name for css/scss', 'gulp task name for js']);
If you want to simply watch for various file changes, then just watch files using glob like *.css in your task.
One problem that has arisen for multiple people (including me) is that adding a gulp.filter outside of the task causes gulp.watch to fail after the first pass. So if you have something like this:
var filter = gulpFilter(['fileToExclude.js'])
gulp.task('newTask', function(){ ...
Then you need to change it to:
gulp.task('newTask', function(){
var filter = gulpFilter(['fileToExclude.js'])
The filter has to be included in the task function. Hope that helps someone.
This works for me (Gulp 4):
function watchSass() {
return gulp.watch(sassGlob, { ignoreInitial: false }, buildCss)
}
function watchImages() {
return gulp.watch(imagesGlob, copyImages)
}
exports.watch = gulp.parallel(watchSass, watchImages)
#A.J Alger's answer worked for me when using Gulp v3.x.
But starting with Gulp 4, The following appears to work for me.
Notice that each task has to return a value or call "done()". The main task in this example is 'watchSrc' which in parallel calls the other tasks.
gulp.task('watchHtml', function(){
return watch('src/**/*.html', function () {
gulp.src('src/**/*')
.pipe(gulp.dest(BUILD_DIR))
})
})
gulp.task('watchJS', function(){
return watch('src/**/*.js', 'devJS')
})
gulp.task('watchCSS', function(){
return watch(['src/**/*.css', 'src/**/*.scss'], 'buildStyles')
})
gulp.task('watchSrc', gulp.parallel('watchHtml', 'watchJS', 'watchCSS'), function(done)
{
done()
})
As of gulp 4, this is another option:
const { watch, series, parallel } = require('gulp');
function watchTask(cb) {
// this will execute all task on any changes
watch(['src/**/*'],
series(parallel(jsTask, htmlTask, assetTask),
));
// this will run specific task based on file type or folder
watch(['src/**/*.js'], series(jsTask));
watch(['src/**/*.html'], series(htmlTask));
watch(['assets/**/*'], series(assetTask));
}
exports.default = series(parallel(jsTask, htmlTask, assetTask), watchTask);
If you convert your tasks into functions
function task1(){
return gulp...
...
}
There are then 2 useful methods you can use:
GULP.SERIES will run the tasks synchronously
gulp.task('default', gulp.series(task1,task2));
GULP.PARALLEL will run them asynchronously
gulp.task('default', gulp.parallel(task1,task2));
I'm trying to use chalk or colors within a meteor app to get prettier logs, but I can't get them to work. It simply prints the logs as if I were not using them.
I've tried using it in a nodejs app (without meteor) and they work fine.
Is there something special meteor does with console.log?
Sample code:
if (Meteor.isServer) {
Meteor.startup(function () {
var chalk = Meteor.require('chalk')
console.log( chalk.blue('AAAAAAAAAAAAAAAAAA' ))
// code to run on server at startup
});
}
Chalk works smooth with meteor, you just need to enable it:
if (Meteor.isServer) {
Meteor.startup(function () {
var chalk = Meteor.npmRequire('chalk');
chalk.enabled = true;
console.log( chalk.red('AAAAAAAAAAAAAAAAAA' ))
});
}
Proof
Update
In comments author of question asked why chalk.enabled is necessary to make it working with meteor.
The reason is that chalk.supportsColor returns false, which stops chalk from creating colorful texts.
When you use chalk.enabled = true then you force chalk to always format text.
I got chalk NPM package working on in Meteor Server with 256 colors:
import Chalk from 'chalk';
const chalk = new Chalk.constructor({enabled: true, level: 2});
console.log(chalk.red('AHA'));
console.log(`${chalk.orange('AHA')}`);
I've not been able to get it working on the Chrome Console yet.