Grunt babel如何对多个文件进行转换并保留源映射信息

12
我正在尝试使用grunt和babel来转译一个文件夹中的所有js6文件,并最终得到一个合并的单个文件(js5),同时生成一个可以与原始es6文件对应的可用源代码映射。然而,源代码映射无法正常工作。我的babel和concat设置如下:
 "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"

我最终得到了一个包含许多JS文件和源映射(tmp目录)的文件夹。但是将它们合并成一个文件会完全搞乱源映射。

有什么好的建议吗?另外,我能否跳过制作临时文件,并将结果直接传输到concat中?


你可以先运行concat任务,然后在单个文件上运行babel任务,并将源映射选项设置为true。 - Prayag Verma
@PrayagVerma,这使得我能够调试ES6代码。虽然不是从原始文件中,但比之前好了一些。 - Todilo
似乎babel有一个inputSourceMap选项,但让它工作起来对我来说并不容易。 - Todilo
@PrayagVerma 这很好,但当Babel遇到错误时,它不会显示原始源位置,而是在连接的文件中。有人知道如何解决这个问题吗? - phobos2077
1个回答

16

将任务顺序反转将使这更容易。首先在JS文件上运行concat任务。之后,使用以下选项在由concat任务之前创建的单个文件上运行babel任务。

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

这里的script.js.map文件是由concat任务生成的源映射文件的名称。由于inputSourceMap选项需要一个源映射对象,我们使用grunt.file API的readJSON方法将其传递进去。

完整的Grunt文件配置如下:

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'
        }
    }

示例项目:https://github.com/pra85/Grunt-Concat-Babel-Example


2
这个可行,谢谢。为了让它在Visual Studio任务运行器中工作,我所做的是更改:inputSourceMap: function () { if (grunt.file.exists('../concatinated-es6.js.map')) { return grunt.file.readJSON('concatinated-es6.js.map') } return ''; }()否则任务列表会崩溃。 - Todilo
11
这基本上起作用了,但是Grunt文件在生成源地图之前��直尝试读取它。为了解决这个问题,我注册了一个自定义任务,在concat和babel之间运行,将“inputSourceMap”选项添加到babel配置中。我的Gruntfile.js看起来像这样:http://jsbin.com/rijazetaxe/3/edit?js - BenJamin
根据babel源代码 ,解析源映射json是不必要的。只要inputSourceMap为真,Babel将始终从连接输出中解析源映射注释。更糟糕的是,如果它发现源映射注释,它将忽略任何值,这在这里总是发生的。因此,这可能不会做你期望的事情。 - user8808265
最终问题的真正解决方案。许多其他grunt插件都有一个选项sourceMapIn,您可以将路径传递给它,但是这个插件需要一个没有更好指定的“源映射对象”。在这里它就是。 - Francesco Pasa
对我来说,这会导致内存溢出错误,因为我的源映射非常大。不过,Node选项--max-old-space-size=10000可以帮助解决问题。https://dev59.com/a6_la4cB1Zd3GeqPys4Q - Waltari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接