I was already successful to automate my build commands inside the "tasks.json" file. But sadly "tasks.json" or vscode does not offer an option to set custom environment variables (which would be a really really really nice and needed feature).
I don't want to change a couple of lines just to specify the program which I want to build (there are a couple in this project). I was able to do a workaround and set an windows environment variable, but for this workaround I need to restart vscode if I change the environment variable.
Therefore I tried to use GULP-Task to start my build process, because with gulp task I set file global variables. I was already able to get my tasks running in gulp, but with gulp tasks I don't see the progress of my building task in the output sequentially, I just get the output when he is finished in a big "blop".
I tried a couple of things, like piping, writing to file (this worked sequentially), but the output on the output-window is still displayed as a "blop". Therefore I want to ask if it is possible to get an sequential output of my running task with gulp?
This is how I start my build task:
gulp.task('BuildDebug', function (cb) {
exec(buildCommand + debugCommand, function (error, stdout, stderr) {
console.log(stdout);
console.log(stderr);
});
});
Related
Having a strange behavior in a gulp task. I have one task that runs my tests just fine every time I manually run it:
gulp.task('run-tests', function () {
return gulp.src('./test/**/*.js', { read: false })
.pipe(mocha({ reporter: 'spec' }));
});
So then I setup a watcher to auto run them when any of the source or tests run:
gulp.task('watch-tests', function () {
gulp.watch(['./generators/**', './test/**/*.js'], ['run-tests']);
});
The first problem is that the tests aren't run when the task starts... I'd like for a first pass when I start this up.
But the bigger issue is that when once I do get the watcher to fire by updating a file, it correctly executes all my tests, but in every subsequent time, it doesn't find any of my tests... as you can see from the following output. Any ideas? Very strange...
$ gulp watch-tests
[16:55:15] Using gulpfile ~/repos/../gulpfile.js
[16:55:15] Starting 'watch-tests'...
[16:55:15] Finished 'watch-tests' after 14 ms
[16:55:19] Starting 'run-tests'...
app
server.js
✓ creates server.js in src/server
✓ set port number in server.js
package.json
✓ creates package.json in root
✓ sets correct values in package.json
static files created in src/public
✓ created public/index.html
✓ created public/content/site.css
6 passing (75ms)
[16:55:20] Finished 'run-tests' after 805 ms
[16:55:38] Starting 'run-tests'...
0 passing (0ms)
[16:55:38] Finished 'run-tests' after 4.14 ms
What happens is that somewhere in your code (tests or the actual code under test) the current working directory gets changed, and the next run of tests doesn't find the specified test files anymore. You cannot see this from the code in your question, I found it in the github generator-office project you link to in a comment.
You can check this by inserting
console.log(process.cwd());
into your test task and see it change on the second run.
Now you could rewrite your code to not change the current working directory or always reset it, but you can also fix it in your gulpfile by creating a variable to save the CWD to (outside if the task definition).
var currentWorkingDirectory = process.cwd();
And then change the file specification from
gulp.src('test/*.js')
to
gulp.src(currentWorkingDirectory + '/test/*.js')
in your test task. (the watch task is not affected by the change in working directory, probably because it will get the references to the files at startup and not scan them again)
It is super annoying,
but simply remove the "./" from the watcher path, like this:
gulp.task('watch-tests', function () {
gulp.watch(['generators/**', 'test/**/*.js'], ['run-tests']);
});
make sure the paths work with out the "./" and it will work as many times as you want.
I am trying to set up a similar process to what Web Essentials offered in the old visual studio in the newest one. For those of you who aren't familiar with how that worked, the process was:
File Setup:
a.less
a.css
a.min.css
a.css.map
b.less
b.css
b.min.css
b.css.map
So basically when you open a.less and start editing it, it would automatically check out a.css, a.min.css, and a.css.map as well. Then when you save, it would recompile the 3 sub files as well as saving the less file.
I am able to replicate this by writing a separate task for each file like so:
gulp.task('checkout', function () {
return gulp.src('Styles/brands.css')
.pipe(tfs());
});
gulp.task('less', ['checkout'], function () {
del('Styles/brands.css');
return gulp.src('Styles/brands.less')
.pipe(less())
.pipe(gulp.dest('Styles'));
});
This uses gulp-tfs-checkout to checkout the sub file, and then the less to compile. This works 100% how I expect it to. I can set up a watch to watch the less task and everything will work great. The only problem is, how do I expand this to handle all my less files in that folder? I could write separate checkout and compile tasks for each file, but that's not really ideal.
I am used to writing projects where saving any less file compiles and concats all of them into a single or a couple files, but this is a work project and for multiple reasons I need to keep the css files separate as they are now. We use visual studio's bundling, but its an older project and people have referenced the css files randomly outside of the bundling process so it would be a pretty big/risky task to change that.
I don't know how to watch many files, but only change the current one if that makes sense.
gulp.task('less', function () {
return gulp.src('Styles/*.less') //watch all of my files
.pipe(tfs())//checkout only the css file for the less file that was changed here somehow
.pipe(less()) //compile only the css file that was changed
.pipe(gulp.dest('Styles'));
});
I am fairly used to grunt and gulp, but like I said I generally do things in bulk on my project. I'm not sure how to do this when I want to watch all the files, but only change 1
Why don't you create all those tasks per each file dynamically? You can read the contents of the folder where your less files are with fs.readdirSync and then if the file is a less file you create for each the task 'checkout' + filename and then 'less' + filename.
Being dynamically you will not have any problems when you create a new less file or when you remove one.
I have a gulp task that performs some pretty common tasks - it runs jshint to validate my code, then concats and minimizes the files and outputs them into single .min.js files.
The task (appears) to execute flawlessly when I run it manually. But the second I try to use it in a $gulp.watch it no longer outputs my file (it still executes and executes jshint though).
The code in my task:
gulp.src(path.join(workingPath, folder, '/*.js'))
.pipe(jshint())
.pipe(jshint.reporter(stylish))
.pipe(jshint.reporter('fail')) //stop build if errors found
.on('error', function() {
console.log("Please review and correct jshint errors.");
this.end();
})
.pipe(order([ //order files before concat - ensure module definitions are first
"*.module.js",
"*.js"
]))
.pipe(concat(filename+'.js'))
.pipe(gulp.dest(destinationPath)) //full combined version
.pipe(uglify())
.pipe(rename(filename+'.min.js'))
.pipe(gulp.dest(destinationPath)) //minified combined version
.on('error',function() {
console.log("An error occurred during Gulp processing.");
this.end();
});
My gulp watch (the task is named 'components'):
gulp.watch(componentsBasePath+"/**/*.js",['components']);
One thing that I've noticed though is at the end of the manual run I see "Process finished with exit code..". And if I kill my gulp.watch it outputs "Process finished with exit code.." - then it DOES creates the output files!
My goal is to have my 'components' task create those output files every time it is triggered by the watch - not just when I kill the watch.
Thank you!
Cliff
Ok so my hacky way to fix the problem with jetbrains (im using phpstorm), you gotta understand 2 things.
gulp watchers act on file save.
jetbrains will not auto update the project files (as you have found out it uses a cache).
To get around this problem i created a macro called saveSync which does the following actions:
Save all
Synchronize
Synchronize
Synchronize
Why did i synchronize 3 times? Because gulp takes a few seconds to finish tasks (compiling, etc) and if you update before they finish obviously the project view doesn't get update properly. I haven't figured out a way to insert a time delay into the macro itself.
After i created the macro, i just rebound ctrl + s from save all to the macro, and it worked.
If there is a 'cleaner' way of doing this i have yet to discover it.
Ran this by someone else and he found the cause of the issue. Though - it's not Gulp related at all it turns out.
The IDE I was using updated the folder and file structure instantly when I manually ran my 'components' task, however it did not do the same when I ran the gulp.watch task. I am happy to report though that the files were being created successfully, they just never appeared in the IDE until I killed the task.
The gulpfile.js I wrote is Common gulpfile.js.
In a build task, inject should inject all static files into html outputs, but it inject nothing in the clean build , I must run same command(here is gulp -p project build) twice(gulp -p project build && gulp -p project build) to inject them successful.
I have tried use run-sequence, it helps nothing.
Is this a bug?
Thanks :)
Your gulp tasks appear not to be returning their streams. If you do not return a stream from a task, then any other tasks that depend on it will not wait for the async behaviour to complete before running.
So more or less, what you're seeing is that you have two levels of things that have to happen: first your "script", "style", and "asset" tasks need to be completed, and then when everything's ready your "view" task can do its work. The first time you run it, all four tasks are run at nearly the same time (so "view" runs with old "asset" results, etc.)
To fix it, just return the working stream in each task:
gulp.task('style', ['check'], function () {
var less_filter = gulpFilter('**/*.less');
return gulp.src(path_current.src_path_style)
.pipe(less_filter)
// ... the rest of your pipes
.pipe(browserSync.reload({stream:true}));
});
I have two requirements for my build script:
When I run gulp clean build, clean must complete before build
starts.
If I run gulp build, then clean shouldn't run.
So, if clean is specified, then build should wait for it, else start.
The first part is possible if I do
gulp.task('clean');
gulp.task('build', ['clean']);
However, that violates point 2
If I do
gulp.task('clean');
gulp.task('build');
That violates point 1
Is this possible with gulp?
You cannot run two gulp tasks with the same command like you did with dependency management you want.
Anyway you can pass an argument to your build task that will allow, using a little ternary, to wait for the clean one to complete before running.
So something like this:
gulp.task('build', (process.argv[3] === '--clean') ? ['clean'] : null, function () {
...
});
This way, you can launch your build normally with
gulp build
And when you want to call it with the clean:
gulp build --clean
There is a lot of ways to get better argument handling, like yargs or the env of gulp-util. But I found my method nice in the fact that it doesn't need any extra dependency.
Looks like you can use Gulp-If
gulp.task('build', function() {
gulp.src('*.*')
.pipe(gulpif(condition, clean()))
.pipe(gulp.dest('./dist'));
});