i am stuck in a kind of a trivial issue and can not get a hang of it.
here is the scenario:
I am using Gulp Task to convert my html templates to javascript using gulp-html2js My environment is Node v6.9.1, gulp 3.9.1, Windows 7
here is the gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var html2js = require('gulp-html2js');
var sourceDir = "D:\Programs_Insalled\nodejs\nodeapps\myApp"
gulp.task('templates', function() {
return gulp.src( 'D:\Programs_Insalled\nodejs\nodeapps\myApp\templates\*.html').
pipe(html2js({outputModuleName: 'templates'})).
pipe(concat('templates.js')).
pipe(gulp.dest('D:\Programs_Insalled\nodejs\nodeapps\myApp\bin'));
});
when i run the task, it completes, in a few m-sec but templates.js is not generated in bin directory
D:\Programs_Insalled\nodejs\nodeapps\myApp>gulp templates
[15:28:45] Using gulpfile D:\Programs_Insalled\nodejs\nodeapps\myApp\gulpfile.js
[15:28:45] Starting 'templates'...
[15:28:45] Finished 'templates' after 19 ms
I have tried below suggestions in similar items listed on GitHub and stackoverflow but have not been successful,
https://github.com/yeoman/generator-webapp/issues/182
https://github.com/yeoman/generator-webapp/issues/225
Can someone help out to find my mistake.
Thanks.
EDIT output of provided examples:
D:\Programs_Insalled\nodejs\nodeapps\myApp>gulp models
[17:13:10] Using gulpfile D:\Programs_Insalled\nodejs\nodeapps\myApp\gulpfile.js
[17:13:10] Starting 'models'...
[17:13:10] Finished 'models' after 21 ms
D:\Programs_Insalled\nodejs\nodeapps\myApp>gulp templates
[17:13:13] Using gulpfile D:\Programs_Insalled\nodejs\nodeapps\myApp\gulpfile.js
[17:13:13] Starting 'templates'...
D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\vinyl\index.js:120
if (!this.path) throw new Error('No path specified! Can not get relative.');
^
Error: No path specified! Can not get relative.
at File.get (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\vinyl\index.js:120:27)
at DestroyableTransform.bufferContents [as _transform] (D:\Programs_Insalled\nodejs\nodeapps\myA
pp\node_modules\gulp-concat\index.js:70:20)
at DestroyableTransform.Transform._read (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules
\gulp-concat\node_modules\readable-stream\lib\_stream_transform.js:184:10)
at DestroyableTransform.Transform._write (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_module
s\gulp-concat\node_modules\readable-stream\lib\_stream_transform.js:172:12)
at doWrite (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\gulp-concat\node_modules\rea
dable-stream\lib\_stream_writable.js:237:10)
at writeOrBuffer (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\gulp-concat\node_modul
es\readable-stream\lib\_stream_writable.js:227:5)
at DestroyableTransform.Writable.write (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\
gulp-concat\node_modules\readable-stream\lib\_stream_writable.js:194:11)
at DestroyableTransform.ondata (D:\Programs_Insalled\nodejs\nodeapps\myApp\node_modules\through2
\node_modules\readable-stream\lib\_stream_readable.js:531:20)
at emitOne (events.js:96:13)
at DestroyableTransform.emit (events.js:188:7)
D:\Programs_Insalled\nodejs\nodeapps\myApp>
. for pipe is better before pipe, I give you an e.g of one of my gulpile and you not need to put absolute machine path in dest your gulpfile is a root path of task gulp work with js use js path try this
Inever use html2js I dont know if you syntax is correct but first try with this path
my e.g
gulp.task('models', function(){
return gulp.src('models/*.*')
.pipe(gulp.dest('../dist/models'))
});
try that for you
gulp.task('templates', function() {
return gulp.src( 'templates/*.html')
.pipe(html2js({outputModuleName: 'templates'}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('bin'))
});
So, i have finally worked out the solution, Alhamdolilah
Issue was not with gulp task, or html2js, real issue was with gulp-concat
and i have realized that it is not needed as output is already concatenated by html2js
here is improved code:
gulp.task('templates', function () {
gulp.src('templates/*.html')
.pipe(html2js('templates.js', {
outputModuleName: 'templates',
name: 'templates'
}))
.pipe(gulp.dest('bin/'));
});
So I'm having a slight problem with producing production ready scripts for my project. I'm using gulp to concatenate and minify my css and js, and while the css is working fine the gulp js function isn't generating my final file. Please refer to my code below:
gulp.task('js', function() {
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(gulp.dest(source + 'js'))
.pipe(rename({
basename: 'production',
suffix: '-min',
}))
.pipe(uglify())
.pipe(gulp.dest(source + 'js/'))
.pipe(notify({ message: 'Scripts task complete', onLast: true }));
});
If anyone has encountered a similar problem or has any tips it would be much appreciated :)
There is nothing wrong with your gulpfile. I tested it and it works perfectly.
The only thing I can guess is that your source is not set correctly. Did you forget the trailing slash '/' ?
I would suggest 2 things to figure it out. Include node path library to check where source is actually pointing to like this:
var path = require('path');
// in gulp task ...
path.resolve(path.resolve(source + 'js/app'));
Make sure it points where you think it does.
Secondly, you could use gulp-debug to establish that any files are found:
npm install gulp-debug
Then
var debug = require('gulp-debug');
// in gulp task ...
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(debug())
.pipe(gulp.dest(source + 'js'))
.pipe(debug())
// etc.
Good luck!
Based on additional infomation in the comments I realise you are generating JS files in a separate process ...
gulp is asynchronous by default. What this boils down to is that all functions try to run at the same time - if you want a specific order it must be by design. This is great because it's very fast but can be a headache to work with.
Problem
Here is what's basically happening:
// SOME TASK THAT SHOULD BE RUN FIRST
gulp.task('copy-vendor-files-to-tempfolder', function (done) {
// copy files to vendor folder
done()
})
// SOME TASKS THAT DEPEND ON FIRST TASK
gulp.task('complile-styles', function () { /* independent task */ })
gulp.task('concat-vendor-files', function () { /* concat files in vendor folder. depends on vendor files existing */ })
// GENERAL TASK WHICH STARTS OTHERS
gulp.task('ready', ['copy-vendor-files-to-tempfolder', 'compile-styles', 'concat-vendor-files])
When you try to run:
$ gulp ready
GULP TASK WILL FAIL! Folder is being created at the same time!!
NOWHERE TO COPY FILES!
Solution
There are many solutions but the following module has come in handy for me again and again:
npm install run-sequence
Then in your gulpfile.js:
var runSequence = require('run-sequence')
gulp.task('ready', function (done) {
runSequence(
'create-folders', // do this first,
[
'copy-css-files',
'copy-html-files'
], // do these AFTER but in parallel
done // callback when ready
)
})
This will guarantee the folder exists when you try to run the other functions.
In your specific case, you should make sure the task that concatenates the JS files is run after the task that copies them out of vendor.
Note: I'm leaving other answer because it contains useful help for debugging similar issues.
HTH!
I have installed Visual Studio 2015 (with no other previous versions) on a new laptop and have pulled down the source for our MVC web app. We have a gulp file with tasks to compile our less and typescript.
When running this task ...
cmd.exe /c gulp -b "C:\Code\Trunk\MyProj\MyProj.Web" --color --gulpfile "C:\Code\Trunk\MyProj\MyProj.Web\Gulpfile.js" typescript
... I get the following error:
[09:43:16] Using gulpfile C:\Code\Trunk\MyProj\MyProj.Web\Gulpfile.js
[09:43:16] Starting 'typescript'...
[09:43:34] Plumber found unhandled error:
Error: UNKNOWN, open 'C:\Code\Trunk\MyProj\MyProj.Web\app\allergy\main.js'
Process terminated with code 0.
Here is the task in the gulp file (with other parts removed for brevity):
var gulp = require("gulp");
var plumber = require("gulp-plumber");
var sourcemaps = require("gulp-sourcemaps");
var typescript = require("gulp-typescript");
var merge = require("merge2");
var paths = {
typescript: {
globpatterns: {
all: "./Scripts/**/*.ts",
excludedefinitions: "!./Scripts/**/*.d.ts"
}
}
};
gulp.task("typescript", function () {
var result = gulp.src([
paths.typescript.globpatterns.all,
paths.typescript.globpatterns.excludedefinitions
])
.pipe(plumber())
.pipe(sourcemaps.init())
.pipe(typescript({
removeComments: true,
declarationFiles: false,
noImplicitAny: false,
noEmitOnError: true,
module: "amd",
target: "ES5"
}));
return merge([
result.js.pipe(gulp.dest("./")),
result.pipe(sourcemaps.write()).pipe(gulp.dest("./"))
]);
});
My colleague has the same set-up as me and gets no error.
Typescript is set to version 1.0 in the project file (<TypeScriptToolsVersion>1.0</TypeScriptToolsVersion>) and I can't change this just now. I wondered if the reason was beacuse I don't have this version installed on my machine but my colleague doesn't either. C:\Program Files (x86)\Microsoft SDKs\TypeScript only has a folder for 1.7
I noticed that the task completes successfully if I remove either of the 2 lines with in the merge block.
It's a different .js file in the error message each time
I searched the web to see what the UNKNOWN error even means but couldn't find anything obvious / helpful. Anyone know how to fix this error? Or how I go about finding out why it's being thrown?
EDIT 20-Jan-2016
So, I was getting this error consistently for about a week ... and now it has stopped happening. I haven't made any changes to my development environment either. I'd like to leave this question open since I'm curious as to why this happened.
Since yesterday something strange has started happening with my gulp-watch task. Afaik, all I did was change the destination but I can reproduce with the simple gulpfile posted below:
I have a file structure like this:
src/html/stuff/file.html
src/js/something/file.js
Whenever there is a change I want it relflected in the build folder but when I run the gulp watch:stuff below I get the following output:
build/html/stuff/file.html
build/stuff/file.html
build/js/something/file.js
Where is that extra build/stuff/file.html file coming from?
What is wrong my watch function wrong?
gulpfile
var gulp = require('gulp');
var watch = require('gulp-watch');
gulp.task('watch:stuff', function () {
var pattern = ['src/html/**/*.html', 'src/js/**/*.js'];
gulp.src(pattern, { base : './src/' })
.pipe(watch({glob: pattern, emit : 'all', verbose: true},
function(files) {
files.pipe(gulp.dest('./build'));
}
)
);
});
Using gulp(3.8.8), gulp-watch(0.7.0)
remove the base option, probably It confuses the gulp.src somehow, I don't know.
I am developing a Gulpfile. Can it be made to restart as soon as it changes? I am developing it in CoffeeScript. Can Gulp watch Gulpfile.coffee in order to restart when changes are saved?
You can create a task that will gulp.watch for gulpfile.js and simply spawn another gulp child_process.
var gulp = require('gulp'),
argv = require('yargs').argv, // for args parsing
spawn = require('child_process').spawn;
gulp.task('log', function() {
console.log('CSSs has been changed');
});
gulp.task('watching-task', function() {
gulp.watch('*.css', ['log']);
});
gulp.task('auto-reload', function() {
var p;
gulp.watch('gulpfile.js', spawnChildren);
spawnChildren();
function spawnChildren(e) {
// kill previous spawned process
if(p) { p.kill(); }
// `spawn` a child `gulp` process linked to the parent `stdio`
p = spawn('gulp', [argv.task], {stdio: 'inherit'});
}
});
I used yargs in order to accept the 'main task' to run once we need to restart. So in order to run this, you would call:
gulp auto-reload --task watching-task
And to test, call either touch gulpfile.js or touch a.css to see the logs.
I created gulper that is gulp.js cli wrapper to restart gulp on gulpfile change.
You can simply replace gulp with gulper.
$ gulper <task-name>
I use a small shell script for this purpose. This works on Windows as well.
Press Ctrl+C to stop the script.
// gulpfile.js
gulp.task('watch', function() {
gulp.watch('gulpfile.js', process.exit);
});
Bash shell script:
# watch.sh
while true; do
gulp watch;
done;
Windows version: watch.bat
#echo off
:label
cmd /c gulp watch
goto label
I was getting a bunch of EADDRINUSE errors with the solution in Caio Cunha's answer. My gulpfile opens a local webserver with connect and LiveReload. It appears the new gulp process briefly coexists with the old one before the older process is killed, so the ports are still in use by the soon-to-die process.
Here's a similar solution which gets around the coexistence problem, (based largely on this):
var gulp = require('gulp');
var spawn = require('child_process').spawn;
gulp.task('gulp-reload', function() {
spawn('gulp', ['watch'], {stdio: 'inherit'});
process.exit();
});
gulp.task('watch', function() {
gulp.watch('gulpfile.js', ['gulp-reload']);
});
That works fairly well, but has one rather serious side-effect: The last gulp process is disconnected from the terminal. So when gulp watch exits, an orphaned gulp process is still running. I haven't been able to work around that problem, the extra gulp process can be killed manually, or just save a syntax error to gulpfile.js.
I've been dealing with the same problem and the solution in my case was actually very simple. Two things.
npm install nodemon -g (or locally if you prefer)
run with cmd or create a script in packages like this:
"dev": "nodemon --watch gulpfile.js --exec gulp"
The just type npm run dev
--watch specifies the file to keep an eye on. --exec says execute next in line and gulp is your default task. Just pass in argument if you want non default task.
Hope it helps.
EDIT : Making it fancy ;)
Now while the first part should achieve what you were after, in my setup I've needed to add a bit more to make it really user friend. What I wanted was
First open the page.
Look for changes in gulpfile.js and restart gulp if there are any
Gulp it up so keep an eye on files, rebuild and hot reload
If you only do what I've said in the first part, it will open the page every time. To fix it, create a gulp task that will open the page. Like this :
gulp.task('open', function(){
return gulp
.src(config.buildDest + '/index.html')
.pipe(plugins.open({
uri: config.url
}));
Then in my main tasks I have :
gulp.task('default', ['dev-open']);
gulp.task('dev-open', function(done){
plugins.sequence('build', 'connect', 'open', 'watch', done);
});
gulp.task('dev', function(done){
plugins.sequence('build', 'connect', 'watch', done);
});
Then modifying your npm scripts to
"dev": "gulp open & nodemon --watch gulpfile.js --watch webpack.config.js --exec gulp dev"
Will give you exactly what you want. First open the page and then just keep live reloading. Btw for livereload I use the one that comes with connect which always uses the same port. Hope it works for you, enjoy!
Another solution for this is to refresh the require.cache.
var gulp = require('gulp');
var __filenameTasks = ['lint', 'css', 'jade'];
var watcher = gulp.watch(__filename).once('change', function(){
watcher.end(); // we haven't re-required the file yet
// so is the old watcher
delete require.cache[__filename];
require(__filename);
process.nextTick(function(){
gulp.start(__filenameTasks);
});
});
I know this is a very old question, but it's a top comment on Google, so still very relevant.
Here is an easier way, if your source gulpfile.js is in a different directory than the one in use. (That's important!) It uses the gulp modules gulp-newer and gulp-data.
var gulp = require('gulp' )
, data = require('gulp-data' )
, newer = require('gulp-newer' )
, child_process = require('child_process')
;
gulp.task( 'gulpfile.js' , function() {
return gulp.src( 'sources/gulpfile.js' ) // source
.pipe( newer( '.' ) ) // check
.pipe( gulp.dest( '.' ) ) // write
.pipe( data( function(file) { // reboot
console.log('gulpfile.js changed! Restarting gulp...') ;
var t , args = process.argv ;
while ( args.shift().substr(-4) !== 'gulp' ) { t=args; }
child_process.spawn( 'gulp' , args , { stdio: 'inherit' } ) ;
return process.exit() ;
} ) )
;
} ) ;
It works like this:
Trick 1: gulp-newer only executes the following pipes, if the source file is newer than the current one. This way we make sure, there's no reboot-loop.
The while loop removes everything before and including the gulp command from the command string, so we can pass through any arguments.
child_process.spawn spawns a new gulp process, piping input output and error to the parent.
Trick 2: process.exit kills the current process. However, the process will wait to die until the child process is finished.
There are many other ways of inserting the restart function into the pipes.
I just happen to use gulp-data in every of my gulpfiles anyway. Feel free to comment your own solution. :)
Here's another version of #CaioToOn's reload code that is more in line with normal Gulp task procedure. It also does not depend on yargs.
Require spawn and initilaize the process variable (yargs is not needed):
var spawn = require('child_process').spawn;
var p;
The default gulp task will be the spawner:
gulp.task('default', function() {
if(p) { p.kill(); }
// Note: The 'watch' is the new name of your normally-default gulp task. Substitute if needed.
p = spawn('gulp', ['watch'], {stdio: 'inherit'});
});
Your watch task was probably your default gulp task. Rename it to watch and add a gulp.watch()for watching your gulpfile and run the default task on changes:
gulp.task('watch', ['sass'], function () {
gulp.watch("scss/*.scss", ['sass']);
gulp.watch('gulpfile.js', ['default']);
});
Now, just run gulp and it will automatically reload if you change your gulpfile!
try this code (only win32 platform)
gulp.task('default', ['less', 'scripts', 'watch'], function(){
gulp.watch('./gulpfile.js').once('change' ,function(){
var p;
var childProcess = require('child_process');
if(process.platform === 'win32'){
if(p){
childProcess.exec('taskkill /PID' + p.id + ' /T /F', function(){});
p.kill();
}else{
p = childProcess.spawn(process.argv[0],[process.argv[1]],{stdio: 'inherit'});
}
}
});
});
A good solution for Windows, which also works well with Visual Studio task runner.
/// <binding ProjectOpened='auto-watchdog' />
const spawn = require('child-proc').spawn,
configPaths = ['Gulpconfig.js', 'bundleconfig.js'];
gulp.task('watchdog', function () {
// TODO: add other watches here
gulp.watch(configPaths, function () {
process.exit(0);
});
});
gulp.task('auto-watchdog', function () {
let p = null;
gulp.watch(configPaths, spawnChildren);
spawnChildren();
function spawnChildren() {
const args = ['watchdog', '--color'];
// kill previous spawned process
if (p) {
// You might want to trigger a build as well
args.unshift('build');
setTimeout(function () {
p.kill();
}, 1000);
}
// `spawn` a child `gulp` process linked to the parent `stdio`
p = spawn('gulp', args, { stdio: 'inherit' });
}
});
Main changes compared to other answers:
Uses child-proc because child_process fails on Windows.
The watchdog exits itself on changes of files because in Windows the gulp call is wrapped in a batch script. Killing the batch script wouldn't kill gulp itself causing multiple watches to be spawned over time.
Build on change: Usually a gulpfile change also warrants rebuilding the project.
Install nodemon globally: npm i -g nodemon
And add in your .bashrc (or .bash_profile or .profile) an alias:
alias gulp='nodemon --watch gulpfile.js --watch gulpfile.babel.js --quiet --exitcrash --exec gulp'
This will watch for file gulpfile.js and gulpfile.babel.js changes. (see Google)
P.S. This can be helpful for endless tasks (like watch) but not for single run tasks. I mean it uses watch so it will continue process even after gulp task is done. ;)
Here's a short version that's easy to understand that you can set as a default task so you just need to type "gulp":
gulp.task('watch', function() {
const restartingGulpProcessCmd = 'while true; do gulp watch2 --colors; done;';
const restartingGulpProcess = require('child_process').exec(restartingGulpProcessCmd);
restartingGulpProcess.stdout.pipe(process.stdout);
restartingGulpProcess.stderr.pipe(process.stderr);
});
gulp.task('watch2', function() {
gulp.watch(['config/**.js', 'webpack.config.js', './gulpfile.js'],
() => {
console.log('Config file changed. Quitting so gulp can be restarted.');
process.exit();
});
// Add your other watch and build commands here
}
gulp.task('default', ['watch']);
I spent a whole day trying to make this work on Windows / Gulp 4.0.2, and I (finally) made it...
I used some solutions from people on this page and from one other page. It's all there in the comments...
Any change in any function inside "allTasks" will take effect on gulpfile.js (or other watched files) save...
There are some useless comments and console.logs left, feel free to remove them... ;)
const { gulp, watch, src, dest, series, parallel } = require("gulp");
const spawn = require('child_process').spawn;
// This function contains all that is necessary: start server, watch files...
const allTasks = function (callback) {
console.log('==========');
console.log('========== STARTING THE GULP DEFAULT TASK...');
console.log('========== USE CTRL+C TO STOP THE TASK');
console.log('==========');
startServer();
// other functions (watchers) here
// *** Thanks to Sebazzz ***
// Stop all on gulpfile.js change
watch('gulpfile.js', function (callback) {
callback(); // avoid "task didn't complete" error
process.exit();
});
callback(); // avoid "task didn't complete" error
}
// Restart allTasks
// ********************************************
// CALL GULPDEFAULT WITH THE GULP DEFAULT TASK:
// export.default = gulpDefault
// ********************************************
const gulpDefault = function (callback) {
let p = null;
watch('gulpfile.js', spawnChildren);
// *** Thanks to Sphinxxx: ***
// New behavior in gulp v4: The watcher function (spawnChildren()) is passed a callback argument
// which must be called after spawnChildren() is done, or else the auto-reload task
// never goes back to watching for further changes (i.e.the reload only works once).
spawnChildren(callback);
function spawnChildren(callback) {
/*
// This didn't do anything for me, with or without the delay,
// so I left it there, but commented it out, together with the console.logs...
// kill previous spawned process
if (p) {
// You might want to trigger a build as well
//args.unshift('build');
setTimeout(function () {
console.log('========== p.pid before kill: ' + p.pid); // a random number
console.log('========== p before kill: ' + p); // [object Object]
p.kill();
console.log('========== p.pid after kill: ' + p.pid); // the same random number
console.log('========== p after kill: ' + p); // still [object Object]
}, 1000);
}
*/
// `spawn` a child `gulp` process linked to the parent `stdio`
// ['watch'] is the task that calls the main function (allTasks):
// exports.watch = allTasks;
p = spawn('gulp', ['watch'], { stdio: 'inherit', shell: true });
// *** Thanks to people from: ***
// https://stackoverflow.com/questions/27688804/how-do-i-debug-error-spawn-enoent-on-node-js
// Prevent Error: spawn ENOENT
// by passing "shell: true" to the spawn options
callback(); // callback called - thanks to Sphinxxx
}
}
exports.default = gulpDefault;
exports.watch = allTasks;
Install gulp-restart
npm install gulp-restart
This code will work for you.
var gulp = require('gulp');
var restart = require('gulp-restart');
gulp.task('watch', function() {
gulp.watch(['gulpfile.js'], restart);
})
it will restart gulp where you do changes on the gulpfile.js