Gulp:为缩小和非缩小脚本生成源图

Posted

技术标签:

【中文标题】Gulp:为缩小和非缩小脚本生成源图【英文标题】:Gulp: Generate sourcemaps for both minified and non-minified scripts 【发布时间】:2017-02-02 03:36:11 【问题描述】:

我是 gulp 的新手,遇到了一个很常见的问题。我正在尝试将 typescript 编译成 javascript,为它创建一个源映射,然后运行 ​​uglify。我想要一个 ugliyfied 和非 uglified js 的源图。

我想要实现的是以下文件结构:

framework.js
framework.js.map < this won't work
framework.min.js
framework.min.js.map

这是我的 gulp 任务:

var gulp = require('gulp'),
uglify = require('gulp-uglify')
ts = require("gulp-typescript")
sourcemaps = require('gulp-sourcemaps')
rename = require('gulp-rename');

var tsProject = ts.createProject("tsconfig.json");


gulp.task('typescript', function()
    tsProject.src()
    .pipe(sourcemaps.init())
    .pipe(tsProject()).js
    .pipe(sourcemaps.write('.')) // Write sourcemap for non-minified version
    .pipe(gulp.dest("dist"))
    .pipe(uglify()) // Code will fail here 
    .pipe(rename(suffix:'.min'))
    .pipe(sourcemaps.write('.')) // Write sourcemap for minified version.
    .pipe(gulp.dest("dist"));
);

gulp.task('default', ['typescript']);

如您所见,我运行 sourcemaps.write() 两次以获取两个不同的文件。这给了我一个错误

tream.js:74                                                                        
  throw er; // Unhandled stream error in pipe.                                  
  ^ GulpUglifyError: unable to minify JavaScript                                       
at createError     (C:\Users\alexa\Dropbox\code\Web\mhadmin\framework\node_modules\gulp-uglify\lib\create-error.js:6:14)

省略第一个 sourcemap.write() 调用将为文件的缩小版本生成正确的源映射。

任何想法如何解决这个问题?

编辑:这不完全是 gulp: uglify and sourcemaps 的副本,因为我需要编写多个源映射并多次调用 gulp.dest()

【问题讨论】:

gulp: uglify and sourcemaps的可能重复 【参考方案1】:

问题是在第一个 .pipe(sourcemaps.write('.')) 之后,您的流中有两个文件:

framework.js
framework.js.map 

您将这两个文件写入文件系统(这很好),但随后您尝试在这两个文件上运行uglify()。由于您的 framework.js.map 文件不是 JavaScript 文件并且不包含有效的 JavaScript 代码,因此 uglify() 插件会抛出。

在您将framework.js.map 写入文件系统之后,真的没有理由再将该文件保留在流中了。 framework.js 的乙烯基文件对象仍然有一个 .sourceMap 属性,它承载了目前为止的所有转换,这意味着您可以从流中删除 framework.js.map 文件。

gulp-filter 插件让您可以做到这一点:

var filter = require('gulp-filter');

gulp.task('typescript', function()
  return tsProject.src()
   .pipe(sourcemaps.init())
   .pipe(tsProject()).js
   .pipe(sourcemaps.write('.'))
   .pipe(gulp.dest("dist"))
   .pipe(filter('**/*.js')) // only let JavaScript files through here
   .pipe(uglify())
   .pipe(rename(suffix:'.min'))
   .pipe(sourcemaps.write('.'))
   .pipe(gulp.dest("dist"));
);

.pipe(filter('**/*.js')) 之后,只有framework.js 文件将在流中,uglify() 不会再抛出。

【讨论】:

非常感谢斯文!我只是想出了完全相同(我的代码甚至与您的代码相同)的解决方案并且它有效! @Sven:uglifyJS 不应该有一个 outSourceMap 选项吗? ***.com/questions/41722432/…【参考方案2】:

看起来有点像黑客,但它确实有效

gulp.src('TypeScript/Test.ts')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(ts(tsOptions)).js
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./wwwroot/test'))
    .pipe(uglify())
    .pipe(rename( extname: '.min.js' ))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./wwwroot/test'));

魔法就在plumber。管道工防止在异常时停止进程。但主要的兴趣是为什么会发生异常。所以,很清楚。在您的代码中,您通过.pipe(sourcemaps.write('.')) // Write sourcemap for non-minified version 创建源映射,然后尝试对其进行丑化。是的,sourcemap 不是 js,并且会发生异常。使用plumber 忽略此异常,您就可以实现目标。

但我可能想出了一些错误,我建议你找到更真实的解决方案。

【讨论】:

这会起作用,但是,就像你说的:这有点像黑客。但是你让我进入了写作轨道。关键是在继续之前摆脱管道中的 *.map 文件。请参阅 SvenSchoenung 的回答。

以上是关于Gulp:为缩小和非缩小脚本生成源图的主要内容,如果未能解决你的问题,请参考以下文章

Gulp将多个js文件缩小为一个

Gulp用手表任务结束并缩小

Photoshop - 使用动作/脚本缩小图像并将图像转储到单独的文件夹中

使用 gulp 生成源映射

Gulp循环监视任务

用于缩小 CSS 的 Python 脚本? [关闭]