什么在我的代码周围添加这个包装器?

时间:2016-07-21 05:25:25

标签: javascript typescript angular gulp source-maps

摘要

我正在TypeScript内编写Angular 2应用,并使用SystemJSGulp进行部署。我在尝试使用源图时遇到了一个奇怪的问题。如果我将sourcemap包含在内,那么一切正常。如果我使用外部地图文件,SystemJS似乎在我的代码中添加了一个我不理解的包装器,打破了浏览器查找源地图的能力。我想弄清楚实际发生了什么以及如何解决它。

内嵌地图工作

gulpfile.js 以下是将TypeScript编译为JavaScript的任务

gulp.task('build-ts', function () {
    return gulp.src(appDev + '**/*.ts')
        .pipe(sourcemaps.init()) //gulp-sourcemaps
        .pipe(typescript(tsProject)) //gulp-typescript
        .pipe(sourcemaps.write()) //map will be inline
        .pipe(gulp.dest(appProd));
});

磁盘和浏览器中生成的JS文件( login.component.js )如下所示:

165| exports.LoginComponent = LoginComponent;
166| 
167| //# sourceMappingURL=data:application/json;base64,eyJ2Z...

浏览器可以使用内联映射让我看到源TypeScript文件。没问题。

外部地图已损坏

gulpfile.js 生成外部地图

gulp.task('build-ts', function () {
    return gulp.src(appDev + '**/*.ts')
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject))
        .pipe(sourcemaps.write('.')) //map will be external
        .pipe(gulp.dest(appProd));
});

磁盘上生成的JS文件( login.component.js 与上面相同,但第167行除外:

165| exports.LoginComponent = LoginComponent;
166| 
167| //# sourceMappingURL=login.component.js.map

当我在浏览器中查看源代码时,同样的文件结束如下:

165| exports.LoginComponent = LoginComponent;
166| 
167| //# sourceMappingURL=login.component.js.map
168| 
169| }).apply(__cjsWrapper.exports, __cjsWrapper.args);
170| })(System, System);
171| //# sourceURL=http://example.com/path/to/login.component.js

映射文件 login.component.js.map 在同一目录中正确生成,但Firefox从不提取它。这种包装破坏了Firefox加载源图的能力。为什么gulp任务生成的文件在浏览器加载后会与同一文件不同?

更新

下面的@ robisim74帮助我缩小了问题:似乎包装与Firefox无法加载外部地图的原因无关。相反,Firefox无法解析sourceMappingURL中的相对路径。在我上面的上一段摘录中,如果我改变第167行:

//# sourceMappingURL=login.component.js.map

为:

//# sourceMappingURL=http://example.com/path/to/login.component.js.map

然后Firefox会加载地图!因此,我使用gulp-sourcemaps write()函数的SourceMappingURL参数在链接到地图时使用完整的网址。因此,我将gulpfile.js打字稿构建任务从上面发布的内容(在外部地图已损坏下)更改为:

gulp.task('build-ts', function () {
    return gulp.src(appDev + '**/*.ts')
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject))
        .pipe(sourcemaps.write('.',{
            sourceMappingURL: function(file) {
                return '//example.com/app/' + file.relative + '.map'; //full URL
            }
        }))
        .pipe(gulp.dest(appProd));
});

这将源映射放在与以前相同的单独文件中,但它将第167行(从上面的文件摘录)转换为:

167| //# sourceMappingURL=//example.com/path\to\login.component.js.map

现在Firefox可以使用地图向我展示Typescript源。

PS:这是交叉发布on Github

1 个答案:

答案 0 :(得分:1)

应该是Firefox问题:In-browser transpilation sourcemaps do not work outside of Chrome。另见Bug 1224078。 无论如何,Sourcemap内联工作都是因为它在同一个js文件中。

编辑。 发布jsjs.map文件时,js文件包含:

// # sourceMappingURL = [file name].js.map.

这是Chrome能够识别的相对路径,而不是Firefox。实际上,如果您使用绝对路径手动更正路径,您将看到Firefox找到它们。转换不是从TypeScript到Javascript,反之亦然:源映射文件用于浏览器重建TypeScript中的源文件,以便您可以调试它们(如果您打开Chrome控制台,您将看到TypeScript文件即使你没有发表它们。)