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

What is adding this wrapper around my code?

总结

我正在 TypeScript 中编写一个 Angular 2 应用程序,并使用 SystemJSGulp 来部署它。我在尝试使用 sourcemaps 时遇到了一个奇怪的问题。如果我内联包含源地图,一切正常。如果我使用外部地图文件,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) on disk除第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 参数在链接到地图时使用完整的 URL。因此,我将 gulpfile.js typescript 构建任务从我上面发布的内容(在 External maps are broken 下)更改为:

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));
});

这与以前一样将 sourcemaps 放在单独的文件中,但是它将第 167 行(从上面的文件摘录)转换为:

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

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

PS:这是交叉发布的 on Github

这应该是 Firefox 的问题:In-browser transpilation sourcemaps do not work outside of Chrome. See also Bug 1224078。 Sourcemap inline 仍然有效,因为它在同一个 js 文件中。

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

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

这是一个相对路径,Chrome可以识别,Firefox不能。事实上,如果您用绝对路径手动更正路径,您会看到 Firefox 找到了它们。转换不是从 TypeScript 到 Javascript,而是相反:sourcemaps 文件用于浏览器以 TypeScript 重建源文件,以便您可以调试它们(如果您打开 Chrome 控制台,您即使您没有发布它们,也会看到 TypeScript 文件。