什么在我的代码周围添加这个包装器?
What is adding this wrapper around my code?
总结
我正在 TypeScript
中编写一个 Angular 2 应用程序,并使用 SystemJS
和 Gulp
来部署它。我在尝试使用 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 文件中。
编辑。
当您发布 js
和 js.map
文件时,js 文件包含:
// # sourceMappingURL = [file name].js.map.
这是一个相对路径,Chrome可以识别,Firefox不能。事实上,如果您用绝对路径手动更正路径,您会看到 Firefox 找到了它们。转换不是从 TypeScript 到 Javascript,而是相反:sourcemaps 文件用于浏览器以 TypeScript 重建源文件,以便您可以调试它们(如果您打开 Chrome 控制台,您即使您没有发布它们,也会看到 TypeScript 文件。
总结
我正在 TypeScript
中编写一个 Angular 2 应用程序,并使用 SystemJS
和 Gulp
来部署它。我在尝试使用 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 文件中。
编辑。
当您发布 js
和 js.map
文件时,js 文件包含:
// # sourceMappingURL = [file name].js.map.
这是一个相对路径,Chrome可以识别,Firefox不能。事实上,如果您用绝对路径手动更正路径,您会看到 Firefox 找到了它们。转换不是从 TypeScript 到 Javascript,而是相反:sourcemaps 文件用于浏览器以 TypeScript 重建源文件,以便您可以调试它们(如果您打开 Chrome 控制台,您即使您没有发布它们,也会看到 TypeScript 文件。