mirror of https://github.com/lukechilds/rollup.git
29 changed files with 327 additions and 37 deletions
@ -0,0 +1,69 @@ |
|||||
|
import { encode, decode } from 'sourcemap-codec'; |
||||
|
|
||||
|
function traceSegment ( loc, mappings ) { |
||||
|
const line = loc[0]; |
||||
|
const column = loc[1]; |
||||
|
|
||||
|
const segments = mappings[ line ]; |
||||
|
|
||||
|
if ( !segments ) return null; |
||||
|
|
||||
|
for ( let i = 0; i < segments.length; i += 1 ) { |
||||
|
const segment = segments[i]; |
||||
|
|
||||
|
if ( segment[0] > column ) return null; |
||||
|
|
||||
|
if ( segment[0] === column ) { |
||||
|
if ( segment[1] !== 0 ) { |
||||
|
throw new Error( 'Bad sourcemap' ); |
||||
|
} |
||||
|
|
||||
|
return [ segment[2], segment[3] ]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
export default function collapseSourcemaps ( map, modules ) { |
||||
|
const chains = modules.map( module => { |
||||
|
return module.sourceMapChain.map( map => decode( map.mappings ) ); |
||||
|
}); |
||||
|
|
||||
|
const decodedMappings = decode( map.mappings ); |
||||
|
|
||||
|
const tracedMappings = decodedMappings.map( line => { |
||||
|
let tracedLine = []; |
||||
|
|
||||
|
line.forEach( segment => { |
||||
|
const sourceIndex = segment[1]; |
||||
|
const sourceCodeLine = segment[2]; |
||||
|
const sourceCodeColumn = segment[3]; |
||||
|
|
||||
|
const chain = chains[ sourceIndex ]; |
||||
|
|
||||
|
let i = chain.length; |
||||
|
let traced = [ sourceCodeLine, sourceCodeColumn ]; |
||||
|
|
||||
|
while ( i-- && traced ) { |
||||
|
traced = traceSegment( traced, chain[i] ); |
||||
|
} |
||||
|
|
||||
|
if ( traced ) { |
||||
|
tracedLine.push([ |
||||
|
segment[0], |
||||
|
segment[1], |
||||
|
traced[0], |
||||
|
traced[1] |
||||
|
// TODO name?
|
||||
|
]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return tracedLine; |
||||
|
}); |
||||
|
|
||||
|
map.sourcesContent = modules.map( module => module.originalCode ); |
||||
|
map.mappings = encode( tracedMappings ); |
||||
|
return map; |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
// Return the first non-falsy result from an array of
|
||||
|
// maybe-sync, maybe-promise-returning functions
|
||||
|
export default function first ( candidates ) { |
||||
|
return function ( ...args ) { |
||||
|
return candidates.reduce( ( promise, candidate ) => { |
||||
|
return promise.then( result => result != null ? |
||||
|
result : |
||||
|
Promise.resolve( candidate( ...args ) ) ); |
||||
|
}, Promise.resolve() ); |
||||
|
} |
||||
|
} |
@ -1,10 +1,5 @@ |
|||||
import { readFileSync } from './fs'; |
import { readFileSync } from './fs'; |
||||
|
|
||||
export function defaultLoader ( id, options ) { |
export function defaultLoader ( id ) { |
||||
// TODO support plugins e.g. !css and !json?
|
return readFileSync( id, 'utf-8' ); |
||||
const source = readFileSync( id, 'utf-8' ); |
|
||||
|
|
||||
return options.transform.reduce( ( source, transformer ) => { |
|
||||
return transformer( source, id ); |
|
||||
}, source ); |
|
||||
} |
} |
||||
|
@ -0,0 +1,34 @@ |
|||||
|
export default function transform ( source, id, transformers ) { |
||||
|
let sourceMapChain = []; |
||||
|
|
||||
|
if ( typeof source === 'string' ) { |
||||
|
source = { |
||||
|
code: source, |
||||
|
ast: null |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
let originalCode = source.code; |
||||
|
let ast = source.ast; |
||||
|
|
||||
|
let code = transformers.reduce( ( previous, transformer ) => { |
||||
|
let result = transformer( previous, id ); |
||||
|
|
||||
|
if ( result == null ) return previous; |
||||
|
|
||||
|
if ( typeof result === 'string' ) { |
||||
|
result = { |
||||
|
code: result, |
||||
|
ast: null, |
||||
|
map: null |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
sourceMapChain.push( result.map ); |
||||
|
ast = result.ast; |
||||
|
|
||||
|
return result.code; |
||||
|
}, source.code ); |
||||
|
|
||||
|
return { code, originalCode, ast, sourceMapChain }; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
module.exports = { |
||||
|
description: 'adds an intro/outro', |
||||
|
options: { |
||||
|
intro: '/* this is an intro */', |
||||
|
outro: '/* this is an outro */' |
||||
|
} |
||||
|
}; |
@ -0,0 +1,7 @@ |
|||||
|
define(function () { 'use strict'; |
||||
|
|
||||
|
/* this is an intro */ |
||||
|
console.log( 'hello world' ); |
||||
|
/* this is an outro */ |
||||
|
|
||||
|
}); |
@ -0,0 +1,5 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
/* this is an intro */ |
||||
|
console.log( 'hello world' ); |
||||
|
/* this is an outro */ |
@ -0,0 +1,3 @@ |
|||||
|
/* this is an intro */ |
||||
|
console.log( 'hello world' ); |
||||
|
/* this is an outro */ |
@ -0,0 +1,7 @@ |
|||||
|
(function () { 'use strict'; |
||||
|
|
||||
|
/* this is an intro */ |
||||
|
console.log( 'hello world' ); |
||||
|
/* this is an outro */ |
||||
|
|
||||
|
})(); |
@ -0,0 +1,11 @@ |
|||||
|
(function (global, factory) { |
||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory() : |
||||
|
typeof define === 'function' && define.amd ? define(factory) : |
||||
|
factory(); |
||||
|
}(this, function () { 'use strict'; |
||||
|
|
||||
|
/* this is an intro */ |
||||
|
console.log( 'hello world' ); |
||||
|
/* this is an outro */ |
||||
|
|
||||
|
})); |
@ -0,0 +1 @@ |
|||||
|
console.log( 'hello world' ); |
@ -0,0 +1,19 @@ |
|||||
|
var fs = require( 'fs' ); |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'uses custom loaders, falling back to default', |
||||
|
options: { |
||||
|
load: [ |
||||
|
function ( id ) { |
||||
|
if ( /foo\.js/.test( id ) ) { |
||||
|
return fs.readFileSync( id, 'utf-8' ).replace( '@', 1 ); |
||||
|
} |
||||
|
}, |
||||
|
function ( id ) { |
||||
|
if ( /bar\.js/.test( id ) ) { |
||||
|
return fs.readFileSync( id, 'utf-8' ).replace( '@', 2 ); |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
}; |
@ -0,0 +1 @@ |
|||||
|
export default '@'; |
@ -0,0 +1 @@ |
|||||
|
export default '@'; |
@ -0,0 +1 @@ |
|||||
|
export default '@'; |
@ -0,0 +1,7 @@ |
|||||
|
import foo from './foo'; |
||||
|
import bar from './bar'; |
||||
|
import baz from './baz'; |
||||
|
|
||||
|
assert.equal( foo, '1' ); |
||||
|
assert.equal( bar, '2' ); |
||||
|
assert.equal( baz, '@' ); |
@ -0,0 +1,21 @@ |
|||||
|
var assert = require( 'assert' ); |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'resolver error is not caught', |
||||
|
options: { |
||||
|
resolveId: [ |
||||
|
function () { |
||||
|
throw new Error( 'nope' ); |
||||
|
}, |
||||
|
function ( importee, importer ) { |
||||
|
return 'main'; |
||||
|
} |
||||
|
], |
||||
|
load: function ( id ) { |
||||
|
if ( id === 'main' ) return 'assert.ok( false );' |
||||
|
} |
||||
|
}, |
||||
|
error: function ( err ) { |
||||
|
assert.equal( err.message, 'nope' ); |
||||
|
} |
||||
|
}; |
@ -0,0 +1,23 @@ |
|||||
|
var path = require( 'path' ); |
||||
|
var assert = require( 'assert' ); |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'uses custom path resolvers (plural)', |
||||
|
options: { |
||||
|
resolveId: [ |
||||
|
function ( importee ) { |
||||
|
if ( importee[0] === '@' ) |
||||
|
return path.resolve( __dirname, 'globals-' + importee.slice( 1 ).toLowerCase() + '.js' ); |
||||
|
}, |
||||
|
function ( importee ) { |
||||
|
if ( importee[0] === '!' ) return '<empty>'; |
||||
|
} |
||||
|
], |
||||
|
load: function ( id ) { |
||||
|
if ( id === '<empty>' ) return ''; |
||||
|
} |
||||
|
}, |
||||
|
exports: function ( exports ) { |
||||
|
assert.strictEqual( exports.res, 0 ); |
||||
|
} |
||||
|
}; |
@ -0,0 +1,2 @@ |
|||||
|
export var sin = Math.sin; |
||||
|
export var cos = Math.cos; |
@ -0,0 +1,4 @@ |
|||||
|
import { sin } from '@Math'; |
||||
|
import '!path'; |
||||
|
|
||||
|
export var res = sin( 0 ); |
@ -0,0 +1,46 @@ |
|||||
|
var babel = require( 'babel-core' ); |
||||
|
var MagicString = require( 'magic-string' ); |
||||
|
var assert = require( 'assert' ); |
||||
|
var getLocation = require( '../../utils/getLocation' ); |
||||
|
var SourceMapConsumer = require( 'source-map' ).SourceMapConsumer; |
||||
|
|
||||
|
module.exports = { |
||||
|
description: 'preserves sourcemap chains when transforming', |
||||
|
options: { |
||||
|
transform: [ |
||||
|
function ( source, id ) { |
||||
|
return babel.transform( source, { |
||||
|
blacklist: [ 'es6.modules' ], |
||||
|
sourceMap: true |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
function ( source, id ) { |
||||
|
var s = new MagicString( source ); |
||||
|
s.append( '\nassert.equal( 1 + 1, 2 );\nassert.equal( 2 + 2, 4 );' ); |
||||
|
|
||||
|
return { |
||||
|
code: s.toString(), |
||||
|
map: s.generateMap({ hires: true }) |
||||
|
}; |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
test: function ( code, map ) { |
||||
|
var smc = new SourceMapConsumer( map ); |
||||
|
|
||||
|
var generatedLoc = getLocation( code, code.indexOf( '42' ) ); |
||||
|
var originalLoc = smc.originalPositionFor( generatedLoc ); |
||||
|
|
||||
|
assert.ok( /foo/.test( originalLoc.source ) ); |
||||
|
assert.equal( originalLoc.line, 1 ); |
||||
|
assert.equal( originalLoc.column, 25 ); |
||||
|
|
||||
|
generatedLoc = getLocation( code, code.indexOf( 'log' ) ); |
||||
|
originalLoc = smc.originalPositionFor( generatedLoc ); |
||||
|
|
||||
|
assert.ok( /main/.test( originalLoc.source ) ); |
||||
|
assert.equal( originalLoc.line, 3 ); |
||||
|
assert.equal( originalLoc.column, 8 ); |
||||
|
} |
||||
|
}; |
@ -0,0 +1 @@ |
|||||
|
export const foo = () => 42; |
@ -0,0 +1,3 @@ |
|||||
|
import { foo } from './foo'; |
||||
|
|
||||
|
console.log( `the answer is ${foo()}` ); |
Loading…
Reference in new issue