【问题标题】:How do I generate sourcemaps for Uglified files using Grunt?如何使用 Grunt 为 Uglified 文件生成源映射?
【发布时间】:2019-06-24 21:23:38
【问题描述】:

我有一个同时使用 Browserify 和 Uglify 的 Grunt 项目。以下是它的核心部分:

browserify: {
  myapp: {
    options: {
      transform: ['babelify'],
      browserifyOptions: {
        debug: true
      },
    },
    src: 'src/index.js',
    dest: 'build/myapp.js'
  }
},

uglify: {
  options: {
    sourceMap: true,
    banner: bannerContent
  },
  target: {
    src: 'build/myapp.js',
    dest: 'build/myapp.min.js'
  }
},

它似乎生成了一个myapp.min.js.map 文件,但它不再具有在浏览器化之前存在的源映射中的原始源。

以下是生成的源映射文件包含的内容:

{
  "version":3,
  "sources":[
    "myapp.js"
  ],
  "names":[
    ...
    ...
    ...
  ],
  "mappings":".........",
  "file":"myapp.min.js"
}

我已尝试对 Browserify 使用 uglifyify 转换,但生成的文件似乎不像 Uglify 任务那么小。

我也将所有依赖项都升级到了最新版本,但我无法解决这个问题。

【问题讨论】:

  • grunt-browserify 不会创建外部 src 映射文件 - 请参阅 here。尝试:1)使用grunt-extract-sourcemapmyapp.js读取内联src映射并创建外部src映射文件(注意:在你当前的browserify任务之后和uglify任务之前运行这个任务)。 2)uglify 任务中设置sourceMapIn 选项以使用在步骤1 中创建的src 映射。
  • @RobC 当脚本通过 uglify 步骤被缩小时,生成的脚本文件是否仍然具有到源映射文件的正确映射?如果我理解正确的话,Unglify 步骤只会缩小 JS 文件,但不会更改源映射。

标签: gruntjs source-maps grunt-contrib-uglify grunt-browserify


【解决方案1】:

grunt-contrib-uglify 有一个 sourceMapIn 选项,可让您从早期编译中指定输入源映射文件的位置 - 在您的场景中是 browserify 任务。

然而,虽然在 browserify 任务中设置 browserifyOptions: { debug: true } 确实会在生成的 .js 文件中(即在 build/myapp.js 中)生成内联源映射,但问题的症结在于双重:

  1. 我们没有可以配置后续grunt-contrib-uglify 任务的sourceMapIn 选项以使用的外部源映射文件。

  2. grunt-browserify 不提供创建外部.map 文件的功能,它只内联创建它们(参见here

要解决上述问题,请考虑在生成后使用grunt-extract-sourcemapbuild/myapp.js(即从您的browserify 任务生成的输出文件)中提取内联源映射。

Gruntfile.js

以下要点显示了应该如何配置您的 Gruntfile.js

module.exports = function (grunt) {

  grunt.initConfig({

      browserify: {
        myapp: {
          options: {
            transform: ['babelify'],
            browserifyOptions: {
              debug: true
            },
          },
          src: 'src/index.js',
          dest: 'build/myapp.js'
        }
      },

      extract_sourcemap: {
        myapp: {
          files: {
            'build': ['build/myapp.js']
          }
        }
      },

      uglify: {
        options: {
          sourceMap: true,
          sourceMapIn: 'build/myapp.js.map'
        },
        target: {
          src: 'build/myapp.js',
          dest: 'build/myapp.min.js'
        }
      }

  });

  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-extract-sourcemap');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Note the order of the tasks in your task list is important.
  grunt.registerTask('default', ['browserify', 'extract_sourcemap', 'uglify']);
};

说明

  1. 首先调用browserify 任务,该任务输出一个新文件(即build/myapp.js),其中包含您捆绑的JavaScript 和“内联” 源映射信息。如果您要在此阶段检查 build/myapp.js 的内容,它的末尾会包含以下内容:

    //# sourceMappingURL=data:application/json;charset=utf-8;base64, ...
    
  2. 接下来调用extract_sourcemap 任务。这实质上是从build/myapp.js 中提取"inlined" 源映射信息并将其写入一个名为myapp.js.map 的新文件,该文件保存在您的build 目录中。

    build/myapp.js 中的原始 "inlined" 源映射信息被替换为新生成的源映射文件的链接,即myapp.js.map。如果您检查 build/myapp.js 的内容,您现在会在文件末尾注意到以下内容:

    //# sourceMappingURL=myapp.js.map
    
  3. 最后调用uglify 任务。请注意它的sourceMapIn 选项是如何配置为读取build/myapp.js.map 的,即我们在步骤 2 中生成的源映射文件。

    此任务创建您想要的 build/myapp.min.js 文件,其中包含:您缩小的 JS,以及指向新生成的源映射文件 build/myapp.min.js.map 的链接。

注意最终生成的文件(即build/myapp.min.js)现在可以正确映射回原始src/index.js 文件以及index.js 本身可能具有import 的任何文件或require()'d

【讨论】:

  • 这似乎是从地图文件中删除源。中间文件有它,但结果没有。我添加了sourceMapIncludeSources: true,但它不起作用。罗有什么建议吗?
  • 有趣的是,我使用答案中显示的配置在生成的build/myapp.min.js.map 文件中列出了"sources": [ .... ]。如果将sourceMap: { includeSources: true } 添加到uglify 任务options 对象会发生什么?失败的可能尝试使用早期版本的 grunt-contrib-uglify
  • sourceMap 不走运:{ includeSources: true }。 @RobC - 你知道你使用了哪个版本的 grunt-contrib-uglify 吗?
  • 回滚到 grunt-contrib-uglify 的 ^2.0.0 也不起作用。我收到警告错误:丑化失败。无法读取“dist/index.js.map”文件(错误代码:ENOENT)..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
  • 2014-12-17
  • 2019-10-02
  • 1970-01-01
  • 2018-08-11
相关资源
最近更新 更多