12

I am trying, using grunt and babel, to transpile all js6 files in a folder and end up with a concatenated single file (js5) with a working sourcemap to the original es6 files. However the sourcemapping does not work. My babel, concat settings below:

 "babel": {
        options: {
            sourceMap : true
        },
        dist: {
            files:[
                {
                    expand: true,
                    cwd: 'wwwroot/js/src',
                    src: ['*.js'],
                    dest: 'tmp/js'
                }]
        }
    },

    concat: {
        options: {
            sourceMap: true
        },
        js: {
            src: [
              'tmp/js/*.js',
            ],
            dest: 'wwwroot/js/app.js'
        }
    }

Versions:
"grunt": "0.4.5",
"grunt-bower-task": "0.4.0",
"grunt-babel": "5.0.1",
"grunt-contrib-concat" : "0.5.1"

I am ending up with firstly a folder with a lot of js files and src maps(tmp directory). But concatinating them into one file messes up with source mapping completely.

Ideas? Also, can I somehow skip the making of temporary files and sort of just pipe the result into concat?

Todilo
  • 1,256
  • 3
  • 19
  • 38
  • You could run concat task first and then on the single file run the babel task with source map option true – Prayag Verma Sep 17 '15 at 08:57
  • @PrayagVerma that does make it a bit better since I can debug es6 code. Not from the original file but well, better. – Todilo Sep 17 '15 at 09:04
  • There seems to be an inputSourceMap option for babel but getting it to work does not seem trivial to me. – Todilo Sep 17 '15 at 09:23
  • @PrayagVerma that is good but when Babel encounters error, it will not show original source location for it, but in concatenated file. Does anyone knows how to solve this? – phobos2077 Dec 16 '16 at 18:38

1 Answers1

16

Reversing the order of task will make this much easier.First run the concat task on the JS files. After that run babel task on the single file created by concat task previously with the following options

options: {
                sourceMap: true,
                inputSourceMap: grunt.file.readJSON('script.js.map')
            },

Here the script.js.map file is the name of the source map file generated by concat task. As inputSourceMap option excepts a source map object , we pass it in using the grunt.file API's readJSON method

The full Grunt file configuration would be:

concat: {
        options: {
            sourceMap: true
        },
        js: {
            src: ['Modules/**/js/*.js'],
            dest: 'script.js'
        }
    },
    babel: {
        dist: {
            options: {
                sourceMap: true,
                inputSourceMap: grunt.file.readJSON('script.js.map')
            },
            src: [
                'script.js',
            ],
            dest: 'app.js'
        }
    }

Example project: https://github.com/pra85/Grunt-Concat-Babel-Example

Prayag Verma
  • 5,581
  • 3
  • 30
  • 56
  • 2
    This works, thank you. What I had to do to make it work in visual studio task runner was to change: inputSourceMap: function () { if (grunt.file.exists('../concatinated-es6.js.map')) { return grunt.file.readJSON('concatinated-es6.js.map') } return ''; }() Otherwise the task list would crash. – Todilo Sep 17 '15 at 14:55
  • 11
    This Mostly worked, the Grunt file kept trying to read the source map before it was generated though. To fix this, I registered a custom task that gets run between concat and babel that addes the `inputSourceMap` option to the babel config. Making my Gruntfile.js look something like this: http://jsbin.com/rijazetaxe/3/edit?js – BenJamin Oct 01 '15 at 15:36
  • According to [babel source code](https://github.com/babel/babel/blob/e44cef34734b59d26b2f090acd7ab16d5570b05c/packages/babel-core/src/transformation/normalize-file.js#L29), parsing the source map json is uneeded. Babel will always parse the source map comment from concat output, as long as `inputSourceMap` is truthy. Even worse, it will ignore any value if it finds a source map comment, which is always the case here. Consequently, this probably won't do what you expect. – user8808265 Nov 14 '17 at 21:24
  • Finally the real solution to the problem. Many other grunt plug-ins have an option `sourceMapIn` to which you can pass the path, but this plugin need a not better specified "source map object". Here it is. – Francesco Pasa Dec 09 '17 at 22:29
  • For me this is causing an out of memory error as my sourcemap is huge. Node option --max-old-space-size=10000 helps though. https://stackoverflow.com/questions/53299430/run-grunt-task-with-node-js-arguments-on-windows – Waltari Nov 14 '18 at 11:50