AlexB
AlexB

Reputation: 695

Webstorm debugging with source maps from Browserify and Typescript

My project is a Laravel site, and I have the public folder renamed to "html". So my public files look like:

html
--js
----main.ts

And html is technically the root of the site for debugging purposes.

Using browserify, I have now generated some source maps for bundle.js, which have paths for main.ts. The problem is that they are pointing to the full path:

"html/js/main.ts"

Usually, I can run configurations to the html folder and catch breakpoints.

http://myapp.app:8000 ->> project>html 

But this is not hitting breakpoints, since the html folder doesn't really exist in this setup. What's strange is that I can set break points in Chrome tools and it works. How can I set up Webstorm so it will hit break points in the html folder?

EDIT:

I am using the following gist for my source maps.

/**
 * Browserify Typescript with sourcemaps that Webstorm can use.
 * The other secret ingredient is to map the source directory to the
 * remote directory through Webstorm's "Edit Configurations" dialog.
 */
'use strict';

var gulp = require('gulp'),
    browserify = require('browserify'),
    tsify = require('tsify'),
    sourcemaps = require('gulp-sourcemaps'),
    buffer = require('vinyl-buffer'),
    source = require('vinyl-source-stream');

var config = {
    client: {
        outDir: './public/scripts',
        out: 'app.js',
        options: {
            browserify: {
                entries: './src/client/main.ts',
                extensions: ['.ts'],
                debug: true
            },
            tsify: {
                target: 'ES5',
                removeComments: true
            }
        }
    }
};

gulp.task('client', function () {
    return browserify(config.client.options.browserify)
        .plugin(tsify, config.client.options.tsify)
        .bundle()
        .on('error', function (err) {
            console.log(err.message);
        })
        .pipe(source(config.client.out))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(sourcemaps.write('./', {includeContent: false, sourceRoot: '/scripts'}))
        .pipe(gulp.dest(config.client.outDir));
});

Upvotes: 4

Views: 2313

Answers (1)

AlexB
AlexB

Reputation: 695

I fixed it in Webstorm. The correct remote url for the html folder in run configurations is:

http://myapp.app:8000/js/html

Pretty weird, but Webstorm thinks that /js/html is a folder and that the source files are inside there.

EDIT 1 :Let me edit this answer. It turns out that the snippet above wasn't giving me all of the source maps. When inspecting the map file, the sources were being listed as js files and not ts files, which meant that the debugger wouldn't catch break points.

Here is the working gulp task, which watches any Typescript file for changes (as long as it's a dependency of main.ts and triggers browserify and the new sourcemaps. It requires the tsify plugin.

'use strict';

var watchify = require('watchify');
var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var assign = require('lodash.assign');

// add custom browserify options here
var customOpts = {
    entries: ['./html/js/main.ts'],
    debug: true
};
var opts = assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts));
gulp.task('bundle', bundle); // so you can run `gulp js` to build the file
b.on('update', bundle); // on any dep update, runs the bundler
b.on('log', gutil.log); // output build logs to terminal
b.plugin('tsify')

function bundle() {
    return b.bundle()
        // log errors if they happen
        .on('error', gutil.log.bind(gutil, 'Browserify Error'))
        .pipe(source('bundle.js'))
        // optional, remove if you don't need to buffer file contents
        .pipe(buffer())
        // optional, remove if you dont want sourcemaps
        .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
        // Add transformation tasks to the pipeline here.
        .pipe(sourcemaps.write({includeContent: false, sourceRoot: './'})) // writes .map file
        .pipe(gulp.dest('./html/js'));
}

Upvotes: 3

Related Questions