Configure VSCode to execute different task - configuration

I have a TypeScript project in Visual Studio Code with the following task:
{
"version": "0.1.0",
// The command is tsc.
"command": "tsc",
// Show the output window only if unrecognized errors occur.
"showOutput": "silent",
// Under windows use tsc.exe. This ensures we don't need a shell.
"windows": {
"command": "tsc"
},
"isShellCommand": true,
// args is the program to compile.
"args": [],
// use the standard tsc problem matcher to find compile problems in the output.
"problemMatcher": "$tsc"
}
This works well when we hit "Ctrl + Shift + B" to build.
Is it possible to have another task that when we press "F5" to run/debug it runs a command through the command line?
Thank you.

TASK RUNNERS VS DEBUGGING PLUS LIVE PREVIEW
Task Runner
Currently, for VSCode version 0.5.0, you can use a task runner, identified in your task.json, to run multiple tasks using the same runner. At this time, configuring different tasks runners is not possible. For example, if you were using Gulp as a task runner you might have something like the following:
{
"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"args": [
"--no-color"
],
"tasks": [
{
"taskName": "serve-dev",
"isBuildCommand": false,
"isTestCommand": true,
"showOutput": "always",
"args": []
},
{
"taskName": "serve-build",
"isBuildCommand": false,
"isTestCommand": true,
"showOutput": "always",
"args": []
}
Now the Gulp tasks would be defined and coded with Gulp but the important thing to note is the isBuildCommand and isTestCommand as these correlate to CTRL+SHFT+B and CTRL+SHFT+T respectively. So these two tasks would be available as keyboard shortcuts. In addition, if you add additional tasks they will each be enumerated and accessible with CTRL+SHFT+P then type "RUN" then select "TASK: Run Task". Each of your tasks with be enumerated, listed and selectable.
The following code just demonstrates how eash VSCode task is related to a task runner task:
//automate build node server start and restart on changes
gulp.task('serve-build', ['optimize'], function () {
serve(false /* is Build */);
});
//automate dev node server start and restart on changes
gulp.task('serve-dev', ['inject'], function () {
serve(true /* is Dev */);
});
Debugging
Now for debugging with Node.js or Mono you have similar options. You will want to configure your launch.json or press the 'gear icon'. You can set the debugger to debug or run your app and use the VSCode 'F5' or PLAY button or menu's to start/stop/restart your app. From there you just use your favorite browser and access the server of your app. You can also use an external debugger to 'attach' to your app. Following is a sample launch.json:
{
"version": "0.1.0",
// List of configurations. Add new configurations or edit existing ones.
// ONLY "node" and "mono" are supported, change "type" to switch.
"configurations": [
{
// Name of configuration; appears in the launch configuration drop down menu.
"name": "Debug src/server/app.js",
// Type of configuration. Possible values: "node", "mono".
"type": "node",
// Workspace relative or absolute path to the program.
"program": "src/server/app.js",
// Automatically stop program after launch.
"stopOnEntry": true,
// Command line arguments passed to the program.
"args": [],
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
"cwd": ".",
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
"runtimeExecutable": null,
// Optional arguments passed to the runtime executable.
"runtimeArgs": [],
// Environment variables passed to the program.
"env": { },
// Use JavaScript source maps (if they exist).
"sourceMaps": false,
// If JavaScript source maps are enabled, the generated code is expected in this directory.
"outDir": null
},
{
// Name of configuration; appears in the launch configuration drop down menu.
"name": "Run src/server/app.js",
// Type of configuration. Possible values: "node", "mono".
"type": "node",
// Workspace relative or absolute path to the program.
"program": "src/server/app.js",
// Automatically stop program after launch.
"stopOnEntry": false,
// Command line arguments passed to the program.
"args": [],
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
"cwd": ".",
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
"runtimeExecutable": null,
// Optional arguments passed to the runtime executable.
"runtimeArgs": [],
// Environment variables passed to the program.
"env": { },
// Use JavaScript source maps (if they exist).
"sourceMaps": false,
// If JavaScript source maps are enabled, the generated code is expected in this directory.
"outDir": null
},
{
"name": "Attach",
"type": "node",
// TCP/IP address. Default is "localhost".
"address": "localhost",
// Port to attach to.
"port": 5858,
"sourceMaps": false
}
]
}
Notice the 'stopOnEntry' property for the RUN and DEBUG setups. This is how you can use the debugger to run or debug the app. From there you would just use the debug 'PLAY' button combined with the debug menu to select the appropriate configuration.
Live Preview
Live Preview is not currently implemented in VSCode. Two of my favorites so far are BrowserSync and Live.JS.
GULP TASK WITH NODEMON
Following is some code that may help point the way to configuring Gulp to run a node.js server. Remember that Gulp tasks can require other tasks to run first. In the code above, the Gulp task "serve-build" requires another task "optimize" to run first. "optimize" can require other tasks to run and so forth.You can chain these tasks so that your top level tasks run all of your sub-level tasks. Following is a function that's executed from a Gulp task in the gulpfile.js setup:
function serve(isDev) {
log('Start pre processes and node server...');
var nodeOptions = {
script: config.nodeServer,
delayTime: 3,
env: {
'PORT': port,
'NODE_ENV': isDev ? 'dev' : 'build'
},
watch: [config.server]
};
return $.nodemon(nodeOptions)
.on('restart', ['vet'], function (ev) {
log('*** nodemon restarted');
log('files changes on restart:\n' + ev);
setTimeout(function () {
browserSync.notify('reloading now ...');
browserSync.reload({ stream: false });
}, config.browserReloadDelay);
})
.on('start', function () {
log('*** nodemon started');
startBrowserSync('isDev');
})
.on('crash', function () {
log('*** nodemon crashed: script crashed for some reason');
})
.on('exit', function () {
log('*** nodemon exited cleanly');
});
}
So the following Gulp tasks actually just run this function which runs nodemon via the Gulp nodemon plugin to make production / "build" or test / "dev" builds using a parameter variable:
//automate build node server start and restart on changes
gulp.task('serve-build', ['optimize'], function () {
serve(false /* is Build */);
});
//automate dev node server start and restart on changes
gulp.task('serve-dev', ['inject'], function () {
serve(true /* is Dev */);
});
MAPPING GULP TASKS TO THE VSCODE TASK RUNNER
Finally, you can map your top-level Gulp tasks like "serve-dev"
and "serve-build" by adding entries to your VSCode tasks.json and using isBuildCommand and isTestCommand to map to CTRL+SHFT+B and CTRL+SHFT-T respectively.
{
"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"args": [
"--no-color"
],
"tasks": [
{
"taskName": "serve-dev",
"isBuildCommand": false,
"isTestCommand": true,
"showOutput": "always",
"args": []
},
{
"taskName": "serve-build",
"isBuildCommand": false,
"isTestCommand": true,
"showOutput": "always",
"args": []
}
VSCode Output
VSCode also has a task.json property to show output of your running tasks in VSCode. This will open the OUTPUT window of VSCode just like using SHFT+CTRL+H or selecting the menu VIEW then selecting SHOW OUTPUT. At this time the output window does not display color.
Just set "showOutput" to always. Perhaps this could replace your need to start a terminal/command line window thats running your node app. You can also set this property to never or silent depending on your needs. You can find more info about these properties in the VSCode documentation.
You can also STOP a running task by with CTRL-SHFT-B or CTRL-SHFT-T or use the menus after starting a task.
Finally, if you must compile your code and run the app in a terminal I think you will need to use a script/batch file in your task.json configuration that runs your task runner and then starts your node server.

If you don't want to use gulp and just do the typescript compilation then a simple way is to go to terminal and run tsc -w <filename.ts>, no need of tasks.json.
It watches for file changes and converts them to js files.
Then whenever you hit 'F5' it should run the updated js file pointed in launch.json.
If you want tsc to convert mutiple ts files you can also add tsconfig.json in your application root with "rootdir", then just run tsc -w and F5 to execute application.
sample tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "ES5",
"outDir": "<js dir>",
"rootDir": "<point to all ts dir>"
}
}

I believe this was solved by a later feature, namely the pre launch task. You can have it run a task before it launches node/Chrome with F5.
http://tstringer.github.io/javascript/vscode/nodejs/gulpjs/2015/10/14/vscode-prelaunchtask.html

Related

Inline sourcemaps generated by gulp-sourcemaps not working in VS-code debugger

I am trying to generate source-maps with a gulp task. I'm transpiling my code with Babel, and I would like to be able to use the debugger from VS Code. I don't know a lot about source-maps, and my way of determining if they are valid or not is to attempt using the debugger with breakpoints (if it stops on the breakpoints, then it works).
Here is my script:
// src/main.js
const i = 1;
const n = 2*i; // breakpoint on this line
console.log(n);
And here is my configuration for the debugger:
//.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/dist/main.js"
}
]
}
The command npx babel src --out-dir dist --source-maps transpiles my code and a .js.map file is created in the dist folder.
Executing the debugger configuration from above works as intended. The debugger stops on the breakpoint.
The command npx babel src --out-dir dist --source-maps inline transpiles my code and the source maps are embedded within the .js output file.
Executing the debugger configuration from above also works as intended. The debugger stops on the breakpoint.
This shows that my debugger configuration should be working for both inline and external source maps.
I created the following Gulp task for the transpilation of my code.
import {dest, src} from "gulp";
import babel from "gulp-babel";
import sourcemaps from "gulp-sourcemaps";
function transpile() {
return src("src/**/*.js")
.pipe(sourcemaps.init())
.pipe(babel())
.pipe(sourcemaps.write(
".",
{
includeContent: false,
sourceRoot: "../src"
}))
.pipe(dest("dist"));
}
export {transpile};
The command npx gulp transpile executes this task and a .js.map file is created in the dist folder.
Executing the debugger configuration from above works as intended. The debugger stops on the breakpoint.
I then edited the Gulp task above so that it would give me inline source maps:
import {dest, src} from "gulp";
import babel from "gulp-babel";
import sourcemaps from "gulp-sourcemaps";
function transpile() {
return src("src/**/*.js")
.pipe(sourcemaps.init())
.pipe(babel())
.pipe(sourcemaps.write())
.pipe(dest("dist"));
}
export {transpile};
The command npx gulp transpile executes this task and the source maps are embedded in my output file.
However, the debugger doesn't stop on the break point.
I've not been able to understand why so far.
Since this is the only case where the debugger doesn't work, I believe the debugger is not the source of the problem. It must be linked to the source map.
Any idea?
Thanks a lot!

Protractor/Selenium embedded credentials dropped support for chrome

I am currently managing a staging environment with some authentication.
I was able to run my tests by embedding credentials to URL like this:
https://johndoe:foobar#app.s.product.com/#login
However, my tests fail because of chrome, dropping this feature(https://www.chromestatus.com/feature/5669008342777856). Is there any other way I can access our staging site? I tried inspecting the popup for credentials and maybe I can sendKeys(), but to no avail.
Thanks in advance!
Have this problem too. My solution is creation chrome extension and add it to chrome on startup.
Create two files in some new folder:
background.js (change user and path with yourth)
chrome.webRequest.onAuthRequired.addListener(
function(details, callbackFn) {
console.log("onAuthRequired!", details, callbackFn);
callbackFn({
authCredentials: {username: "user", password: "pass"}
});
},
{urls: ["<all_urls>"]},
['asyncBlocking']
);
manifest.json
{
"manifest_version": 2,
"name": "Authentication for tests",
"version": "1.0.0",
"permissions": ["<all_urls>", "webRequest", "webRequestBlocking"],
"background": {
"scripts": ["background.js"]
}
}
Pack them into crx (chrome://extensions/ -> Pack extension)
Add this file to project
Add to conf.js:
As first line
var fs = require('fs');
const ext64 = fs.readFileSync('./ext.crx', 'base64');
exports.config = {
...
and to chrome options
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['--no-sandbox'],
extensions: [ext64]
}
},

Visual Studio Code. Build gulp task has no effect. Nothing happens, output is empty

I am trying to run build task in VS Code. Unfortunately, nothing happens when I attempt to execute the task from the task runner or with a hot-key combo (shift+ctrl+b). The OUTPUT window (with tasks dropdown) is empty.
My task.json file content:
{"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"tasks": [
{
"taskName": "deploy",
"isBuildCommand": true,
"showOutput": "always"
}]}
My gulpfile.js is on root application folder
var gulp = require('gulp');
var plugins = require("gulp-load-plugins")();
var karma = require("karma");
function getTask()
{
var srvInst = new karma.Server({
configFile: __dirname + "/karma.conf.js",
});
return srvInst.start();
}
//build task
gulp.task("deploy",function(){
plugins.util.log("done");
});
//test task
gulp.task("test",getTask());
This is simplified versions of files, but the problem remains. I'm wondering why the OUTPUT is empty. Where can I find any clue what is wrong?
I manage to find the cause of the problem. It is possible to debug gulp task with help of node debugger and I find out that it is gulp.task("test",getTask()); playing tricks on me and on OUTPUT. Even if I execute build command, the getTask function is called because of mistaken execution getTask().
The question now is following - empty OUTPUT is a bug or a feature in such context. Should I report about it or it is totally my fault?

Gulp bundle only if source files changed

I'm pretty new to gulp, so hopefully this is an easy one.
I'm trying to genereate a number of bundles, each of which will be composed of a bunch of js/css files (sourced from a file), but I only want to build each bundle if any of it's source files changed.
My starting code looks like the following. What do I need to add to make it work?
gulp.task('bundle', function () {
return gulp
.src(sourceFile)
.pipe(bundle())
.pipe(gulp.dest(buildDest))
.pipe(bundle.results({
pathPrefix: '/bundlePath/',
dest: manifestDest
}));
});
sourceFile:
module.exports = {
bundle: {
"bundle1": {
"scripts": [
"file1.js",
"file2.js",
"file3.js"
],
"styles": "style1.css"
},
"bundle2": {
"scripts": [
"file1.js",
"file4.js"
],
"styles": [
"style1.css",
"style2.css"
]
}
}
}
For example, if only file1.js changes, I want both bundle1 and bundle2 rebuilt since they share file1.js. If only file4.js changes, only bundle2 should be rebuilt.
This process is kicked off when the release version of the project is built in VS2012.
I looked into alternative packages like gulp-changed, but they seem to only work with single files (correct me if I'm wrong).

"require not defined" when testing with proxyquireify stubs

Hello i have a project that uses gulp for the build framework, and used karma with jasmine for the testing.
I am trying to integrate proxyquireify to mock the requires, i just added proxyquireify as browserify plugin in karma config, as i am using karma-browserify.
But this results in an error when running the tests, in the first line, saying 'require is undefined'.
What am i doing wrong?
here is my karma config
// Karma configuration
// Generated on Wed Nov 26 2014 17:57:28 GMT+0530 (IST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['browserify', 'jasmine'],
// list of files / patterns to load in the browser
files: [
'./components/renderer/**/*.spec.js',
'./components/tracker/**/*.spec.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'./components/**/*.spec.js' : [ 'browserify' ]
},
browserify: {
debug:true,
plugin: ['proxyquireify/plugin']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['spec'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
proxyquireify works internally by substituting the require function provided by browserify.
In this case it seems the new substituted require function was not exposed to global scope.
I went through the code and found out proxyquireify creates the new require function in node_modules/proxyquireify/lib/prelude.js named as newRequire.
the issue i was having was that the newRequire function was not exposed in the global scope as the require function, so i changed node_modules/proxyquireify/lib/prelude.js so that
// Override the current require with this new one
return newRequire;
becomes
// Override the current require with this new one
require = newRequire;
and the newRequire was properly exposed to global scope and everything worked fine. Since this change is reset every time i do a npm install, i created a gulp task in my case which does this change every time before tests are run, i will add the gulp task for reference
// Task to modify proxyquireify so that it works properly, there is a bug in the npm library
gulp.task('_patch:proxyquireify', function() {
gulp.src(['./node_modules/proxyquireify/lib/prelude.js'])
.pipe(replace(/return newRequire;/g, 'require = newRequire;'))
.pipe(gulp.dest('./node_modules/proxyquireify/lib'));
});
I run this task before executing the test tasks, like this
// Task to run tests
gulp.task('run:test', ['_patch:proxyquireify'], function() {
//logic to run tests
};
I hope this helps, thanks