sorcery-map
TypeScript icon, indicating that this package has built-in type declarations

6.0.1 • Public • Published

sorcery-map.js

This package is a JavaScript source map management toolset

The purpose is to be consistent, have the same implemenation and the same options for managing these different features.

We merged pull requests

New features

  • Flatten is optional and can be limited to existing physical files only (ease the debugging)
  • source path can be customized, relative or absolute.
  • Provide a source root resolution fallback when map has been generated from another path (browserify)
  • sourceMappingURL can be inline content, absolute, relative...

Beware, all these features are experimental and not fully covered by tests, if you find an issue, do not hesitate to create a bug or contribute ;-)

Usage

First, install sorcery-map globally:

npm install -g sorcery-map

Options

Reading map (load, loadSync)

API Command line Value Description
--- -i, --input <file>
<folder>
Input file
Input folder
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
sourceRootResolution --sourceRootResolution base path of the relative sources path in the map

Generating map (apply, write, writeSync)

API Command line Value Description
--- -o, --output <file> Output file (if absent, will use input)
excludeContent -x, --excludeContent flag Don't populate the sourcesContent array
sourceMappingURLTemplate --sourceMappingURLTemplate [relative-path] (default)
[resource-path]
[absolute-path]
inline
none
<string>
SourceMapping path is relative to the file map location or sourceMappingURLBase
relative-path without root ([drive]:/ or /)
SourceMapping path is absoluteAppend map as a data URI rather than separate fileRemove map reference
TBD
sourceMappingURLBase --sourceMappingURLBase <folder> allows the base to be specified as something other than the map file, used by [relative-path]/[resource-path]
sourcePathTemplate --sourcePathTemplate [relative-path] (default)
[resource-path]
[absolute-path]
<string>
Source paths are relative to the file location or sourcePathBase
relative-path without root ([drive]:/ or /)
Source paths are absolute
Customize the relative path, can contain [relative-path] or [absolute-path]
for instance webpack://[resource-path]
sourcePathBase --sourcePathBase <folder> Base path for calculating relative source paths, used by [relative-path]/[resource-path]
sourceRoot --sourceRoot <folder> Root URL for loading relative source paths. Set as sourceRoot in the source map
flatten -f, --flatten full (default)
existing
<false>
flatten source map until the original file is reached
flatten source map as long as the file (content) exists
do not flatten the map

deprecated

API Command line Value Description
inline -d, --datauri flag equivalent to sourceMappingURLTemplate=inline
absolutePath --- flag equivalent to sourceMappingURLTemplate=[absolute-path]
sourceMappingURL --sourceMappingURL see sourceMappingURLTemplate

misc

Command line Description
-h, --help Show help message
-v, --version Show version

Sorcery-map

command line

  Usage:
    sorcery-map <input file> [options]

  Resolve a chain of sourcemaps back to the original source.

  Options:
    -h, --help                      Show help message
    -v, --version                   Show version
    -i, --input <file|folder>       Input file (option will override default provided value)
    -o, --output <file|folder>      Output file (if absent, will overwrite input)
    -d, --datauri                   Append map as a data URI, rather than separate file
    -x, --excludeContent            Do not 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-map -i some/generated/code.min.js

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

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

API

interface SourceMap {
    version: 3;
    file: string;
    sources: string[];
    sourcesContent: string[];
    names: string[];
    mappings: string;
    sourceRoot: string;
    toString(): string;
    toUrl(): string;
}

interface Chain {
    apply ( apply_options: Options ): SourceMap | null;
    trace ( oneBasedLineIndex: number, zeroBasedColumnIndex: number, trace_options: Options ): Trace;

    write ( write_options?: Options ): Promise<void>;
    write ( dest: string, write_options?: Options ): Promise<void>;
    writeSync ( write_options?: Options ): void;
    writeSync ( dest: string, write_options?: Options ): void;
}

function load(file: string, options: Options): Promise<Chain | null>;
function loadSync(file: string, options: Options): Chain | null;
var sorcery_map = require( 'sorcery-map' );

sorcery_map.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-map synchronously:
var chain = sorcery_map.loadSync( 'some/generated/code.min.js' );
var map = chain.apply();
var loc = chain.trace( x, y );
chain.writeSync();

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.

sorcery_map.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': {...}
  },
  existingContentOnly: false
}).then( chain => {
  /* ... */
});

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

Sorcery-exorcist

Can replace exorcist

command line

  Usage:
    sorcery-exorcist <map file> [options]

  Externalizes the source map of the file streamed in.

  The source map is written as JSON to map_file, and the original file is streamed out with its
  sourceMappingURL set to the path of map_file (or to the value of the --url option).

  Options:
    --base -b   Base path for calculating relative source paths.
                (default: use absolute paths)

    --root -r   Root URL for loading relative source paths.
                Set as sourceRoot in the source map.
                (default: '')

    --url -u   Full URL to source map.
              Set as sourceMappingURL in the output stream.
              (default: map_file)

    --error-on-missing -e   Abort with error if no map is found in the stream.
                          (default: warn but still pipe through source)

Examples:

  Bundle main.js with browserify into bundle.js and externalize the map to bundle.js.map.

    browserify main.js --debug | sorcery-exorcist bundle.js.map > bundle.js

API

function transform(mapFileOrStream: string | Writable, options?: Options): Transform;
  const basedir = process.cwd();
  const browserify_options = { 
        debug: true,
        basedir,
        ...options
    };

    browserify(inputFile, browserify_options)
    .bundle()
    .pipe(exorcist(mapFile, undefined, undefined, path.dirname(inputFile)))
    .pipe(fse.createWriteStream(bundleFile));

by such code

    .pipe(sorcery_map.transform(mapFile, { flatten: false, sourcePathBase: path.dirname(inputFile) }))]
    .pipe(fse.createWriteStream(bundleFile));

you can flatten the map at the same time

    .pipe(sorcery_map.transform(mapFile, {
        flatten: 'existing',
        sourcePathBase: path.dirname(inputFile),
        excludeContent: true
    }))]
    .pipe(fse.createWriteStream(bundleFile));

Webpack >= 5.x

Loader

If you are happy with source maps generated by Webpack but would like to have them flattened, this is the good way to do this.
Can replace source-map-loader. On our side, this plugin is in trouble when reaching content not present on the machine.

module.exports = {
...
  module: {
            rules: [
                {
                    test: /\.js$/,
                    use: [
                        { loader : 'sorcery-map/loader',
                          options: { 
                              excludeContent: true
                          }
                        },
                        // { loader : "source-map-loader" },
                    ]
                },
            ]

Plugin

If the Webpack source maps are not properly generated, problem of paths, roots, ... this plugin could help to fix/normalize them.

Here, webpack will generated map files using absolute paths, our plugin will normalize paths and flattern them.

const SorceryMapperPlugin = require('sorcery-map/plugin');

module.exports = {
 ...
  module: {
    devtool: "source-map",
    plugins: [new SorceryMapperPlugin( { excludeContent: true } )],

    output: {
        sourceMapFilename: `[file].map`,
        devtoolModuleFilenameTemplate: "[absolute-resource-path]",
        devtoolFallbackModuleFilenameTemplate: `"[absolute-resource-path]?[hash]`
    },

License

MIT

Dependencies (6)

Dev Dependencies (27)

Package Sidebar

Install

npm i sorcery-map

Weekly Downloads

2

Version

6.0.1

License

MIT

Unpacked Size

187 kB

Total Files

115

Last publish

Collaborators

  • emmkimme