UNPKG

exorcist

Version:

Externalizes the source map found inside a stream to an external `.js.map` file

97 lines (79 loc) 3.26 kB
'use strict'; var mold = require('mold-source-map') , path = require('path') , fs = require('fs') , mkdirp = require('mkdirp') , isStream = require('is-stream') , fs = require('fs'); function separate(src, url, root, base) { src.sourceRoot(root || src.sourcemap.getProperty('sourceRoot') || ''); if (base) { src.mapSources(mold.mapPathRelativeTo(base)); } var json = src.toJSON(2); var comment = ''; var commentRx = /^\s*\/(\/|\*)[@#]\s+sourceMappingURL/mg; var commentMatch = commentRx.exec(src.source); var commentBlock = (commentMatch && commentMatch[1] === '*'); if (commentBlock) { comment = '/*# sourceMappingURL=' + url + ' */'; } else { comment = '//# sourceMappingURL=' + url; } return { json: json, comment: comment } } var go = module.exports = /** * * Externalizes the source map of the file streamed in. * * The source map is written as JSON to `file`, and the original file is streamed out with its * `sourceMappingURL` set to the path of `file` (or to the value of `url`). * * #### Events (in addition to stream events) * * - `missing-map` emitted if no map was found in the stream and errorOnMissing is falsey * (the src is still piped through in this case, but no map file is written) * * @name exorcist * @function * @param {String|Object} input file path or writable stream where the source map will be written * @param {String=} url full URL to the map file, set as `sourceMappingURL` in the streaming output (default: file) * @param {String=} root root URL for loading relative source paths, set as `sourceRoot` in the source map (default: '') * @param {String=} base base path for calculating relative source paths (default: use absolute paths) * @param {Boolean=} errorOnMissing when truthy, causes 'error' to be emitted instead of 'missing-map' if no map was found in the stream (default: falsey) * @return {TransformStream} transform stream into which to pipe the code containing the source map */ function exorcist(input, url, root, base, errorOnMissing) { var missingMapMsg = "The code that you piped into exorcist contains no source map!"; var stream = mold.transform(function(src, write) { if (!src.sourcemap) { if (errorOnMissing) return stream.emit('error', new Error(missingMapMsg)); stream.emit( 'missing-map' , missingMapMsg + '\n' + 'Therefore it was piped through as is and no external map file generated.' ); return write(src.source); } if (isStream(input) && isStream.writable(stream)) { return stream.emit('error', new Error('Must provide a writable stream')); } if (isStream(input) && typeof url !== 'string') { return stream.emit('error', new Error('map file URL is required when using stream output')); } url = url || path.basename(input) var separated = separate(src, url, root, base); if (isStream(input)) { return input.end(separated.json, 'utf8', done); } mkdirp(path.dirname(input)) .then(() => fs.writeFile(input, separated.json, 'utf8', done)) .catch(done); function done(err) { if (err) return stream.emit('error', err); write(separated.comment); } }); return stream; }