Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging with webpack, ES6 and Babel

This seems like something that should have been relatively simple to achieve, but alas.

I have ES6 class:

'use strict';

export class BaseModel {  
    constructor(options) {
        console.log(options);
    }
};

and root module that uses it:

'use strict';

import {BaseModel} from './base/model.js';

export let init = function init() {
    console.log('In Bundle');
    new BaseModel({a: 30});    
};

My target is:

  1. pass the above through Babel, to get ES5 code
  2. pack the modules with webpack
  3. be able to debug the result

After some trial, this is the webpack config that I have:

{
    entry: {
        app: PATH.resolve(__dirname, 'src/bundle.js'),
    },
    output: {
        path: PATH.resolve(__dirname, 'public/js'),
        filename: 'bundle.js'
    },        
    devtool: 'inline-source-map',
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel'
            }
        ]        
    }
}

This seems to be working, to an extent.

So, I can do that:

devtools breakpoint screenshot

I can click F11 and enter the code, but I can't evaluate BaseModel:

erro in console evaluation

which kinda defeats the purpose (or one of purposes) of debugging.

I've tried adding source-map-loader in various order with babel-loader:

{
    test: /\.js$/,
    loader: "source-map-loader"
}

to no avail.

Side note 1: if I abandon webpack and just compile my modules with source maps via Babel into, say, System.js:

babel src/ --out-dir public/js/ --debug --source-maps inline --modules system
  • all works properly.

enter image description here

Side note 2: this ?sourceMaps=true doesn't seem to do anything at all, since, if I remove source map configuration from webpack - no source maps are preserved/generated at all. One would expect the initial, Babel-produced, source maps to be preserved in the resulting files. Nope.

Any suggestions would be greatly appreciated

like image 307
ZenMaster Avatar asked Aug 25 '15 18:08

ZenMaster


People also ask

Can I use Babel with Webpack?

There is a specific folder structure to be followed when using Webpack and Babel in your project. We need two separate folders, dist for the output files and src for the input files. You have to keep the index. html file inside the dist folder.

Is Webpack and Babel same?

Babel can be classified as a tool in the "JavaScript Compilers" category, while Webpack is grouped under "JS Build Tools / JS Task Runners".

Can Webpack work without Babel?

No unless all dependencies of your project supports ES6. There is one serious incompatibility: import is asynchronous while require() is synchronous.

Can you debug Webpack?

Click the "inspect" link under each script to open a dedicated debugger or the Open dedicated DevTools for Node link for a session that will connect automatically. You can also check out the NiM extension, a handy Chrome plugin that will automatically open a DevTools tab every time you --inspect a script.


3 Answers

You'll need to use the compiled variable names, not the originals. Source maps only allow the browser to display the source code that corresponds to the compiled code; they can't make the browser resolve original variable names from the compiled code.

To see the compiled variable names, either switch to the compiled source, or look in the Scope Variables pane on the right, which will show you (like it says on the tin) what variables exist in the current scope.

IIRC Babel tends to prefix module names with _, so your BaseModel variable is probably called _baseModel or similar.

like image 25
Jordan Running Avatar answered Oct 17 '22 04:10

Jordan Running


This is an issue with Javascript source maps, which don't currently support mapping symbol names, and babel, which changes the names of import-ed modules when compiling to CommonJS from ES2105 module syntax.

Babel does this to fully support the fact that ES2015 modules export bindings by resolving all references to imports whenever they are used in code, instead of at import time.

If you aren't writing modules that depend on exporting bindings (as is likely, since you couldn't actually do this with CommonJS), then you may prefer to preserve variable names when transpiling ES2015. I created an alternative to the native babel commonjs module transform for Babel 6 that preserves variable names: babel-plugin-transform-es2015-modules-commonjs-simple. This is a drop-in replacement for babel-plugin-transform-es2015-modules-commonjs, the native babel transform.

You can use this with webpack or node. A typical config might be:

npm install --save-dev babel-preset-es2015-webpack
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs-simple

The module babel-preset-es2015-webpack is a fork of the standard es2015 preset that does not include the module transform, because you want to use the alternate version. This works for node also. These modules are used in .babelrc:

{
    "presets": [
        "es2015-webpack"
    ],
    "plugins": [
        "transform-runtime",
        ["transform-es2015-modules-commonjs-simple", {
            "noMangle": true
        }]
    ]
}

transform-runtime is usually a good idea to include in any substantive project to avoid extra repetition of generated code. Typical module config in webpack.config.js:

module: {
    loaders: [
        {
            loader: "babel-loader",
            include: [path.resolve(__dirname, "src")]                
        }
    ]
},
devtool: '#inline-source-map'

The resulting code won't change the names of imports, so debugging with source maps will provide you with access to symbols.

like image 164
Jamie Treworgy Avatar answered Oct 17 '22 03:10

Jamie Treworgy


I had some good success by adding the statement

debugger;

in your javascript/typescript files even in framework files of angular or vue2 like *.vue

So even if the file gets converted or changed or renamed or your path mappings to URL don't work, the debugger will step anyway.

like image 1
1P0 Avatar answered Oct 17 '22 03:10

1P0