I have the following gulp file that was working fine for months until this morning:
//gulpfile.js
const gulp = require('gulp')
const { series } = require('gulp')
const rename = require('gulp-rename')
const uglify = require('gulp-uglify')
const sass = require('gulp-sass')(require('sass'))
function minJs() {
return gulp
.src('./dev/js/script.js')
.pipe(uglify())
.pipe(
rename({
extname: '.min.js'
})
)
.pipe(gulp.dest('./build/js/'))
}
exports.minJs = minJs
function minCss() {
return gulp
.src('./dev/css/style.sass')
.pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError))
.pipe(
rename({
extname: '.min.css'
})
)
.pipe(gulp.dest('./build/css/'))
}
exports.minCss = minCss
exports.test = () => {
series(minCss, minJs)
}
Every time I run "Gulp test" I get the following error:
[11:17:59] Starting 'test'...
[11:17:59] The following tasks did not complete: test
[11:17:59] Did you forget to signal async completion?
I've tried adding a callback to the two tasks and tried changing them to async functions but neither resolved the issue. I'm not sure why I'm getting this error since I am returning a stream.
Any help is appreciated!
gulp.series is actually a higher-order rule, i.e., it makes a rule out of rules, so shouldn't be wrapped in a closure:
exports.test = series(minCss, minJs);
Related
Gulp terminal seems to get stucked after browserify-ing my main.js. Below is my gulpfile.babel.js
'use strict';
import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import browserSyncLib from 'browser-sync';
import pjson from './package.json';
import minimist from 'minimist';
import glob from 'glob';
// Load all gulp plugins based on their names
// EX: gulp-copy -> copy
const plugins = gulpLoadPlugins();
const defaultNotification = function(err) {
return {
subtitle: err.plugin,
message: err.message,
sound: 'Funk',
onLast: true,
};
};
let config = Object.assign({}, pjson.config, defaultNotification);
let args = minimist(process.argv.slice(2));
let dirs = config.directories;
let taskTarget = args.production ? dirs.destination : dirs.temporary;
// Create a new browserSync instance
let browserSync = browserSyncLib.create();
// This will grab all js in the `gulp` directory
// in order to load all gulp tasks
glob.sync('./gulp/**/*.js').filter(function(file) {
return (/\.(js)$/i).test(file);
}).map(function(file) {
require(file)(gulp, plugins, args, config, taskTarget, browserSync);
});
// Default task
gulp.task('default', ['clean'], () => {
gulp.start('build');
});
// Build production-ready code
gulp.task('build', [
'browserify'
]);
// Testing
gulp.task('test', ['eslint']);
This is my browserify.js
'use strict';
import path from 'path';
import glob from 'glob';
import browserify from 'browserify';
import watchify from 'watchify';
import envify from 'envify';
import babelify from 'babelify';
import _ from 'lodash';
import vsource from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import gulpif from 'gulp-if';
export default function(gulp, plugins, args, config, taskTarget, browserSync) {
let dirs = config.directories;
let entries = config.entries;
let browserifyTask = (files) => {
return files.map((entry) => {
let dest = path.resolve(taskTarget);
// Options
let customOpts = {
entries: [entry],
debug: true,
transform: [
babelify, // Enable ES6 features
envify // Sets NODE_ENV for better optimization of npm packages
],
paths: ['./node_modules','./src/_modules/', './src/Cwp/assets/PTM/scripts/', './src/_Cwp/assets/PTM/scripts/']
};
let bundler = browserify(customOpts);
if (!args.production) {
// Setup Watchify for faster builds
let opts = _.assign({}, watchify.args, customOpts);
bundler = watchify(browserify(opts));
}
let rebundle = function() {
let startTime = new Date().getTime();
bundler.bundle()
.on('error', function(err) {
plugins.util.log(
plugins.util.colors.red('Browserify compile error:'),
'\n',
err.stack,
'\n'
);
this.emit('end');
})
.on('error', plugins.notify.onError(config.defaultNotification))
.pipe(vsource(entry))
.pipe(buffer())
.pipe(plugins.sourcemaps.init({loadMaps: true}))
.pipe(gulpif(args.production, plugins.minify()))
.on('error', plugins.notify.onError(config.defaultNotification))
.pipe(plugins.rename(function(filepath) {
// Remove 'source' directory as well as prefixed folder underscores
// Ex: 'src/_scripts' --> '/scripts'
filepath.dirname = filepath.dirname.replace(dirs.source, '').replace('_', '');
}))
.pipe(plugins.sourcemaps.write('./'))
.pipe(gulp.dest(dest))
// Show which file was bundled and how long it took
.on('end', function() {
let time = (new Date().getTime() - startTime) / 1000;
console.log(
plugins.util.colors.cyan(entry)
+ ' was browserified: '
+ plugins.util.colors.magenta(time + 's'));
return browserSync.reload('*.js');
});
};
if (!args.production) {
bundler.on('update', rebundle); // on any dep update, runs the bundler
bundler.on('log', plugins.util.log); // output build logs to terminal
}
return rebundle();
});
};
// Browserify Task
gulp.task('browserify', (done) => {
return glob('./' + path.join(dirs.source, dirs.scripts, entries.js), function(err, files) {
if (err) {
done(err);
}
return browserifyTask(files);
});
});
}
When I execute gulp build in my terminal, below output is:
C:\Users\Chan\Downloads\Frontend\Frontend>gulp build
[23:25:23] Requiring external module babel-register
[23:25:25] Using gulpfile ~\Downloads\Frontend\Frontend\gulpfile.babel.js
[23:25:25] Starting 'browserify'...
[23:25:26] 842639 bytes written (1.21 seconds)
[23:25:27] 831961 bytes written (1.55 seconds)
./src/_Cwp/assets/PTM/scripts/main-contribute-form-iframe.js was browserified: 1.751s
./src/_Cwp/assets/PTM/scripts/main-vip-tree-iframe.js was browserified: 1.607s
[23:25:27] 1445674 bytes written (1.76 seconds)
./src/_Cwp/assets/PTM/scripts/main-plot-tree-iframe.js was browserified: 1.853s
[23:25:31] 7046431 bytes written (5.32 seconds)
./src/_Cwp/assets/PTM/scripts/main.js was browserified: 5.589s
The terminal looks stucked. what seems to be the problem here?
I tried running gulp command on my terminal in the project directory where I have the gulpfile.js but I get the error, The following tasks did not complete: default, gulpSass; Did you forget to signal async completion which I tried looking for a solution to but to no avail.
I checked out some possible reasons to why I am facing the problem and implemented some but I still kept getting the error.
One of the possible fix I tried was using async await in all of the functions but it didn't solve the issue.
This is my gulpfile.js
var gulp = require('gulp'),
sass = require('gulp-sass'),
plumber = require('gulp-plumber'),
notify = require('gulp-notify'),
livereload = require('gulp-livereload')
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
// Concat all js into one script
async function js ( cb ) {
return await gulp.src(['./assets/js/lib/*.js','./assets/js/scripts/**/*.js'])
.pipe(plumber(plumberErrorHandler))
//.pipe(jshint())
//.pipe(jshint.reporter('jshint-stylish'))
.pipe(sourcemaps.init())
.pipe(concat('scripts.min.js'))
.pipe(uglify())
.pipe(sourcemaps.write('../maps/'))
.pipe(gulp.dest('./assets/js'))
.pipe(livereload());
cb();
}
// Sass compiler + Maps
async function sass ( cb ) {
return await gulp.src('./assets/scss/*.scss')
.pipe(plumber(plumberErrorHandler))
.pipe(sassGlob())
.pipe(sourcemaps.init())
.pipe(sass({outputStyle: 'development'}))
//.pipe(autoprefixer({
// browsers: ['>1%'],
//remove: false
//}))
.pipe(sourcemaps.write('./assets/maps'))
.pipe(gulp.dest('.'))
.pipe(livereload());
cb();
}
// Watch for changes
async function watch ( cb ) {
livereload.listen();
return await gulp.watch('./assets/scss/**/*', ['sass']);
return await gulp.watch('./assets/js/lib/**/*.js', ['js']);
return await gulp.watch('./assets/js/scripts/**/*.js', ['js']);
return await gulp.watch('./**/*.php').on('change', async function(file) {
livereload.changed(file.path);
});
cb();
}
// Error handling/reporting
var plumberErrorHandler = {
errorHandler: notify.onError({
title: 'Gulp',
message: 'Error: <%= error.message %>'
})
}
// Default
exports.default = gulp.series(js, sass, watch);
First, your error message says The following tasks did not complete: default, gulpSass; but there is no gulpSass task in your code so you changed something before you copied it here.
Second, this syntax is old:
return await gulp.watch('./assets/scss/**/*', ['sass']);
Use this instead:
gulp.watch('./assets/scss/**/*', sass);
You are using the function name form of tasks not the gulp.task('sass') syntax, so in the watch calls you use the function name sass but not as a string'sass'.
Make this change throughout your watch task.
And I would get rid of the return await - it is probably a problem.
I'm beginner with nodejs and I want environment variables shared through modules. I read those variables with dotenv package. But in next required module process.env is undefined.
app.js
console.log(require('dotenv').config())
console.log(process.env.NODE_ENV);
require('./task')
task.js
console.log(process.env);
console.log(process.env.NODE_ENV);
.env
NODE_ENV=development
PORT=8080
console log
{ parsed: { NODE_ENV: 'development', PORT: '8080' } }
development
undefined
E:\msf\nodejs_prj\compositor\task.js:2
console.log(process.env.NODE_ENV);
^
TypeError: Cannot read property 'NODE_ENV' of undefined
at Object.<anonymous> ...
I created new clean project with provided code and it works also for me. That means it's related to something else. This node.js is weard about errors.
This is my whole code from task.js
const fs = require('fs')
const path = require('path')
const decompress = require('decompress')
const dir = './upload'
console.log(process, process.env)
function process() {
console.log('cron - process data');
fs.readdir(dir, (err, files) => {
if (err) return
files.forEach(file => {
if (path.extname(file) != '.zip') return
let target = path.join(dir, path.basename(file).replace(path.extname(file), ''))
unlinkDirSync(target)
decompress(path.join(dir, file), target).then(files => {
console.log(files);
console.log('done!');
//todo process unzipped files
//todo delete unzipped directory and zip file
})
})
})
}
function unlinkDirSync(dir_path) {
if (fs.existsSync(dir_path)) {
fs.readdirSync(dir_path).forEach(function (entry) {
var entry_path = path.join(dir_path, entry);
if (fs.lstatSync(entry_path).isDirectory()) {
unlinkDirSync(entry_path);
} else {
fs.unlinkSync(entry_path);
}
});
fs.rmdirSync(dir_path);
}
}
if (process.env === undefined || process.env.NODE_ENV === undefined || process.env.NODE_ENV === 'production') {
console.log('starting on production')
setInterval(process, 1000 * 60)
} else {
console.log('starting on development')
setTimeout(process, 1000)
}
If I comment out the rest after console.log it works.
I'm idiot. I named function process, which is the name of system variable :D
Sorry for bothering you guys, thanks for help.
Add require('dotenv').config() in global. Also make sure .env file is in root directory of the project. I have created a sample on github https://github.com/GMaker01/basic-dotenv-example
For reference, you can look into the dotenv documentation
could anyone please add a snippet to a google-closure-compiler basic process, I am trying unsuccessfully to this via js code.
I am using the exmple snippet from the official npm page.
when I run it, something seem to happen but the output file isn't created.
My code:
const ClosureCompiler = require('google-closure-compiler').jsCompiler;
console.log(ClosureCompiler.CONTRIB_PATH); // absolute path to the contrib folder which contains externs
const closureCompiler = new ClosureCompiler({
compilation_level: 'ADVANCED'
});
const compilerProcess = closureCompiler.run([{
path: './',
src: 'a.js',
sourceMap: null // optional input source map
}], (exitCode, stdOut, stdErr) => {
console.log(stdOut)
//compilation complete
});
Building from what you had, I've changed just a few things:
1) The src attribute is not a path it is the file: read the file in this case with fs.readFileSync.
2) The output is returned in the callback: you'll need to write it to the disk.
Files:
index.js
const ClosureCompiler = require('google-closure-compiler').jsCompiler;
const {writeFile, readFileSync} = require('fs');
const closureCompiler = new ClosureCompiler({
compilation_level: 'ADVANCED'
});
let src = readFileSync('a.js', 'UTF-8');
const compilerProcess = closureCompiler.run([{
path: './',
src: src,
sourceMap: null
}], (exitCode, stdOut, stdErr) => {
stdOut.map((fileResults) => {
writeFile(fileResults.path, fileResults.src, () => {});
});
});
a.js
console.log('hello world!')
compiled.js
console.log("hello world!");
Ok, so apperantly there is no way to create a file without using a 'fs' library.
according to the "closure-compiler-js.js", when "run" is complete, the callback only loggs out the result.
https://github.com/google/closure-compiler-npm/blob/master/packages/google-closure-compiler/lib/node/closure-compiler-js.js
which is funnny, because 'closure-compiler-npm' does use 'fs' to read the file contents, but it dosent have any 'write-file' mechanism.
and even on the official 'cli.js' the 'fs' library is used:
https://github.com/google/closure-compiler-npm/blob/master/packages/google-closure-compiler/cli.js
const ClosureCompiler = require('google-closure-compiler').jsCompiler;
const { writeFile } = require('fs');
const closureCompiler = new ClosureCompiler({
js:['a.js','a1.js'],
js_output_file: 'out.js'
});
const compilerProcess = closureCompiler.run([{
path: './',
}], (exitCode, stdOut, stdErr) => {
writeFile(stdOut[0].path, stdOut[0].src,()=>{});
});
I am new to javascript and mocha. I have been looking at how to create a third party reporter. I saw some samples at https://github.com/mochajs/mocha/wiki/Third-party-reporters
I created one that meets my needs and was able to install it and use it. But, the requirement is to not install the reporter. It can either be a different file or be part of the same js file.
Can anyone please tell me how to hook the reporter with the js file?
Here is my test js file
const mochasteps = require('mocha-steps')
var Mocha = require('mocha');
var report = require('./report')
var mochainstance = new Mocha({reporter: report});
console.log(mochainstance._reporter)
before(() => console.log('before'))
after(() => console.log('after'))
describe('Array', () => {
step('should start empty', done => {
var arr = [];
if (arr.length == 1) return done()
done(new Error('array length not 0'))
});
});
describe('Test', () => {
step('some Test', done => {
done();
});
});
Here is my test report.js file that does the reporting.
var mocha = require('mocha');
module.exports = report;
function report(runner) {
mocha.reporters.Base.call(this, runner);
runner.on('pass', function(test){
console.log('[pass]%s', test.title);
});
runner.on('fail', function(test, err){
console.log('[fail]%s(%s)', test.title, err.message);
});
runner.on('end', function(){
process.exit(0);
});
}
Thanks,
r1j1m1n1
You need to pass the path to the custom reporter when running the tests. In your example, assuming test.js and report.js are in the same folder, it would be as follows:
mocha test.js -R 'report.js'
This will run the test.js tests with report.js as the reporter without having to install the reporter.