Why is Gulp failing randomly with ENOENT error (or) failing to generate output (or accidentally deleted)? - node.js

Software Environment
I am using NodeJS v4.2.1 on Windows.
I have included my gulpfile.js, bower.json, and package.json files at the bottom.
Additional Information
I don't have any IDE running at the moment. So it is definitely not a problem with files being locked by an external program.
I am running everything on the command prompt.
Question
Is something wrong with my gulpfile.js?
Is this a bug with NodeJS v4.2.1?
Is this a bug with Gulp?
Problem
I am experiencing these two problems when I run gulp at command prompt.
Problem #1
My build folder would not be created every other time when I run gulp.
When I run it first time, it creates the build folder with copy-bower Gulp task output artifacts.
When I run it another time after it, build folder doesn't get created.
The gulp console output clearly shows my copy-bower task ran after the clean task, but I don't see the build folder created.
[21:21:32] Using gulpfile
[21:21:32] Starting 'clean'...
[21:21:32] Finished 'clean' after 3.66
[21:21:32] Starting 'copy-bower'...
[21:21:32] Finished 'copy-bower' after
[21:21:32] Starting 'default'...
[21:21:32] Finished 'default' after 6.
Directory: C:\Users\stun\Desktop\test-app
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/22/2015 9:00 PM bower_components
d----- 10/22/2015 8:59 PM node_modules
-a---- 10/22/2015 9:30 PM 347 bower.json
-a---- 10/22/2015 9:31 PM 421 gulpfile.js
-a---- 10/22/2015 9:30 PM 301 package.json
Problem #2
From time to time, I get either one of these errors.
events.js:141
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, chmod 'C:\Users\stun\Desktop\test-app\build\bower_components\jquery\dist\jquery.min.map'
at Error (native)
Another Error
events.js:141
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, stat 'C:\Users\stun\Desktop\test-app\build\bower_components\bootstrap\dist\fonts'
at Error (native)
gulpfile.js
var gulp = require('gulp'),
del = require('del');
gulp.task('clean', function () {
del(['build']);
});
gulp.task('copy-bower', ['clean'], function () {
var src = [
'./bower_components/bootstrap/dist/**',
'./bower_components/jquery/dist/*'
];
gulp.src(src, { base: '.' })
.pipe(gulp.dest('./build/'));
});
gulp.task('default', ['copy-bower'], function () { });
bower.json
{
"name": "test-app",
"description": "testing gulp and bower",
"main": "",
"moduleType": [],
"authors": [""],
"license": "MIT",
"homepage": "",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"bootstrap": "~3.3.5"
}
}
package.json
{
"name": "test-app",
"version": "1.0.0",
"description": "testing gulp and bower",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"del": "^2.0.2",
"gulp": "^3.9.0"
}
}

Your tasks do not return anything or call any callbacks, so Gulp thinks your tasks are done immediately. In particular, it won't wait for your clean task to have finished its work before starting to copy the bower files. The two may clash and result in filesystem errors.
Change your code to this:
var gulp = require('gulp'),
del = require('del');
gulp.task('clean', function () {
// Return the promise that del produces.
return del(['build']);
});
gulp.task('copy-bower', ['clean'], function () {
var src = [
'./bower_components/bootstrap/dist/**',
'./bower_components/jquery/dist/*'
];
// Return your stream.
return gulp.src(src, { base: '.' })
.pipe(gulp.dest('./build/'));
});
gulp.task('default', ['copy-bower'], function () { });

If the output shows that one task is starting before the previous is finished (especially "clean"), like this (see 'build' starting before 'clean' has ended):
[08:32:07] Using gulpfile ~/project/gulpfile.js
[08:32:07] Starting 'clean'...
[08:32:07] Starting 'build'...
[08:32:07] Finished 'clean' after 14 ms
[08:32:07] Finished 'build' after 15.53 ms
Use these techniques to fix it:
Technique 1 - return a promise
As #Louis wrote, turn this:
del = require('del');
gulp.task('clean', function () {
del(['build']);
});
into this:
del = require('del');
gulp.task('clean', function () {
return del(['build']); // see "return"
});
Technique 2 - task's dependency
turn this:
gulp.task('build', function () {
// some code...
});
to this:
gulp.task('build', ['clean'], function () { // see 'clean' as dependency
// some code...
});
Technique 3 - tasks ordering
turn this:
gulp.task('default', ['build', 'serve', 'watch']);
into this:
gulp.task('default', ['build'], function () {
gulp.start(['serve', 'watch']); // starts only after 'build'
});

Sadly I find that this issue still occurs. The esiest solution (for me) is to use run-sequence:
var runSequence = require('run-sequence');
gulp.task('some-task', function() {
runSequence(
['task-1', 'task-2', 'task-3'], // These 3 can be done in parallel
'task-4', // ...then just do this
['task-5', 'task-5'], // ...then do these things in parallel
'task-6', // ...then do this
// ....
);
});
found: https://davidwalsh.name/gulp-run-sequence

Just in case anyone encounters this issue after following the solutions in this thread... I was executing my clean and copy task within a gulp.parallel instead of a gulp.series which was making my build task fail randomly. I spent 1 hour trying to figure out what the problem was but never noticing that small detail. Hopefully this is useful for someone

Related

"Uncaught (in promise) ReferenceError: process is not defined" when migrating to Parcel 2

I'm trying to migrate a Node.js webapp from Parcel 1 to Parcel 2.
I have a function in the client-side javascript code (that Parcel bundles) that calls another function I'm importing from a utility functions file in the back-end Node.js code.
All other front-end functions work and all other Node.js functions which require Node.js process still work.
When I trigger calling this function in the code:
getCloudinaryUrl.js:22 Uncaught (in promise) ReferenceError: process is not defined
Everything worked just fine in Parcel 1, so I'm assuming this is a problem with my Parcel 2 configuration, not with Cloudinary.
The offending lines:
In getColudinaryUrl.js (back-end):
const { Cloudinary } = require('cloudinary-core');
...
// this is what triggers the error
const cloudName = process.env.CLOUDINARY_CLOUD_NAME;
const cl = new Cloudinary({
cloud_name: cloudName,
});
In index.js (front-end):
import getCloudinaryUrl from './../../utils/getCloudinaryUrl';
// then I'm calling it later on in the code
In server.js (back-end)
This is the only place in the code where I do dotenv.config:
const dotenv = require('dotenv');
...
dotenv.config({ path: './.env' });
My OLD package.json with Parcel 1 which worked:
...
"scripts": {
...
"watch:js": "parcel watch ./public/js/index.js --public-url /js --out-dir ./public/js --out-file bundle.js",
"build:js": "parcel build ./public/js/index.js --public-url /js --out-dir ./public/js --out-file bundle.js"
},
"devDependencies": {
...
"parcel-bundler": "1.12.3",
...
},
"engines": {
"node": "^14"
}
My NEW package.json file which doesn't work:
...
"scripts": {
...
"watch:js": "rm -rf .parcel-cache/ && parcel watch ./public/js/index.js --public-url /js --dist-dir ./public/js",
"build:js": "rm -rf .parcel-cache/ && parcel build ./public/js/index.js --public-url /js --dist-dir ./public/js"
},
"devDependencies": {
...
"parcel": "^2.0.0-nightly.524",
...
},
"engines": {
"node": "^14"
},
"default": "./public/js/bundle.js",
"targets": {
"main": false,
"default": {
"includeNodeModules": true,
"scopeHoist": false
}
}
I added rm -rf .parcel-cache/ && since otherwise a second build would always fail.
I read the migration guide and several other pages:
https://v2.parceljs.org/getting-started/migration/
https://v2.parceljs.org/features/module-resolution/
https://v2.parceljs.org/features/node-emulation/
It wasn't easy for me to read and, being rather new, Parcel 2 doesn't have many resources online to read over. That's how I ended up with the new package.json file above which gave me the least amount of errors (excluding the one above).
If there's anything else I should add to the question, I will gladly provide it.
How do I configure Parcel 2 to detect process in that one file?
It could be as easy as adding CLOUDINARY_CLOUD_NAME=something to a .env file in the project root?
A bit late, but for anyone ending up here, I eventually fixed it by removing the engines key from the package.json.

How to replace sass variable values using grunt-sass-replace?

I want to replace few sass variable values inside a sass config file.
For example, I want to replace the value of variable "$file_global" = "new";
I want to use "grunt-sass-replace" package to do the work, i tried alot but its giving me various errors.
My Project Directory Structure:
grep/
/node_modules/
package.json
Gruntfile.js
src/
my-styles.scss
my-styles.scss Code:
$file_global: "old";
Gruntfile.js Code:
module.exports = function(grunt){
pkg: grunt.file.readJSON('package.json'),
grunt.initConfig({
'sass-replace': {
files: { // File Options
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
},
options: {
variables: [
{
name: 'file_global',
to: 'new'
}
]
}
}
});
grunt.loadNpmTasks('grunt-sass-replace');
grunt.registerTask('default', ['sass-replace']);
};
package.json Code:
{
"name": "grep",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "KJ",
"license": "ISC",
"devDependencies": {
"grunt": "^1.0.4",
"grunt-sass-replace": "^0.1.18",
"npm-check-updates": "^3.1.9"
}
}
I updated the "files" but its still giving me various errors.
Below are the options that i tried and the errors generated.
First Try
// Option First :
files: {
'dest/my-styles.scss': 'src/my-styles.scss'
},
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
Warning: no files passed. Use --force to continue..
Aborted due to warnings.
Second Try:
// Option Second :
files: [
{
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
}
],
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
Warning: pattern.indexOf is not a function Use --force to continue.
Aborted due to warnings.
Last Try:
// Option Third :
files: {
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
},
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
>> [1] scss files found in [1] passed files.
>> replacements resolved successfully.
running string-replace task.
Warning: Task "string-replace:sass" not found. Use --force to continue.
Aborted due to warnings.
Anyone know how to solve this error, or any other grunt package which can do this kind of work.
This package was last updated 3 years ago, also it uses grunt ~0.4.5. I can't help you with this, However checkout "grunt-sass-replace-values" from https://www.npmjs.com/package/grunt-sass-replace-values. This package is updated a year ago and patched.
npm install grunt-sass-replace-values --save-dev
Check out following issue on Github:
https://github.com/eliranmal/grunt-sass-replace/issues/1
Explanation :
Cause of errors :
You defined sass variable incorrectly. Variables should be defined as "$variable: value;" and not like "$variable = value;"
As of the Github issue with this package, you need to update the path to your "grunt-string-replace" dependency.
Solution :
Under your project root folder, Go to below directory:
node_modules/grunt-sass-replace/tasks
Once you're in the above directory, look for a file name "sass-replace.js"
Just open the file with any Text Editor, and Edit the path to dependency.
grunt.task.loadTasks(path.resolve(__dirname, '../node_modules/grunt-string-replace/tasks'));
In your case edit this like as below :
grunt.task.loadTasks(path.resolve(__dirname, '../../../node_modules/grunt-string-replace/tasks'));
I hope this solves your problem. If not use another package, or use older node and grunt(0.4.5) versions.

Using Benchmarkjs with Webpack and Babel

I'm trying to get some basic benchmark tests working and am having trouble figuring out the right configuration. I'm trying to use Benchmarkjs with webpack and babel to transpile my code to es5. I created a benchmarks.webpack.js as an entry point which looks like this:
var context = require.context('./src/js', true, /-benchmark\.js$/);
context.keys().forEach(context);
module.exports = context;
I then have a benchmark file that I want to run (test-benchmark.js):
import benchmark from 'benchmark';
import benchmarks from 'beautify-benchmark';
let suite = new benchmark.Suite;
suite.add('RegExp#test', function() {
/o/.test('Hello World!');
})
.add('String#indexOf', function() {
'Hello World!'.indexOf('o') > -1;
})
.on('cycle', function(event) {
benchmarks.add(event.target);
})
.on('complete', function() {
benchmarks.log();
})
.run();
I updated my webpack build to try and transpile the benchmarks:
_.assign(config, {
devtool: 'eval-cheap-module-source-map',
output: {
path: path.join(__dirname, 'build/benchmark'),
filename: 'benchmark.js',
publicPath: '/'
},
entry: [
'./benchmarks.webpack.js'
],
plugins: [
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel?stage=0'],
include: path.join(__dirname, 'src/js')
},
]
},
});
Finally, I want to be able run this from an npm script:
"scripts": {
"bench": "webpack --config webpack.bench.config.js && node build/benchmark/benchmark.js"
},
However, I'm getting warnings that the result of the benchmark dependency is an expression and there no suitable loaders for the .json, .txt, etc files. I tried hacking up Benchmarkjs to export correctly but was not successful.
WARNING in ./~/benchmark/benchmark.js
Critical dependencies:
1122:34-49 the request of a dependency is an expression
# ./~/benchmark/benchmark.js 1122:34-49
WARNING in ./~/benchmark/package.json
Module parse failed: /home/bill/dev/levelstory/react-client-redux/node_modules/benchmark/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "name": "benchmark",
| "version": "1.0.0",
| "description": "A benchmarking library that works on nearly all JavaScript platforms, supports high-resolution timers, and returns statistically significant results.",
# ./~/benchmark ^\.\/.*$
WARNING in ./~/benchmark/LICENSE.txt
Module parse failed: /home/bill/dev/levelstory/react-client-redux/node_modules/benchmark/LICENSE.txt Line 1: Unexpected number
You may need an appropriate loader to handle this file type.
| Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
| Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
| Modified by John-David Dalton <http://allyoucanleet.com/>
# ./~/benchmark ^\.\/.*$
Looks like benchmark does something special with require. That messes it up for Webpack. It has the following lines:
var freeRequire = typeof require == 'function' && require;
...
function req(id) {
try {
var result = freeExports && freeRequire(id);
} catch(e) { }
return result || null;
}
If you comment out the function contents, the error goes away. Given it's not ideal to patch around it this way I would poke the benchmark guys about this directly instead. Perhaps there's something we're missing.

grunt throw "Recursive process.nextTick detected"

I'm running Lion 10.9.2 with nodejs v0.10.26
I want to setup an automated compilation on sass files and a live reload with grunt, nothing complicated but...
When running grunt watch I get the following error
(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
util.js:35
var str = String(f).replace(formatRegExp, function(x) {
^
RangeError: Maximum call stack size exceeded
here is the Gruntfile.js
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
files: {
'assets/css/styles.css': 'assets/sass/styles.scss'
}
}
},
watch: {
all: {
files: 'index.html', // Change this if you are not watching index.html
options: {
livereload: true // Set livereload to trigger a reload upon change
}
},
css: {
files: [ 'assets/sass/**/*.scss' ],
tasks: [ 'sass' ],
options: {
spawn: false
}
},
options: {
livereload: true // Set livereload to trigger a reload upon change
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('watch', [ 'watch']);
grunt.registerTask('default', [ 'sass', 'watch' ]);
};
and here is the package.json
{
"name": "application",
"version": "0.0.1",
"private": true,
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-sass": "~0.7.3"
}
}
I finally figured out a similar problem I was having with SASS. I was using
grunt.registerTask('sass', [ 'sass']);
The trick was that Grunt doesn't seem to like the repetition in names. When I switch to
grunt.registerTask('styles', [ 'sass']);
Everything worked as it should.
Just had this problem. Resolved it by removing grunt.registerTask('watch', [ 'watch']);
I just fixed a similar error "Recursive process.nextTick detected" causing by command: grunt server
The solution? Use sudo grunt serve instead
you could try this one, it fixed the issue for me, working with Yeoman 1.3.3 and Ubuntu 14.04 Grunt watch error - Waiting...Fatal error: watch ENOSPC
I was getting error in even trying to install grunt. Running npm dedupe solved my problem as answered here: Grunt watch error - Waiting...Fatal error: watch ENOSPC
Alternative solution: check your watch for an empty file argument.
Here's an excerpt of my gruntfile
watch: {
all: {
options:{
livereload: true
},
files: ['src/scss/*.scss', 'src/foo.html',, 'src/bar.html'],
tasks: ['default']
}
}
In my case, I could recreate the original poster's error on demand with the empty argument above.

Arguments to path.resolve must be strings when running Grunt

My Grunt file:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
ts: {
dev: {
src: ["src/background/*.ts"],
out: ["build/background.js"],
}
}
});
grunt.loadNpmTasks("grunt-ts");
grunt.registerTask("default", ["ts:dev"]);
};
(I am using grunt-ts.)
System info
Windows 8.1
NodeJS v0.10.24
grunt-cli v0.1.11
grunt v0.4.2
I've already searched the Internet and found many resources about this error, but they all say that one should upgrade NodeJS and/or Grunt. I've already tried that. I had even completely re-installed Grunt, however, the error remained.
The complete error message:
P:\my-folder>grunt ts
Running "ts:dev" (ts) task
Warning: Arguments to path.resolve must be strings Use --force to continue
Aborted due to warnings.
package.json
{
"name": "regex-search",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-jshint": "~0.6.3",
"grunt-contrib-nodeunit": "~0.2.0",
"grunt-contrib-uglify": "~0.2.2",
"grunt-ts": "~1.5.1"
}
}
After comparing my Gruntfile with the officially provided sample file, I found my really silly mistake:
ts: {
dev: {
src: ["src/background/*.ts"],
out: ["build/background.js"],
}
}
out must not be an array!
The correct version:
ts: {
dev: {
src: ["src/background/*.ts"],
out: "build/background.js",
}
}
So in my particular case, a node module's main attribute in package.json was an array and not a string, example in history.js' package.json:
{
"main": [ './history.js', './history.adapter.ender.js' ]
}
The way I found this out was going to where the error originated in my node_modules and then did console.log(pkg.main) right above it.
Original stacktrace:
Fatal error: Arguments to path.resolve must be strings
TypeError: Arguments to path.resolve must be strings
at Object.posix.resolve (path.js:422:13)
at /Users/ebower/work/renvy/node_modules/browserify/node_modules/resolve/lib/async.js:153:38
at fs.js:336:14
at /Users/ebower/work/renvy/node_modules/grunt-browserify/node_modules/watchify/node_modules/chokidar/node_modules/readdirp/node_modules/graceful-fs/graceful-fs.js:104:5
at /Users/ebower/work/renvy/node_modules/grunt-mocha/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/graceful-fs.js:104:5
at FSReqWrap.oncomplete (fs.js:99:15)

Resources