function genSourceMap(modules) {
  var sourceMapGen = new SourceMapGenerator({file: 'bundle.js', version: 3});
  var bundleLineNo = 0;
  for (var i = 0; i < modules.length; i++) {
    var module = modules[i];
    var transformedCode = module.code;
    var sourcePath = module.sourcePath;
    var sourceCode = module.sourceCode;
    var transformedLineCount = 0;
    var lastCharNewLine = false;
    for (var t = 0; t < transformedCode.length; t++) {
      if (t === 0 || lastCharNewLine) {
        sourceMapGen.addMapping({
          generated: {line: bundleLineNo + 1, column: 0},
          original: {line: transformedLineCount + 1, column: 0},
          source: sourcePath
        });
      }
      lastCharNewLine = transformedCode[t] === '\n';
      if (lastCharNewLine) {
        transformedLineCount++;
        bundleLineNo++;
      }
    }
    bundleLineNo++;
    sourceMapGen.setSourceContent(
      sourcePath,
      sourceCode
    );
  }
  return sourceMapGen.toJSON();
}
Example #2
0
function generateMap(mappings, sourceRoot, mapFileBaseName, generatedLineOffset) {
  var SourceMapGenerator = require('source-map').SourceMapGenerator;

  var generator = new SourceMapGenerator({ file: mapFileBaseName });
  var seenFiles = Object.create(null);

  for (var generatedLineNumber in mappings) {
    var generatedLineNumber = parseInt(generatedLineNumber, 10);
    var mapping = mappings[generatedLineNumber];
    var originalFileName = mapping.originalFileName;
    generator.addMapping({
      generated: { line: generatedLineNumber + generatedLineOffset, column: 0 },
      original: { line: mapping.originalLineNumber, column: 0 },
      source: originalFileName
    });

    // we could call setSourceContent repeatedly, but readFileSync is slow, so
    // avoid doing it unnecessarily
    if (!(originalFileName in seenFiles)) {
      seenFiles[originalFileName] = true;
      var rootedPath = originalFileName[0] === path.sep ?
          originalFileName : path.join(sourceRoot, originalFileName);
      try {
        generator.setSourceContent(originalFileName, fs.readFileSync(rootedPath, 'utf-8'));
      } catch (e) {
        console.warn("sourcemapper: Unable to find original file for " + originalFileName +
          " at " + rootedPath);
      }
    }
  }

  fs.writeFileSync(mapFileBaseName + '.map', generator.toString());
}
Example #3
0
 obj.data.split('\n').forEach(function (line, idx) {
   smg.addMapping({
     source: name,
     original: { line: idx + 1, column: 0 },
     generated: { line: idx + 1, column: 0 }
   });
 });
Example #4
0
  it('generates source map', () => {
    const generator = new SourceMapGenerator({
      file: 'test.html'
    })
    generator.addMapping({
      source: 'test.html',
      original: { line: 1, column: 0 },
      generated: { line: 1, column: 0 }
    })
    const map = JSON.parse(generator.toString())

    const b = new Builder()
    b.addLine('var a = "a"')
    b.addLine('var render = function () { return "test" }', map)
    b.addLine('var b = "b"')

    const result = b.generate()
    const smc = new SourceMapConsumer(result.map)

    expect(result.code).toBe(code([
      'var a = "a"',
      'var render = function () { return "test" }',
      'var b = "b"'
    ]))

    let pos = smc.originalPositionFor({ line: 2, column: 0 })
    expect(pos.source).toBe('test.html')
    expect(pos.line).toBe(1)
    expect(pos.column).toBe(0)

    pos = smc.originalPositionFor({ line: 3, column: 0 })
    expect(pos.source).toBe(null)
    expect(pos.line).toBe(null)
    expect(pos.column).toBe(null)
  })
Example #5
0
 secret.mappings.forEach(function(mapping) {
   var sourceCursor = mapping.sourceLines.skipSpaces(mapping.sourceLoc.start) || mapping.sourceLines.lastPos();
   var targetCursor = targetLines.skipSpaces(mapping.targetLoc.start) || targetLines.lastPos();
   while (comparePos(sourceCursor, mapping.sourceLoc.end) < 0 && comparePos(targetCursor, mapping.targetLoc.end) < 0) {
     var sourceChar = mapping.sourceLines.charAt(sourceCursor);
     var targetChar = targetLines.charAt(targetCursor);
     assert.strictEqual(sourceChar, targetChar);
     var sourceName = mapping.sourceLines.name;
     smg.addMapping({
       source: sourceName,
       original: {
         line: sourceCursor.line,
         column: sourceCursor.column
       },
       generated: {
         line: targetCursor.line,
         column: targetCursor.column
       }
     });
     if (!hasOwn.call(sourcesToContents, sourceName)) {
       var sourceContent = mapping.sourceLines.toString();
       smg.setSourceContent(sourceName, sourceContent);
       sourcesToContents[sourceName] = sourceContent;
     }
     targetLines.nextPos(targetCursor, true);
     mapping.sourceLines.nextPos(sourceCursor, true);
   }
 });
Example #6
0
  mark(node) {
    let loc = node.loc;
    if (!loc) return; // no location info

    let map = this.map;
    if (!map) return; // no source map

    if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes

    let position = this.position;

    let generated = {
      line: position.line,
      column: position.column
    };

    let original = loc.start;

    // Avoid emitting duplicates on either side. Duplicated
    // original values creates unnecesssarily large source maps
    // and increases compile time. Duplicates on the generated
    // side can lead to incorrect mappings.
    if (comparePosition(original, this.last.original)
        || comparePosition(generated, this.last.generated)) {
      return;
    }

    this.last = {
      source: loc.filename || this.opts.sourceFileName,
      generated: generated,
      original: original
    };

    map.addMapping(this.last);
  }
Example #7
0
function getMap(fileName, sourceName, originalSource, generatedSource, options) {
  var map = new sourceMap.SourceMapGenerator({
    file: fileName
  });

  var defineToken = "define([";

  var commentMatcher = matcher.getComment(isFileCoffee(fileName));
  var commentMatch = commentMatcher.exec(originalSource);
  var commentEndIndex = commentMatch.index + commentMatch[0].length;

  var orgCoords = getCoordinates(originalSource, commentEndIndex);
  var genCoords = getCoordinates(generatedSource, defineToken);

  var offset = orgCoords.line - (genCoords.line + 1);

  var lineCount = generatedSource.split(/\r?\n/).length;
  for (var i = genCoords.line + 1; i < lineCount; i++) {
    map.addMapping({
      original: {
        line: i + offset,
        column: 1
      },
      generated: {
        line: i,
        column: 1 + getIndent(options).length,
      },
      source: sourceName
    });
  }

  return map.toString();
}
Example #8
0
 return function* (next) {
   var fileType = (this.url.match(/\.(js)$/) || [])[1];
   var file, content;
   if (fileType === 'js') {
     var yiminghe = this.yiminghe = this.yiminghe || {};
     file = path.join(dir, this.url);
     content = this.body;
     if (!content) {
       var json = 0;
       if (!fs.existsSync(file)) {
         if (util.endsWith(file, '.json.js')) {
           file = file.slice(0, -3);
           json = 1;
         }
       }
       if (!fs.existsSync(file)) {
         return yield *next;
       }
       content = fs.readFileSync(file, 'utf-8');
       yiminghe.source = content;
       if (json) {
         content = 'module.exports = ' + content + ';';
       }
     }
     if (!option.nowrap || !option.nowrap.call(this)) {
       content = modularizeUtils.completeRequire(file, content, option);
       var leading = 'define(function (require, exports, module) {'; // no \n does not change file no
       var contents = content.split(/\n/);
       var map = new SourceMap.SourceMapGenerator({
         file: 'source-mapped.js.map'
       });
       for (var i = 0; i < contents.length; i++) {
         map.addMapping({
           generated: {
             line: i + 1,
             column: 0
           },
           original: {
             line: i + 1,
             column: 0
           },
           source: this.url
         });
       }
       yiminghe.sourceMaps = yiminghe.sourceMaps || [];
       // plain json
       yiminghe.sourceMaps.push(map.toJSON());
       content = leading + content + '\n});';
     }
     this.set('Content-Type', 'application/javascript;charset=utf-8');
     this.set('Content-Length', Buffer.byteLength(content));
     this.body = content;
     if (option.next && option.next.call(this)) {
       yield *next;
     }
   } else {
     yield *next;
   }
 };
Example #9
0
function createSourceMap() {
  var map = new sourceMap.SourceMapGenerator({ file: 'forVisual.css' });
  map.addMapping({
    generated: { line: 2, column: 7 },
    source: 'forVisual.original.css',
    original: { line: 102, column: 107 },
  });
  return map;
}
 inMapConsumer.eachMapping(function(mapping) {
   if (mapping.generatedLine == i + 1) {
     mapping.generatedColumn += charDelta;
   }
   mapping.generatedLine += lineDelta;
   outMapGenerator.addMapping(
     {generated: {line: mapping.generatedLine, column: mapping.generatedColumn},
     original: {line: mapping.originalLine, column: mapping.originalColumn},
     source: mapping.source, name: mapping.name});
 });
Example #11
0
        var builder = (str, node, type) => {
            this.css += str;

            if ( node && node.source && node.source.start && type != 'end' ) {
                this.map.addMapping({
                    source:   this.sourcePath(node),
                    original: {
                        line:   node.source.start.line,
                        column: node.source.start.column - 1
                    },
                    generated: {
                        line:   line,
                        column: column - 1
                    }
                });
            }

            lines = str.match(/\n/g);
            if ( lines ) {
                line  += lines.length;
                last   = str.lastIndexOf("\n");
                column = str.length - last;
            } else {
                column = column + str.length;
            }

            if ( node && node.source && node.source.end && type != 'start' ) {
              this.map.addMapping({
                  source:   this.sourcePath(node),
                  original: {
                      line:   node.source.end.line,
                      column: node.source.end.column
                  },
                  generated: {
                      line:   line,
                      column: column
                  }
              });
            }
        };
Example #12
0
 function addMapping() {
   sourceMapGenerator.addMapping({
     generated: {
       line: generatedLineNumber,
       column: generatedColumnNumber
     },
     original: {
       line: originalLineNumber,
       column: originalColumnNumber
     },
     source: sourceUrl
   });
 }
Example #13
0
 mark(original) {
   if (!this.map) return;
   // use current location to mark the source map
   let position = this.position;
   this.map.addMapping({
     source: this.opts.sourceFileName,
     generated: {
       line: position.line,
       column: position.column
     },
     original: original
   });
 }
Example #14
0
function xform(mapping) {
  var generator = new sourceMap.SourceMapGenerator({
    file: "foo.js",
    sourceRoot: "http://example.com/"
  });

  generator.addMapping(mapping);

  babel.transform("a=1", {
    sourceMaps: true,
    inputSourceMap: JSON.parse(generator.toString()),
  });
}
Example #15
0
 map.eachMapping(function(mapping) {
     generator.addMapping({
         generated: {
             line: mapping.generatedLine + offset,
             column: mapping.generatedColumn
         },
         original: {
             line: mapping.originalLine,
             column: mapping.originalColumn
         },
         source: mapping.source,
         name: mapping.name
     });
 });
Example #16
0
export default function generate(pundle: Pundle, contents: Array<File>, requires: Array<string>, givenConfig: Object) {
  let lines = 0
  const config = Helpers.fillConfig(givenConfig)

  const output = []
  const sourceMap = new SourceMapGenerator({
    skipValidation: true,
  })

  if (config.wrapper === 'normal') {
    output.push(WrapperNormal)
    lines += Helpers.getLinesCount(WrapperNormal)
  } else if (config.wrapper === 'hmr') {
    output.push(WrapperHMR)
    lines += Helpers.getLinesCount(WrapperHMR)
  } else {
    lines = 1
  }
  for (const file of (contents: Array<File>)) {
    const fileContents = file.contents.trim()
    const entry = `__sb_pundle_register('${pundle.getUniquePathID(file.filePath)}', function(module, exports) {\n${fileContents}\n});`
    output.push(entry)

    if (!config.sourceMap) {
      continue
    }

    const entryPath = file.filePath.replace('$root', `$${config.projectName}`)
    const entryMap = new SourceMapConsumer(file.sourceMap)
    for (const mapping of entryMap._generatedMappings) {
      sourceMap.addMapping({
        source: entryPath,
        original: { line: mapping.originalLine, column: mapping.originalColumn },
        generated: { line: lines + mapping.generatedLine, column: mapping.generatedColumn },
      })
    }
    lines += Helpers.getLinesCount(fileContents)
    lines ++
    sourceMap.setSourceContent(entryPath, file.source)
  }
  for (const entry of (requires: Array<string>)) {
    output.push(`__require('${pundle.getUniquePathID(entry)}')`)
  }

  return {
    contents: output.join(''),
    sourceMap: config.sourceMap ? sourceMap.toJSON() : null,
  }
}
Example #17
0
    wrapSourceMap(map).eachMapping(function(mapping) {
      if (mapping.source.match(/(\/|^)@traceur/))
        return;

      generated.addMapping({
        generated: {
          line: offset + mapping.generatedLine,
          column: mapping.generatedColumn
        },
        original: {
          line: mapping.originalLine,
          column: mapping.originalColumn
        },
        source: mapping.source
      });
    });
    consumer.eachMapping(function(m) {

        var path = m.source.replace(sourcemap.sourceRoot, '').replace(this.rootDir, '');
        var filepath = Module._findPath(path, [this.rootDir, this.sourceDir]).replace(this.sourceDir, '').replace(this.rootDir, '');

        if(filepath.charAt(0) == '/'){
        	filepath = filepath.substr(1);
        }

        generator.addMapping({
            source: '/' + filepath,
            original: { line: m.originalLine, column: m.originalColumn },
            generated: { line: m.generatedLine, column: m.generatedColumn }
        });

    }.bind(this), {}, consumer.ORIGINAL_ORDER);
Example #19
0
/**
 * Create source map from 'content'
 * @param {String} content
 * @param {String} [url]
 * @returns {SourceMapGenerator}
 */
function create(content, url) {
  url = url || '<source>';
  const map = new SourceMapGenerator({ file: url });
  const lines = content.split('\n');

  for (let l = 1, n = lines.length; l <= n; l++) {
    // Skip empty
    if (lines[l - 1]) {
      map.addMapping({
        source: url,
        original: { line: l, column: 0 },
        generated: { line: l, column: 0 }
      });
    }
  }

  map.setSourceContent(url, content);
  return map;
}
 function mapForASTs(origAst, rewrittenAst, origFile, optFilename) {
     var generator = new sourcemap.SourceMapGenerator({ file: optFilename });
     if (isNaN(origAst.astIndex))
         throw new Error('Source Mapping is done by AST indices but astIndex is missing!');
     var idx, maxIdx = origAst.astIndex;
     for (idx = 0; idx <= maxIdx; idx++) {
         var origNode = acorn.walk.findNodeByAstIndex(origAst, idx, false);
         var rewrittenNode = acorn.walk.findNodeByAstIndex(rewrittenAst, idx, false);
         if (origNode == null || rewrittenNode == null) {
             console.warn('Could not find AST index %s in given ASTs for file %s when generating source map', idx, origFile);
             continue;
         }
         generator.addMapping({
             original: { line: origNode.loc.start.line, column: origNode.loc.start.column },
             generated: { line: rewrittenNode.loc.start.line, column: rewrittenNode.loc.start.column },
             source: origFile
         });
     }
     return generator.toString();
 }
Example #21
0
        it("should generate correct sourcemaps for default options", function() {
            var fileName = "whatever.js";
            var options = {};
            var result = iife.surround(code, options, { fileName });

            var expectedMap = new SourceMapGenerator({ file: fileName });

            expectedMap.addMapping({
                source: fileName,
                original: {
                    line: 1,
                    column: 0
                },
                generated: {
                    line: 4,
                    column: 0
                }
            });

            assert.equal(result.sourceMap, expectedMap.toString());
        });
Example #22
0
function generateSourceMap(originalCode, options, sourceMapOptions) {
    // We don't care about trailing lines for the mapping
    var code = originalCode.trimRight();

    var sourceMapGenerator = new SourceMapGenerator({
        file: sourceMapOptions.fileName
    });

    // We have at least one line of positive offset because of the start of the IIFE
    var linesOffset = 1;

    // Then we have optionally two more lines because of the "use strict"
    // and the empty line after that
    linesOffset += options.useStrict ? 2 : 0;

    // Then we have negative lines for the leading empty lines that are trimmed
    var leadingEmptyLines = ((code.match(/^\s+/) || [""])[0].match(/\n/g) || []).length;
    linesOffset -= options.trimCode ? leadingEmptyLines : 0;

    // We add sourcemaps only for the non-empty lines.
    // So, we start the loop in the first non-empty line.
    // (The trailing empty lines are already trimmed.)
    var codeLines = (code.trimLeft().match(/\n/g) || []).length + 1;

    for (var i = 1 + leadingEmptyLines; i <= codeLines + leadingEmptyLines; i++) {
        sourceMapGenerator.addMapping({
            source: sourceMapOptions.fileName,
            original: {
                line: i,
                column: 0
            },
            generated: {
                line: i + linesOffset,
                column: 0
            }
        });
    }

    return sourceMapGenerator.toString();
}
Example #23
0
        it("should generate correct sourcemaps when \"trimCode\" is true", function() {
            var codeWithLeadingSpace = "\n\n" + code;
            var fileName = "whatever.js";
            var options = { trimCode: true };
            var result = iife.surround(codeWithLeadingSpace, options, { fileName });

            var expectedMap = new SourceMapGenerator({ file: fileName });

            expectedMap.addMapping({
                source: fileName,
                original: {
                    line: 3,
                    column: 0
                },
                generated: {
                    line: 4,
                    column: 0
                }
            });

            assert.equal(result.sourceMap, expectedMap.toString());
        });
Example #24
0
export function generateMap (loader, source, iterator) {
  const filePath = loader.resourcePath

  const fileNameWithHash = getFileNameWithHash(filePath)
  const sourceRoot = path.resolve('.')

  const map = new SourceMapGenerator({
    sourceRoot,
    skipValidation: true
  })
  map.setSourceContent(fileNameWithHash, source)

  for (const { original, generated } of iterator) {
    map.addMapping({
      source: fileNameWithHash,
      original,
      generated
    })
  }

  return map
}
Example #25
0
function generateJs(sourcePath, fileContent) {
  var generator = new SourceMapGenerator({ file: sourcePath });
  var tokenizer = acorn.tokenizer(fileContent, { allowHashBang: true, locations: true });

  while (true) {
    var token = tokenizer.getToken();

    if (token.type.label === 'eof') {
      break;
    }
    var mapping = {
      original: token.loc.start,
      generated: token.loc.start,
      source: sourcePath,
    };
    if (token.type.label === 'name') {
      mapping.name = token.value;
    }
    generator.addMapping(mapping);
  }
  generator.setSourceContent(sourcePath, fileContent);

  return generator.toJSON();
}
Example #26
0
  mark(node, type) {
    var loc = node.loc;
    if (!loc) return; // no location info

    var map = this.map;
    if (!map) return; // no source map

    if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes

    var position = this.position;

    var generated = {
      line: position.line,
      column: position.column
    };

    var original = loc[type];

    map.addMapping({
      source: this.opts.sourceFileName,
      generated: generated,
      original: original
    });
  }
 new sourceMap.SourceMapConsumer(sourceMaps[i]).eachMapping(function(mapping) {
   outMapGenerator.addMapping({
     generated: {line: mapping.generatedLine + lineDelta, column: mapping.generatedColumn},
     original: {line: mapping.originalLine, column: mapping.originalColumn},
     source: mapping.source, name: mapping.name});
 });
Example #28
0
        function(cb)
        {
            if(!isfile(args.target) ||
               files.some(function(f){ return isnewer(f.path, args.target); }))
            {
                var d = new Depends();
                files.forEach(
                    function(file)
                    {
                        var depend = {file: file, depends:[]};
                        d.depends.push(depend);
                        try
                        {
                            Parser.transverse(esprima.parse(file.contents.toString()), depend, args.srcDir);
                        }
                        catch(e)
                        {
                            throw new Error(file.path + ": " + e.toString());
                        }
                    });

                d.depends = d.expand().sort();

                var sourceMap = new sourcemap.SourceMapGenerator(
                    {
                        file: path.basename(args.target)
                    });
                var lineOffset = 0;

                //
                // Wrap the library in a closure to hold the private Slice module.
                //
                var preamble =
                    "(function()\n" +
                    "{\n";

                var epilogue =
                    "}());\n\n";

                //
                // Wrap contents of each file in a closure to keep local variables local.
                //
                var modulePreamble =
                    "\n" +
                    "    (function()\n" +
                    "    {\n";

                var moduleEpilogue =
                    "    }());\n";

                var sb = new StringBuffer();

                sb.write(preamble);
                sb.write("    var root = typeof(window) !== \"undefined\" ? window : typeof(global) !== \"undefined\" ? global : typeof(self) !== \"undefined\" ? self : {};\n");
                lineOffset += 3;
                args.modules.forEach(
                    function(m){
                        sb.write("    root." + m + " = root." + m + " || {};\n");
                        lineOffset++;

                        if(m == "Ice")
                        {
                            sb.write("    Ice.Slice = Ice.Slice || {};\n");
                            lineOffset++;
                        }
                    });
                sb.write("    var Slice = Ice.Slice;\n");
                lineOffset++;

                for(var i = 0;  i < d.depends.length; ++i)
                {
                    sb.write(modulePreamble);
                    lineOffset += 3;

                    var data = d.depends[i].file.contents.toString();
                    var file = d.depends[i].file;
                    var lines = data.toString().split("\n");

                    var skip = false;
                    var skipUntil;
                    var skipAuto = false;
                    var line;
                    var out;

                    var j = 0;
                    for(j = 0; j < lines.length; j++)
                    {
                        out = lines[j];
                        line = out.trim();

                        if(line == "/* slice2js browser-bundle-skip */")
                        {
                            skipAuto = true;
                            continue;
                        }
                        if(line == "/* slice2js browser-bundle-skip-end */")
                        {
                            skipAuto = false;
                            continue;
                        }
                        else if(skipAuto)
                        {
                            continue;
                        }

                        //
                        // Get rid of require statements, the bundle include all required files,
                        // so require statements are not required.
                        //
                        if(line.match(/const .* require\(".*"\).*;/))
                        {
                            continue;
                        }
                        if(line.match(/_ModuleRegistry\.require\(/))
                        {
                            if(line.lastIndexOf(";") === -1)
                            {
                                // skip until next semicolon
                                skip = true;
                                skipUntil = ";";
                            }
                            continue;
                        }

                        //
                        // Get rid of _ModuleRegistry.module statements, in browser top level modules are
                        // global.
                        //
                        if(line.match(/const .* = _ModuleRegistry.module\(/))
                        {
                            if(line.lastIndexOf(";") === -1)
                            {
                                // skip until next semicolon
                                skip = true;
                                skipUntil = ";";
                            }
                            continue;
                        }

                        if(skip)
                        {
                            if(line.lastIndexOf(skipUntil) !== -1)
                            {
                                skip = false;
                            }
                            continue;
                        }

                        if(line.indexOf("module.exports.") === 0)
                        {
                            continue;
                        }
                        else if(line.indexOf("exports.") === 0)
                        {
                            continue;
                        }
                        else if(line.indexOf("exports =") === 0)
                        {
                            continue;
                        }

                        sb.write("        " + out + "\n");

                        sourceMap.addMapping(
                            {
                                generated:
                                {
                                    line: lineOffset + 1,
                                    column: 8
                                },
                                original:
                                {
                                    line: j + 1,
                                    column:0
                                },
                                source: sourceMapRelativePath(file.path)
                            });
                        lineOffset++;
                    }
                    sb.write(moduleEpilogue);
                    lineOffset++;
                }
                sb.write("\n");
                lineOffset++;

                //
                // Now exports the modules to the global object.
                //
                args.modules.forEach(
                    function(m){
                        sb.write("    root." + m + " = " + m + ";\n");
                        lineOffset++;
                    });

                sb.write(epilogue);
                lineOffset++;

                var target = new gutil.File(
                    {
                        cwd: "",
                        base:"",
                        path:path.basename(args.target),
                        contents:sb.buffer
                    });
                target.sourceMap = JSON.parse(sourceMap.toString());
                this.push(target);
            }
            cb();
        });
Example #29
0
File: init.js Project: 4gekkman/R5
  function sourceMapInit(file, encoding, callback) {
    /*jshint validthis:true */

    // pass through if file is null or already has a source map
    if (file.isNull() || file.sourceMap) {
      this.push(file);
      return callback();
    }

    if (file.isStream()) {
      return callback(new Error(PLUGIN_NAME + '-init: Streaming not supported'));
    }

    if (options === undefined) {
      options = {};
    }
    debug(function() {
      return options;
    });

    var fileContent = file.contents.toString();
    var sourceMap;

    if (options.loadMaps) {
      debug('loadMaps');
      var sourcePath = ''; //root path for the sources in the map

      // Try to read inline source map
      sourceMap = convert.fromSource(fileContent, options.largeFile);
      if (sourceMap) {
        sourceMap = sourceMap.toObject();
        // sources in map are relative to the source file
        sourcePath = path.dirname(file.path);
        if (!options.largeFile) {
          fileContent = convert.removeComments(fileContent);
        }
      } else {
        // look for source map comment referencing a source map file
        var mapComment = convert.mapFileCommentRegex.exec(fileContent);

        var mapFile;
        if (mapComment) {
          mapFile = path.resolve(path.dirname(file.path), mapComment[1] || mapComment[2]);
          fileContent = convert.removeMapFileComments(fileContent);
          // if no comment try map file with same name as source file
        } else {
          mapFile = file.path + '.map';
        }

        // sources in external map are relative to map file
        sourcePath = path.dirname(mapFile);

        try {
          sourceMap = JSON.parse(stripBom(fs.readFileSync(mapFile, 'utf8')));
        } catch (e) {}
      }

      // fix source paths and sourceContent for imported source map
      if (sourceMap) {
        sourceMap.sourcesContent = sourceMap.sourcesContent || [];
        sourceMap.sources.forEach(function(source, i) {
          if (source.match(urlRegex)) {
            sourceMap.sourcesContent[i] = sourceMap.sourcesContent[i] || null;
            return;
          }
          var absPath = path.resolve(sourcePath, source);
          sourceMap.sources[i] = unixStylePath(path.relative(file.base, absPath));

          if (!sourceMap.sourcesContent[i]) {
            var sourceContent = null;
            if (sourceMap.sourceRoot) {
              if (sourceMap.sourceRoot.match(urlRegex)) {
                sourceMap.sourcesContent[i] = null;
                return;
              }
              absPath = path.resolve(sourcePath, sourceMap.sourceRoot, source);
            }

            // if current file: use content
            if (absPath === file.path) {
              sourceContent = fileContent;

              // else load content from file
            } else {
              try {
                if (options.debug)
                  debug('No source content for "' + source + '". Loading from file.');
                sourceContent = stripBom(fs.readFileSync(absPath, 'utf8'));
              } catch (e) {
                if (options.debug)
                  debug('warn: source file not found: ' + absPath);
                }
              }
            sourceMap.sourcesContent[i] = sourceContent;
          }
        });

        // remove source map comment from source
        file.contents = new Buffer(fileContent, 'utf8');
      }
    }

    if (!sourceMap && options.identityMap) {
      debug(function() {
        return 'identityMap';
      });
      var fileType = path.extname(file.path);
      var source = unixStylePath(file.relative);
      var generator = new SourceMapGenerator({file: source});

      if (fileType === '.js') {
        var tokenizer = acorn.tokenizer(fileContent, {locations: true});
        while (true) {
          var token = tokenizer.getToken();
          if (token.type.label === "eof")
            break;
          var mapping = {
            original: token.loc.start,
            generated: token.loc.start,
            source: source
          };
          if (token.type.label === 'name') {
            mapping.name = token.value;
          }
          generator.addMapping(mapping);
        }
        generator.setSourceContent(source, fileContent);
        sourceMap = generator.toJSON();

      } else if (fileType === '.css') {
        debug('css');
        var ast = css.parse(fileContent, {silent: true});
        debug(function() {
          return ast;
        });
        var registerTokens = function(ast) {
          if (ast.position) {
            generator.addMapping({original: ast.position.start, generated: ast.position.start, source: source});
          }

          function logAst(key, ast) {
            debug(function() {
              return 'key: ' + key;
            });
            debug(function() {
              return ast[key];
            });
          }

          for (var key in ast) {
            logAst(key, ast);
            if (key !== "position") {
              if (Object.prototype.toString.call(ast[key]) === '[object Object]') {
                registerTokens(ast[key]);
              } else if (Array.isArray(ast[key])) {
                debug(function() {
                  return "@@@@ ast[key] isArray @@@@";
                });
                for (var i = 0; i < ast[key].length; i++) {
                  registerTokens(ast[key][i]);
                }
              }
            }
          }
        };
        registerTokens(ast);
        generator.setSourceContent(source, fileContent);
        sourceMap = generator.toJSON();
      }
    }

    if (!sourceMap) {
      // Make an empty source map
      sourceMap = {
        version: 3,
        names: [],
        mappings: '',
        sources: [unixStylePath(file.relative)],
        sourcesContent: [fileContent]
      };
    }

    sourceMap.file = unixStylePath(file.relative);
    file.sourceMap = sourceMap;

    this.push(file);
    callback();
  }
Example #30
0
function wrapMendelModule(module) {
    var keepProps = ['id', 'normalizedId', 'variation', 'entry', 'expose'];
    var browserModule = Object.keys(module).reduce((bModule, key) => {
        if (keepProps.includes(key)) {
            bModule[key] = module[key];
        }
        return bModule;
    }, {});

    browserModule.deps = Object.keys(module.deps).reduce((deps, key) => {
        let originalDep = module.deps[key];

        if (typeof originalDep === 'string') {
            deps[key] = originalDep;
            return deps;
        }

        const firstKey = Object.keys(originalDep)[0];
        // most important last will override prev
        deps[key] = [firstKey, 'main', 'browser'].reduce((prev, key) => {
            return originalDep[key] || prev;
        }, '');

        return deps;
    }, {});

    browserModule.moduleFn = 'MENDEL_REPLACE';

    var moduleString = JSON.stringify(browserModule);

    var moduleBeforeSource =
        'window.__mendel_module__["' + module.id + '"] = ' + moduleString + ';';

    var parts = moduleBeforeSource.split('"MENDEL_REPLACE"');
    parts[0] = parts[0] + 'function(require,module,exports){\n';
    parts[1] = '\n}' + parts[1];
    var padLines = parts[0].split('\n');
    var padCol = padLines[padLines.length - 1].length;

    var output = parts[0] + module.source + parts[1];

    var newSourceMap = new SourceMapGenerator({file: module.id});
    var finalMap;
    if (module.map) {
        // remap existing map summing our module padding
        var existingMap = new SourceMapConsumer(module.map);
        existingMap.eachMapping(function(mapping) {
            const add = {
                original: {
                    line: mapping.originalLine,
                    column: mapping.originalColumn,
                },
                generated: {
                    line: padLines.length - 1 + mapping.generatedLine,
                    column:
                        mapping.generatedLine !== 1
                            ? mapping.generatedColumn
                            : padCol + mapping.generatedColumn,
                },
                source: mapping.source,
                name: mapping.name,
            };
            if (
                null === mapping.originalLine ||
                null === mapping.originalColumn
            ) {
                add.original = null;
            }
            newSourceMap.addMapping(add);
            // Only use mappings from new map, so we keep paths in a way
            // that karma understands and keeps track of it
            const newMapObject = JSON.parse(newSourceMap.toString());
            finalMap = JSON.stringify(
                Object.assign({}, module.map, {
                    mappings: newMapObject.mappings,
                })
            );
        });
    } else {
        // create a line-only sourcemap, accounting for padding
        var sourceLinesCount = module.source.split('\n');
        for (var i = 1; i <= sourceLinesCount.length; i++) {
            newSourceMap.addMapping({
                original: {
                    line: i,
                    column: 0,
                },
                generated: {
                    line: i + padLines.length - 1,
                    column: i === 1 ? padCol : 0,
                },
                source: module.id,
            });
        }
        newSourceMap.setSourceContent(module.id, module.source);
        finalMap = newSourceMap.toString();
    }

    var comment = [
        INLINE_MAP_PREFIX,
        new Buffer(finalMap).toString('base64'),
    ].join('');

    return output + '\n' + comment + '\n';
}