Preserve original sourcemap with Browserify
Asked Answered
U

5

13

Suppose I have a module whose source code is not ECMA 5 (e.g. it's Coffescript or Typescript or whatever) and is distributed in compiled form with a source map. How can I include this source map in a Browserify bundle?

For example imagine a project with a single dependency:

index.js
    node_modules
         typescript_module
              (main.ts)
              dist
                  main.js
                  main.js.map

The "main.js.map" is not consumed by browserify. That is, the browserify bundle source map maps to "main.js" instead of deferring to the original map which describes "main.ts"

For most transforms, there is a way to input source maps generated by the prior step, but is there a way to just preserve them on the original input files, when source maps already exist?

Urias answered 9/9, 2015 at 17:50 Comment(2)
possible duplicate of Keep original typescript source maps after using browserifyGowen
Saw that question - the answer is out of date at best, as the syntax is no longer supported by Browserify, but I'm not even trying to pass this through uglify/minify. Just plain old browserify with {debug: true} produces source maps with no reference to the original.Urias
U
7

This appears to be a bug/non-feauture of Browserify:

https://github.com/substack/node-browserify/issues/772

Answering my own question because it's very hard to track down any discussion of this issue with google and no mention of it in the Browserify docs.

Urias answered 9/9, 2015 at 18:25 Comment(0)
I
3

My setup is the following:

tsc --project tsconfig.script.json --outDir ~temp/ts

Compiles src/script.ts to ~temp/ts/script.js and ~temp/ts/script.js.map.

browserify ~temp/ts/script.js --debug | exorcist --root ../../ ~temp/bfy/script.js.map > ~temp/bfy/script.js

Compiles ~temp/ts/script.js to ~temp/bfy/script.js and ~temp/bfy/script.js.map.

sorcery --input ~temp/bfy/script.js --output dist/script.js

Reads ~temp/bfy/script.js; finds ~temp/bfy/script.js.map + ~temp/ts/script.js.map, and finally outputs dist/script.js and dist/script.js.map.

The dist/script.js.map file does reference the original src/script.ts file.

Requires Browserify, Exorcist and Sorcery (and of course CoffeeScript or TypeScript or whatever).

Inedible answered 17/3, 2017 at 8:17 Comment(2)
Wow, thanks. I spent the whole day to make this work and you have provided the final piece. A twist to my solution is that (1) in front of that pipeline I have Webpack and (2) at the end of the pipeline I'm building a Chrome Plugin. Chrome plugins don't support external source map files (bug), so I had to adjust sorcery to generate an inline sourcemap.Salicin
But won't ~temp/bfy/script.js.map be the JS map, not the original TS map?Rivarivage
B
3

If you are using a TypeScript library that you have control over (for example in a lerna monorepo), you can enable the following compilerOptions in tsconfig.json:

{
  "compilerOptions": {
    "sourceMap": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    // ...
  }
}

browserify should now use and transform the inlined source maps.

browserify will not read source maps that reference another file, it will only use inlined source maps with inlined sources. I have written about this in the referenced issue on GitHub browserify/browserify#772.

Alternatively, if you do not have control over the source of the TypeScript library, but you would still like to see the original source in DevTools, you can use the sourceify library someone mentioned in another answer. However, I had to patch it to work and I submitted a pull request. It hasn't been merged yet (at the time of writing this). If you wish to test it yourself, you can install it directly from my branch:

npm install https://github.com/jeremija/sourceify#sources-content

Make sure to use the global transform -g [ sourceify ], because the default transform (-t) in Browserify does not modify files in node_modules.

Budde answered 26/3, 2019 at 11:30 Comment(0)
M
2

Have a look at sourceify.

Just install it:

npm i --save-dev sourceify

... and add it as a transform to package.json:

"browserify": {
  "transform": [
    "sourceify"
  ]
}

... and it Just Works.

Marrs answered 1/2, 2017 at 0:59 Comment(1)
I have the same issue as the OP, but unfortunately sourceify does not solve it. Note that I used browserify temp/script.js -t [ sourceify ] --debug | exorcist --root ../ dist/script.js.map > dist/script.js from the command line, to compile temp/script.js that came from tsc --outDir temp. That's unfortunate.Inedible
B
1

Try the following:

var gulp        = require("gulp"),
    browserify  = require("browserify"),
    tsify       = require('tsify'),
    source      = require("vinyl-source-stream"),
    sourcemaps  = require("gulp-sourcemaps"),
    buffer      = require("vinyl-buffer"),
    uglify      = require("gulp-uglify"),
    header      = require("gulp-header");

var settings = {
  projectName : "test"
};    

gulp.task("bundle", function() {

  var mainTsFilePath = "src/main.ts";
  var outputFolder   = "bundle/src/";
  var outputFileName = settings.projectName + ".min.js";
  var pkg            = require("./package.json");

  var banner = [
    "/**",
    " * <%= pkg.name %> v.<%= pkg.version %> - <%= pkg.description %>",
    " * Copyright (c) 2015 <%= pkg.author %>",
    " * <%= pkg.license %>",
    " */", ""
  ].join("\n");

  var bundler = browserify({
    debug: true,
    standalone : settings.projectName
  });

  // TS compiler options are in tsconfig.json file
  return bundler.add(mainTsFilePath)
                .plugin(tsify)
                .bundle()
                .pipe(source(outputFileName))
                .pipe(buffer())
                .pipe(sourcemaps.init({ loadMaps: true }))
                .pipe(uglify())
                .pipe(header(banner, { pkg : pkg } ))
                .pipe(sourcemaps.write('./'))
                .pipe(gulp.dest(outputFolder));
});

Note: change the paths to match your project!

Brooks answered 14/11, 2015 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.