Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relative SourceMap paths for debugging in WebStorm #238

Closed
szag opened this issue Apr 14, 2014 · 44 comments
Closed

Relative SourceMap paths for debugging in WebStorm #238

szag opened this issue Apr 14, 2014 · 44 comments

Comments

@szag
Copy link

szag commented Apr 14, 2014

I'd like to debug an application's JavaScript source files in WebStorm using SourceMaps. However this does not work with SourceMap files generated by webpack (devtool: source-map).

It seems that the path mapping to the original files is not provided in a way which WebStorm and maybe other tools can understand. It does work with a SourceMap generated using r.js together with Almond. These source maps use relative paths to point to the original files instead of webpack-module:// URLs.

Is there a way to make webpack generate relative path information for the sources of a SourceMap? Or any other solution?

Example

Consider a project structure to be like this:

project/
  app/
    bower_components/
        a/
          lib.js
    src/
       main.js
       example.js
    index.html

  build
    src/
       main.js
       main.js.map
    index.html

Webpack SourceMap

The application source files residing in app/ are built to the build/ dir, with main being the entry chunk.
For specifying the source files the simplified main.js.map generated by webpack contains:

{
    "sources":["webpack/bootstrap fc4e6211bca39864adc8","./main.js","./example.js","../bower_components/a/lib.js"],
    "sourceRoot":"webpack-module://"
}

Thus according to the spec the URL to example would be webpack-module://./example.js because the sourceRoot is simply prepended. This can be seen in the Firefox dev tools where every source file URL would be displayed this way without any grouping by directory. Chrome dev tools seem to be a bit cleverer and group sources located in ../ or ./ in a tree view. In both browsers setting a breakpoint for debugging works. Perhaps because the sourcesContent is included so the original source files are not required.

However in WebStorm it is not possible to set a breakpoint in app/src/example.js and debug the build/index.html so that the breakpoint is hit. Also it is not possible to view the source by navigating to it using the Debug > Structure | Text | Scripts panel.

r.js SourceMap with relative paths

The debugging in webstorm does work by changing the main.js.map to a format as generated by r.js:

{
    "sources":["../../app/src/main.js","../../app/src/example.js","../../app/bower_components/a/lib.js"]
}

By omitting sourceRoot and using relative paths to the source files (which are served by WebStorms built-in server) WebStorm seems to be able to find the correct source files.
Also the Firefox dev tools are now grouping the source files by directory which aids navigation.

@sokra
Copy link
Member

sokra commented Apr 17, 2014

I'll investigate...

@jhnns
Copy link
Member

jhnns commented Apr 17, 2014

👍

@szag
Copy link
Author

szag commented Apr 22, 2014

Thanks. Looking forward to a solution!

@marshallswain
Copy link

Could this be related to this message that I only get in the Firefox dev console?:

SyntaxError: Using //@ to indicate sourceMappingURL pragmas is deprecated. Use //# instead vendors.js:301
Error: http://localhost/assets/vendors.js is being assigned a //# sourceMappingURL, but already has one

@fresheneesz
Copy link
Contributor

I'm also wondering what's going on here, and what to do about the webpack-module:// sourceRoot. I get the feeling that's not how sourceRoot is intended to be used. I'm adding source map support for my unit testing library, and I can't quite reconsile the source map spec with webpack's behavior here.

I'm using source-map to use source map files, and it does indeed return paths like webpack-module://./example.js, which a browser obviously isn't going to handle.

So either I should strip off sourceMap.sourceRoot from sourceMapLineInfo.source, or webpack shouldn't be using webpack-module:// as the source root. Anyone know which of these is the case?

@charandas
Copy link

+1 this would be helpful for us WebStorm users.

@sokra
Copy link
Member

sokra commented Jul 18, 2014

If somebody want to make a PR for this, add a [relative-resource-path] here. Than you could do:

plugins: [
  new webpack.SourceMapDevToolPlugin(
    sourceMapFilename, null,
    "../../[relative-resource-path]", "../../[relative-resource-path]")
]

I don't use WebStorm and cannot test it...

@jhnns
Copy link
Member

jhnns commented Jul 21, 2014

@szag

@byelims
Copy link

byelims commented Jul 25, 2014

I investigate the source map built by Browserify, and find that it just uses absolute paths. So I modify SourceMapDevToolPlugin.js a little like this:

function SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate) {
    this.sourceMapFilename = sourceMapFilename;
    this.sourceMappingURLComment = sourceMappingURLComment || "\n//# sourceMappingURL=[url]";
    // just modify two templates
    this.moduleFilenameTemplate = moduleFilenameTemplate || "[absolute-resource-path]";
    this.fallbackModuleFilenameTemplate = fallbackModuleFilenameTemplate || "[absolute-resource-path]";
}

It works in WebStorm. I believe relative paths will work, too.

@sokra
Copy link
Member

sokra commented Jul 25, 2014

So you could do this?

plugins: [
  new webpack.SourceMapDevToolPlugin(
    sourceMapFilename, null,
    "[absolute-resource-path]", "[absolute-resource-path]")
]

@byelims
Copy link

byelims commented Jul 25, 2014

Oh yeah, it works! Just remove devtool in config and use that instead.

I'm new to webpack, didn't know how to use plugins. :P

@charandas
Copy link

I am not using devtool and only using the above plugins definition like so:

plugins: [
        new webpack.SourceMapDevToolPlugin(
            'bundle.js.map', null,
            "[absolute-resource-path]", "[absolute-resource-path]")

The map is generating fine and looks legit but webstorm does something weird: I have to put the breakpoints in the bundle JS, it does track back to correct source. Breakpoints in the original source don't work.

What might I be missing?

code-splitting: not pertinent, my comment previously mentioned it

@byelims
Copy link

byelims commented Sep 17, 2014

@kbdaitch If you are using React, jsx-loader doesn't generate source map now. Plain JS works fine here.

@charandas
Copy link

@byelims Thanks but I am not using react. Some more details:

  1. Most of my requires are amd style.
  2. Using exports-loader and noParse with angular and jQuery.
  3. Using the latest 1.4 beta webpack.

@charandas
Copy link

@sokra this is whole webpack config, if it helps:

// webpack.config.js
var webpack = require('webpack');
var path = require('path');

module.exports = {
    entry: path.join(__dirname, '../app/js/main.js'),
    output: {
        path: path.join(__dirname, '../app/bundle'),
        publicPath: '/app/bundle/',
        filename: 'bundle.js'
    },
    resolve: {
        root: [
            path.join(__dirname, '..', 'app', 'lib'),
            path.join(__dirname, '..', 'app', 'js'),
            path.join(__dirname, '..', 'app', 'themes'),
        ],
        alias: {
            jquery$: 'jquery/jquery',
            angular$: 'angular/angular',
            angularAnimate$: 'angular-animate/angular-animate',
            angularResource$: 'angular-resource/angular-resource',
            angularSanitize$: 'angular-sanitize/angular-sanitize',
            angularUiRouter$: 'angular-ui-router/angular-ui-router',
            angularPermission$: 'angular-permission/angular-permission',
            foundation$: 'foundation/js/foundation.min',
            lodash$: 'lodash/lodash',
            _$: 'lodash/lodash'
        }
    },
    resolveLoader: {
        root: [
            path.join(__dirname, 'node_modules')
        ]
    },
    module: {
        loaders: [
            { test: /\.css$/, loaders: ['style/useable', 'css'] },
            { test: /[\/\\]angular\.js$/, loader: 'exports?window.angular' },
            { test: /[\/\\]jquery\.js$/, loader: 'exports?window.$' }
        ],
        noParse: [
            /[\/\\]angular\.js$/,
            /[\/\\]jquery\.js$/
        ]
    },
    plugins: [
        new webpack.SourceMapDevToolPlugin(
            'bundle.js.map', null,
            "[absolute-resource-path]", "[absolute-resource-path]")

    ]
};

@sokra
Copy link
Member

sokra commented Sep 19, 2014

@kbdaitch I don't have WebStorm, so I can't help here.

If you are using Code Splitting, you'll need to specify:

 new webpack.SourceMapDevToolPlugin(
            '[file].map', null,
            "[absolute-resource-path]", "[absolute-resource-path]")

@RReverser
Copy link
Contributor

Any updates on this? Doesn't look like it was implemented, but closed for some reason. Would be great to have [relative-resource-path] as suggested by @sokra.

@Agamennon
Copy link

Man this problem was driving me mad, i was fiddling with configs in the hopes of being able to debug in webstorm, to no avail, and now i find this! the issue is closed so what is the solution?

@Agamennon
Copy link

i am just using the react-hot-boilerplate (its totaly minimum and uses babel) i just added this to the config and removed the devtool:'eval' entry

plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new webpack.SourceMapDevToolPlugin(
        '[file].map', null,
        "[absolute-resource-path]", "[absolute-resource-path]")
  ],

and it freezes the debugger, using webstorm (it works fine inside chrome) if i refresh the browser i can hit a breakpoint but its takes me to the bundle.js file and not to the app.js file i have no clue now how to proceed

@develar
Copy link

develar commented Jun 11, 2015

See https://youtrack.jetbrains.com/issue/WEB-14000#comment=27-1013153 Webpack is a great tool and I can confirm, that if something doesn't work — it is WebStorm issue, but not webpack. WebStorm 11 EAP will be soon, feel free to ping me / file issues to JetBrains tracker.

@iamstarkov
Copy link

@develar is WebStorm 11 already out?

@Agamennon
Copy link

Only the EAP, and as far as I can see it does not solve this issue yet, debugging inside chrome works, the issue is real, perhaps will get attention before final release

@jeloi
Copy link

jeloi commented Sep 26, 2015

+1

@bholloway
Copy link

I tried the new webpack.SourceMapDevToolPlugin() method shown by @sokra above but I got two instances of the plugin with my explicit instance getting trumped by the second instance from WebpackOptionsApply.js. I presume this originally worked but that the code has moved on.

However upon inspecting the code I found that I can use the configuration output option to achieve the same thing.

output : {
    ...
    devtoolModuleFilenameTemplate        : '[absolute-resource-path]',
    devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
}

For me I get paths relative to the project root, which is exactly what I wanted.

From previously implementing this in Browserify I can tell you that you also need to do the following or it just won't work.

  • Ensure that your combination of loaders and plugins produced impecable source maps. Definitely make use of the source-map-visualization tool. Personally I use esmangle over Uglify because of big problems with this in Browserify.
  • Ensure your minifier does not convert statements to sequences or breakpoints will appear flaky. Once again esmangle is an option here.
  • Ensure you are serving your project root. I am using BrowserSyncPlugin with baseDir not the project root, so I add routes: {'/': ''} in the plugin options.
  • Ensure that your Webstorm debug configuration specifies a remote URL.
  • Test lots of different breakpoints on different types of statements before you tell your whole team how awesome you and Webpack are.

My working todo project is here.

Thanks to everyone who has commented this issue, otherwise I would never have figured it out!

P.S. Do we still want to implement [relative-resource-path]? I do not need it but I could take a look.

@SimenB
Copy link
Contributor

SimenB commented Sep 30, 2015

@samunro
Copy link

samunro commented Sep 30, 2015

I was able to get relative paths based on the information that bholloway provided in his answer but did have to adjust the configuration that he had supplied - maybe there is a difference in versions? I am using webpack 1.12.2 which is currently the latest available (https://www.npmjs.com/package/webpack).

I just had to drop the 'devtool' prefix. I also went with the [resourcePath] macro which is the one that is used as the default in webpack.SourceMapDevToolPlugin.

moduleFilenameTemplate: "[resourcePath]",
fallbackModuleFilenameTemplate: "[resourcePath]?[hash]"

Here is the relevant code. Note that although there are parameters with these names, they are ignored if an options parameter is passed - not very helpful.

function SourceMapDevToolPlugin(options, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate) {
    if(!options || typeof options !== "object") {
        this.sourceMapFilename = options;
        this.sourceMappingURLComment = sourceMappingURLComment === false ? false : sourceMappingURLComment || "\n//# sourceMappingURL=[url]";
        this.moduleFilenameTemplate = moduleFilenameTemplate || "webpack:///[resourcePath]";
        this.fallbackModuleFilenameTemplate = fallbackModuleFilenameTemplate || "webpack:///[resourcePath]?[hash]";
        this.options = {};
    } else {
        this.sourceMapFilename = options.filename;
        this.sourceMappingURLComment = options.append === false ? false : options.append || "\n//# sourceMappingURL=[url]";
        this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack:///[resourcePath]";
        this.fallbackModuleFilenameTemplate = options.fallbackModuleFilenameTemplate || "webpack:///[resourcePath]?[hash]";
        this.options = options;
    }
}

@amcsi
Copy link

amcsi commented Jan 25, 2016

I'm sorry, I'm confused about all the information going on in this ticket.

I tried doing what was in this comment: #238 (comment)

namely:

output : {
    ...
    devtoolModuleFilenameTemplate        : '[absolute-resource-path]',
    devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
}

And with that my source maps were appearing with absolute path prefixes. But when I entered debug mode with nodejs, then in the Scripts tab only the "dist/" and "node_modules/" were appearing as folders; the entire "app/" folder with all my actual sources weren't even there.

When the prefix was webpack:/// before making the above changes, at least all my sources were appearing in the Sources tabs under the "webpack:///./" and similar webpack style folder names. AND with that setup what I was getting is the same as in this comment: #238 (comment)
Namely that breakpoints in my actual sources didn't work, but they did in the compiled files, and doing "Step Over" would take me straight over to the source.

I'm using PHPStorm 10, which is a superset of WebStorm 11

@develar
Copy link

develar commented Jan 25, 2016

@amcsi it is our issue — https://youtrack.jetbrains.com/issue/WEB-19984 I can definitely promise that it will be fixed in the next PHPStorm 11 EAP.

@amcsi
Copy link

amcsi commented Jan 25, 2016

Thank you, @develar. So will there basically be something like mappings for JavaScript Debug, but for Node.Js? Because that's what seems to be missing.

@develar
Copy link

develar commented Jan 25, 2016

@amcsi No, it will be smart magic solution — ’’ If you pay money for a smart IDE and then read "you have to configure"... Yes, it is not what you expect from a smart developer tool." (see https://docs.google.com/document/d/19rmW6PGpIIx57ntk4M_1x6F0t-0qO2weCtNKWQJaemA/edit) We are not going to step back and return mappings configuration to NodeJS Debug RC. (but inlining sources into sourcemap may be required — Electron main debug implemented in this way in the recent WebStorm 12 EAP).

@amcsi
Copy link

amcsi commented Jan 25, 2016

Oh goodie, thanks for clarifying!

@antigremlin
Copy link

@amcsi and @develar, if the problem is experienced on Windows it can be caused by a path handling bug in Webpack that I've fixed recently. The problem was that absolute paths were used on Windows because of the different path separator. The bugfix is PR #1909 and it is now included into 1.12.12. It has been merged to the master branch several weeks ago.

Could you test your set-up with 1.12.12 and report if there is any difference?

@develar
Copy link

develar commented Jan 25, 2016

@antigremlin That's great! Our users reports about this problem and right now I am checking that my fix is working on windows due to this bug (" absolute paths were used on Windows " instead of "/./"). Thanks. I will check 1.12.12.

@amcsi
Copy link

amcsi commented Jan 25, 2016

@antigremlin unfortunately my issue is happening on Linux

@antigremlin
Copy link

@develar I hadn't tested this extensively but in my case the bugfix worked with WebStorm -- the Scripts tab shows relative filenames. I didn't have to change any of the devtool templates. What is not working is the Visualize Source Map command -- seems like it doesn't do anything.

Another thing that was not working is debugger breakpoints while running tests in Chrome with Karma, because the Chrome is launched with a clean profile and there is no JetBrains IDE support extension. To fix this I had to make a change to karma-chrome-launcher, which is now merged to master, see karma-runner/karma-chrome-launcher#65. I can give you more details if you are interested.

@antigremlin
Copy link

@amcsi Can you still try with webpack 1.12.12. and without any tweaks to devtool templates? Can you share some details on the project set-up (libraries, build system, etc.)?

@amcsi
Copy link

amcsi commented Jan 25, 2016

@antigremlin

Now that I actually upgraded my webpack in my local dependencies (my global webpack was already the correct version), I can hardly believe it, but it works!

Now all I need to do is something about the terribly slow running process when debugging is enabled, i.e. when my application is run with /usr/bin/node --debug-brk=40258 --nolazy --harmony dist/server.js by PhpStorm's Debug run.

By the way, this is the state of my project: https://github.com/amcsi/szeremi/tree/90e0e8e4c61dc3c1d731815e5542226e0611226f

@amcsi
Copy link

amcsi commented Jan 25, 2016

Okay, I feel like I spoke too soon.

It does stop at a breakpoint in the source server.js file, however it's all very limited.
Like I said, it's extremely slow (1-5 seconds PER LINE). I'm actually talking about it here: nodejs/node-v0.x-archive#9125 (comment)
Also, breakpoints do not work at import declarations at all.
Also, often even if there's a function call and I press F7 to Step In, it just steps over (in 1-5s as usual).
And when typing in the localhost URL to try a breakpoint in one of the route callbacks... well it loads forever.

So as it is, it's completely unuable unfortunately :(

@develar
Copy link

develar commented Jan 26, 2016

@amcsi Issue on our side was fixed yesterday — please see https://youtrack.jetbrains.com/issue/WEB-19984 (verification on windows in progress).

Slow debug — depends on nodejs/node#4231 and nodejs/node#3875

@richb-hanover
Copy link

Not sure if this is entirely helpful, but I got the following info about debugging webpack apps from WebStorm from WEB-20781.

I summarized the information for WebStorm 2016.1 (final) in my blog: http://richb-hanover.com/debugging-webpack-apps-with-webstorm-2016-1/

@Vloz
Copy link

Vloz commented Apr 7, 2016

Same issue with Visual Studio Code, it seems to not support Webpack:// uri, but does support relative path (relative to the output file) and absolute path.

But #238 (comment) alone isnt working since it doesnt update "sourceRoot" that need to be set to "/" to properly work.

Cant find any information on how to modify the sourceRoot with webpack, any help? :'(

@cellvia
Copy link

cellvia commented May 5, 2016

+1 !!!!!

debugging not working in VS2015, even using this plugin: https://www.npmjs.com/package/vs-fix-sourcemaps and solutions mentioned in the above comments do not work either...

sokra added a commit that referenced this issue May 5, 2016
simplified option passing

fixes #238
@kongu-zz
Copy link

Hi
As I see Sokra added this option
Can anybody write example of webpack config to debug in VS Code?

@Vloz
Copy link

Vloz commented May 11, 2016

I m not sure (because i was trying lot of things) but it looks like VsCode last update 1.1.0 no longer struggle with unset sourceRoot.

Here is an example of use set sourceRoot for those who are still interested, but it's only available for webpack2: http://pastebin.com/xSN4pk6i

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests