Use sorcery to merge sourcemaps between browserify and gulp-typescript#9439
Conversation
| } | ||
|
|
||
| declare module "sorcery" { | ||
| export = any; |
There was a problem hiding this comment.
is there a value any defined any where?
There was a problem hiding this comment.
Might have intended declare module "sorcery";
| browserify(intoStream(file.contents)) | ||
| const originalMap = file.sourceMap; | ||
| const prebundledContent = file.contents.toString(); | ||
| originalMap.sources = originalMap.sources.map(s => path.resolve(s)); // Make paths absolute to help sorcery deal with all the terrible paths being thrown around |
There was a problem hiding this comment.
nit: ...map(path.resolve) should work fine.
There was a problem hiding this comment.
Scratch that, map(path.resolve) throws with perhaps the oddest assertion I've ever seen. Comments still moved.
| file.contents = res; | ||
| const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/true).toJSON()); | ||
| delete maps.sourceRoot; | ||
| for (let i = 0; i < maps.sources.length; i++) { |
There was a problem hiding this comment.
Need the indexes to do the assignments. I could rewrite it as a map, however, and will do so.
| file.contents = res; | ||
| let maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/true).toJSON()); | ||
| delete maps.sourceRoot; | ||
| maps = maps.map(s => (s === "_stream_0.js") ? path.resolve("built/local/_stream_0.js") : path.resolve(s)); |
There was a problem hiding this comment.
push the conditional down into the path.resolve argument
|
👍 -- works for me. 1 minor nit about the conditional left. |
|
Well, actually it needs a |
|
I sent an email to @jrieken about the feasibility of using gulp-tsb (which is used by VS Code) instead of gulp-typescript, though it needs some updates to work well for us. One of the changes I made in the referenced PR should make sourcemaps much cleaner. |
|
Would the incrementality of gulp-tsb fix the fact that this task doesn't update source maps when source code changes? |
|
I'm not certain. I'm testing my fork of gulp-tsb right now. Do you have simplified repro steps I could use to check this scenario? |
|
Edit: here is a reusable repro. I don't have any idea how to automate this, but maybe it will still be useful:
|
|
So it seems there are various issues with source maps across gulp-typescript, gulp-sourcemaps, and browserify. I've done some investigation and it boils down into a few main themes:
I've experimented with using my fork of import rename = require("gulp-rename");
import source = require("vinyl-source-stream");
import buffer = require("vinyl-buffer");
import applySourceMaps = require("vinyl-sourcemaps-apply");
...
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [run], () => {
const b = browserify("./run.js", { debug: true, basedir: path.resolve(builtLocalDirectory) });
return b.bundle()
.pipe(source("run.js", path.resolve(harnessDirectory))) // emulate a file in src/harness
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true })) // pull in the inline sourcemap from browserify
.pipe(through2.obj((bundle, enc, cb) => {
gulp.src(run)
.pipe(sourcemaps.init({ loadMaps: true }))
.on("data", file => {
// truncate source root and repoint source maps
delete file.sourceMap.sourceRoot;
delete bundle.sourceMap.sourceRoot;
const sourceMap = bundle.sourceMap;
bundle.sourceMap = file.sourceMap;
applySourceMaps(bundle, sourceMap);
cb(null, bundle);
});
}))
.pipe(rename("bundle.js"))
.pipe(sourcemaps.write(".", { includeContent: false, destPath: builtLocalDirectory })) // sets the correct sourceRoot
.pipe(gulp.dest(builtLocalDirectory));
});I still have some testing to do to make sure it is working as expected, however. |
|
@rbuckton, are you OK with @weswigham merging this now and implementing the right fix later? I have continued to use this branch and have not had any problems, but it would be way more convenient to have it in master. |
|
After addressing the merge conflicts, 👍 |
Yesterday @sandersn and @Andy-MS both mentioned that their sourcemaps for in-browser debugging seemed off. I checked, and despite loading in the correct files, the maps were indeed off by around 1 line in most places! After looking into it, I determined it was because we were never integrating any sourcemaps from the browserify transform step of the browser tests build. Now, browserify doesn't ingest sourcemaps from the incoming stream particularly well (or at all), so I extracted the single-stage sourcemaps it makes and merged two two layers of sourcemaps using a library called
sorcery. I've tried combining them usingvinyl-sourcemaps-applyandcombine-source-maps(more popular libraries), but it seems like those libraries are focused more for concatenation, not redirection/layering - for some reason neither of them actually merge both the actual sourcemaps and source files list correctly (whereassorcerydoes, with a little coercion).@rbuckton You typically have opinions on all things gulp - do you have any suggestions/feedback here?