Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

sorcery

Rich-Harris1.6mMIT1.0.0

Resolve a chain of sourcemaps back to the original source

readme

sorcery.js

Sourcemaps are great - if you have a JavaScript file, and you minify it, your minifier can generate a map that lets you debug as though you were looking at the original uncompressed code.

But if you have more than one transformation - say you want to transpile your JavaScript, concatenate several files into one, and minify the result - it gets a little trickier. Each intermediate step needs to be able to both ingest a sourcemap and generate one, all the time pointing back to the original source.

Most compilers don't do that. (UglifyJS is an honourable exception.) So when you fire up devtools, instead of looking at the original source you find yourself looking at the final intermediate step in the chain of transformations.

Sorcery aims to fix that. Given a file at the end of a transformation chain (e.g., your minified JavaScript), it will follow the entire chain back to the original source, and generate a new sourcemap that describes the whole process. How? Magic.

This is a work-in-progress - suitable for playing around with, but don't rely on it to debug air traffic control software or medical equipment. Other than that, it can't do much harm.

Usage

As a node module

Install sorcery locally:

npm install sorcery
import * as sorcery from 'sorcery';

sorcery.load('some/generated/code.min.js').then(function (chain) {
  // generate a flattened sourcemap
  var map = chain.apply(); // { version: 3, file: 'code.min.js', ... }

  // get a JSON representation of the sourcemap
  map.toString(); // '{"version":3,"file":"code.min.js",...}'

  // get a data URI representation
  map.toUrl(); // 'data:application/json;charset=utf-8;base64,eyJ2ZXJ...'

  // write to a new file - this will create `output.js` and
  // `output.js.map`, and will preserve relative paths. It
  // returns a Promise
  chain.write('output.js');

  // write to a new file but use an absolute path for the
  // sourceMappingURL
  chain.write('output.js', { absolutePath: true });

  // write to a new file, but append the flattened sourcemap as a data URI
  chain.write('output.js', { inline: true });

  // overwrite the existing file
  chain.write();
  chain.write({ inline: true });

  // find the origin of line x, column y. Returns an object with
  // `source`, `line`, `column` and (if applicable) `name` properties.
  // Note - for consistency with other tools, line numbers are always
  // one-based, column numbers are always zero-based. It's daft, I know.
  var loc = chain.trace(x, y);
});

// You can also use sorcery synchronously:
var chain = sorcery.loadSync('some/generated/code.min.js');
var map = chain.apply();
var loc = chain.trace(x, y);
chain.writeSync();

Advanced options

You can pass an optional second argument to sorcery.load() and sorcery.loadSync(), with zero or more of the following properties:

  • content - a map of filename: contents pairs. filename will be resolved against the current working directory if needs be
  • sourcemaps - a map of filename: sourcemap pairs, where filename is the name of the file the sourcemap is related to. This will override any sourceMappingURL comments in the file itself.

For example:

sorcery.load( 'some/generated/code.min.js', {
  content: {
    'some/minified/code.min.js': '...',
    'some/transpiled/code.js': '...',
    'some/original/code.js': '...'
  },
  sourcemaps: {
    'some/minified/code.min.js': {...},
    'some/transpiled/code.js': {...}
  }
}).then( chain => {
  /* ... */
});

Any files not found will be read from the filesystem as normal.

On the command line

First, install sorcery globally:

npm install -g sorcery
Usage:
  sorcery [options]

Options:
  -h, --help               Show help message
  -v, --version            Show version
  -i, --input <file>       Input file
  -o, --output <file>      Output file (if absent, will overwrite input)
  -d, --datauri            Append map as a data URI, rather than separate file
  -x, --excludeContent     Don't populate the sourcesContent array

Examples:

# overwrite sourcemap in place (will write map to
# some/generated/code.min.js.map, and update
# sourceMappingURL comment if necessary
sorcery -i some/generated/code.min.js

# append flattened sourcemap as an inline data URI
# (will delete existing .map file, if applicable)
sorcery -d -i some/generated/code.min.js

# write to a new file (will create newfile.js and
# newfile.js.map)
sorcery -i some/generated/code.min.js -o newfile.js

License

MIT

changelog

changelog

1.0.0

  • Modernise package (#191)

0.11.1

  • Fix sources content when using loadSync (#185)
  • Update deps (#186)

0.11.0

  • Use @jridgewell/sourcemap-codec

0.10.0

  • Allow CLI to recurse over a directory (#13)

0.9.4

  • Remove caching mechanism due to collisions (#74)

0.9.3

  • Update dependencies, use Bublé instead of Babel

0.9.1-2

  • Fix case-sensitive filenames

0.9.0

  • Update build process

0.8.0

  • Add ES6 build

0.7.0

0.6.5

  • Use rollup-babel

0.6.4

  • Update dependencies
  • General tidy-up

0.6.3

  • New writeSync method - same options as write (#16)
  • User-supplied content is correctly used in sourcesContent with loadSync (#16)

0.6.2

  • Handle segments of length 1 (normal segments have a length of 4 or 5) (#10)
  • Fix excludeContent CLI option (#12)
  • Fix sources array on Windows (#11)

0.6.1

  • Handle URLs that look a bit like data URIs

0.6.0

  • Use rollup for building, instead of esperanto

0.5.5

  • sourceRoot is respected

0.5.4

  • sourceMappingURLs are correctly encoded

0.5.3

  • Better CSS sourcemap handling (old comments are removed, new comments are block-style)

0.5.2

  • Handle CSS sourcemap comments

0.5.1

  • Fix build definition to prevent ES6-only features appearing in dist files
  • Hook up to Travis CI
  • Update tests to not use gobble (since latest gobble uses sorcery by default)

0.5.0

  • Allow user to supply content and sourcemaps, if available (#8)
  • Remove all existing sourceMappingURL comments
  • Allow base to be specified on chain.write(), i.e. chain.write({ base: somethingOtherThanDest })
  • Internal refactor

0.4.0

  • Handle sourceMappingURLs with spaces (#6)
  • Encode URLs when writing sourceMappingURL comments

0.3.5

  • Better handling of inline data URIs

0.3.4

  • Ensure trailing newline on chain.write() (#4)
  • Upgrade dependencies

0.3.3

  • Cache decodings for better performance
  • Add node.stat() method for rudimentary profiling

0.3.2

  • Significant (>2x) performance improvements (achieved by replacing forEach and map with for/while loops where appropriate, and avoiding hard-to-transpile destructuring)

0.3.1

  • Correct behaviour on Windows (#3)

0.3.0

  • Handle browserify-style line mappings

0.2.5

  • Re-architect as ES6 modules, add jsnext:main field to package.json

0.2.4

  • absolutePath option ensures sourceMappingURL is an absolute path to the resulting .map file

0.2.3

  • CLI now uses chain.write() internally

0.2.2

  • chain.write() will overwrite the existing file, if no destination is supplied
  • sorcery will use the sourcesContent array, rather than reading additional files, if possible

0.2.1

  • Implement chain.write()
  • Various bug fixes

0.2.0

  • Redesigned API around sorcery.load() - consult the docs
  • Command line interface

0.1.1

  • sorcery.resolve() fulfils with null if the target file has no sourcemap

0.1.0

  • First release. Here be dragons.