javascript - 在我的代码中添加这个包装器是什么?

标签 javascript typescript angular gulp source-maps

摘要

我正在使用 TypeScript 编写一个 Angular 2 应用程序,并使用 SystemJSGulp 来部署它。在尝试使用源映射时,我遇到了一个奇怪的问题。如果我内联包含源映射,一切正常。如果我使用外部映射文件,SystemJS 似乎会在我的代码周围添加一个我不理解的包装器,从而破坏浏览器查找源映射的能力。我想弄清楚到底发生了什么以及如何解决它。

内嵌 map 工作

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 文件。没问题。

外部 map 已损坏

gulpfile.js 生成外部 map

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

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

更新

下面的@robisim74帮助我缩小了问题范围:似乎包装与Firefox无法加载外部 map 的原因无关。相反,Firefox 无法解析 sourceMappingURL 中的相对路径。在上面的最后摘录中,如果我将第 167 行更改为:

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

至:

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

然后 Firefox 将加载 map !所以我使用了 gulp-sourcemaps write()SourceMappingURL 参数链接到 map 时使用完整 URL 的功能。因此,我将我的 gulpfile.js typescript 构建任务从上面发布的内容(在外部映射已损坏下)更改为:

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 可以使用 map 向我显示 Typescript 源代码。

PS:这是交叉发布的on Github

最佳答案

应该是 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,反之亦然:sourcemaps 文件服务于浏览器以 TypeScript 重建源文件,以便您可以调试它们(如果您打开 Chrome 控制台,您将看到 TypeScript 文件,即使您还没有发布它们)。

关于javascript - 在我的代码中添加这个包装器是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38495497/

相关文章:

typescript - 如何使用 JSDoc 传递泛型类型参数?

javascript - 为什么我的函数会导致 TypeError <function> is not a function?

javascript - 有 Elixir 的 typescript 吗?

javascript - angular2 组件内的 iframe,属性 'contentWindow' 在类型 'HTMLElement' 上不存在

angular - 如何在 Angular 2 中使用 RxJS "throttle"运算符

javascript - 在 div 上使用 z-index 时遇到问题。是jsfiddle吗?

javascript - 如何在 app.js 的 html 页面中隐藏 div

javascript - Material Angular 表不包含对象的排序列

javascript - 仅用JS将文件上传到服务器

javascript - Jquery 手机屏幕方向 - Cordova 项目