Skip to content

Commit

Permalink
Merge pull request #99 from esperantojs/resolution
Browse files Browse the repository at this point in the history
Resolution
  • Loading branch information
Rich-Harris committed Feb 8, 2015
2 parents 6ed4a54 + 85610f9 commit 3bc515c
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 55 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"gobble-esperanto-bundle": "^0.1.4",
"gobble-uglifyjs": "^0.1.0",
"mocha": "^2.1.0",
"resolve": "^1.1.0",
"sander": "^0.2.1",
"source-map": "^0.1.40"
},
Expand Down
2 changes: 1 addition & 1 deletion src/bundler/combine/populateIdentifierReplacements.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function populateIdentifierReplacements ( bundle ) {
// then determine which existing identifiers
// need to be replaced
bundle.modules.forEach( mod => {
var moduleIdentifiers, x;
var moduleIdentifiers;

moduleIdentifiers = mod.identifierReplacements;

Expand Down
3 changes: 2 additions & 1 deletion src/bundler/combine/transformBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ export default function transformBody ( bundle, mod, body ) {
if ( name === identifierReplacements.default ) {
body.remove( x.start, x.end );
} else {
body.replace( x.start, x.end, `var ${identifierReplacements.default} = ${identifierReplacements[name]};` );
let original = hasOwnProp.call( identifierReplacements, name ) ? identifierReplacements[ name ] : name;
body.replace( x.start, x.end, `var ${identifierReplacements.default} = ${original};` );
}
}

Expand Down
107 changes: 56 additions & 51 deletions src/bundler/getBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function getBundle ( options ) {
entry = entry.substring( base.length );
}

return fetchModule( entry ).then( () => {
return fetchModule( entry, null ).then( () => {
var entryModule, bundle;

entryModule = moduleLookup[ entry ];
Expand All @@ -48,76 +48,61 @@ export default function getBundle ( options ) {
return bundle;
});

function fetchModule ( moduleId ) {
var modulePath;

modulePath = path.resolve( base, moduleId + '.js' );

function fetchModule ( moduleId, importerPath ) {
if ( !hasOwnProp.call( promiseById, moduleId ) ) {
promiseById[ moduleId ] = sander.readFile( modulePath ).catch( function ( err ) {
if ( err.code === 'ENOENT' ) {
modulePath = modulePath.replace( /\.js$/, '/index.js' );
return sander.readFile( modulePath );
}

throw err;
}).then( function ( source ) {
source = String( source );
promiseById[ moduleId ] = resolvePath( base, moduleId, importerPath, options.resolvePath ).then( modulePath => {
return sander.readFile( modulePath ).then( String ).then( function ( source ) {
var module, promises;

if ( options.transform ) {
source = options.transform( source, modulePath );
if ( options.transform ) {
source = options.transform( source, modulePath );

if ( typeof source !== 'string' && !isThenable( source ) ) {
throw new Error( 'transform should return String or Promise' );
if ( typeof source !== 'string' && !isThenable( source ) ) {
throw new Error( 'transform should return String or Promise' );
}
}
}

return source;
}).then( function ( source ) {
var module, promises;
module = getModule({
source: source,
id: moduleId,
file: modulePath.substring( base.length ),
path: modulePath
});

module = getModule({
source: source,
id: moduleId,
file: modulePath.substring( base.length ),
path: modulePath
});
modules.push( module );
moduleLookup[ moduleId ] = module;

modules.push( module );
moduleLookup[ moduleId ] = module;
promises = module.imports.map( x => {
x.id = resolveId( x.path, module.file );

promises = module.imports.map( x => {
x.id = resolveId( x.path, module.file );
if ( x.id === moduleId ) {
throw new Error( 'A module (' + moduleId + ') cannot import itself' );
}

if ( x.id === moduleId ) {
throw new Error( 'A module (' + moduleId + ') cannot import itself' );
}
// Some modules can be skipped
if ( skip && ~skip.indexOf( x.id ) ) {
return;
}

// Some modules can be skipped
if ( skip && ~skip.indexOf( x.id ) ) {
return;
}
// short-circuit cycles
if ( hasOwnProp.call( promiseById, x.id ) ) {
return;
}

// short-circuit cycles
if ( hasOwnProp.call( promiseById, x.id ) ) {
return;
}
return fetchModule( x.id, modulePath );
});

return fetchModule( x.id );
return Promise.all( promises );
});

return Promise.all( promises );
}).catch( function ( err ) {
var externalModule;

}, function ( err ) {
if ( err.code === 'ENOENT' ) {
if ( moduleId === entry ) {
throw new Error( 'Could not find entry module (' + entry + ')' );
}

// Most likely an external module
if ( !hasOwnProp.call( externalModuleLookup, moduleId ) ) {
externalModule = {
let externalModule = {
id: moduleId
};

Expand All @@ -134,6 +119,26 @@ export default function getBundle ( options ) {
}
}

function resolvePath ( base, moduleId, importerPath, resolver ) {
return tryPath( base + moduleId + '.js' )
.catch( function () {
return tryPath( base + moduleId + path.sep + 'index.js' );
})
.catch( function ( err ) {
if ( resolver ) {
return resolver( moduleId, importerPath );
} else {
throw err;
}
});
}

function tryPath ( path ) {
return sander.stat( path ).then( function () {
return path;
});
}

function isThenable ( obj ) {
return obj && typeof obj.then === 'function';
}
3 changes: 2 additions & 1 deletion test/bundle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ module.exports = function () {
entry: config.entry || 'main',
skip: config.skip,
names: config.names,
transform: config.transform
transform: config.transform,
resolvePath: config.resolvePath
}).then( function ( bundle ) {
var options, actual;

Expand Down
30 changes: 30 additions & 0 deletions test/bundle/input/35/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var path = require( 'path' );
var Promise = require( 'sander' ).Promise;
var resolve = require( 'resolve' );

module.exports = {
description: 'External module paths can be resolved with resolvePath option',
resolvePath: function ( importee, importer ) {
return new Promise( function ( fulfil, reject ) {
var callback = function ( err, result ) {
if ( err ) {
reject( err );
} else {
fulfil( result );
}
};

resolve( importee, {
basedir: path.dirname( importer ),
moduleDirectory: 'js_modules', // to avoid faffing with .gitignore
packageFilter: function ( pkg ) {
if ( pkg[ 'jsnext:main' ] ) {
pkg.main = pkg[ 'jsnext:main' ];
}

return pkg;
}
}, callback );
});
}
};
3 changes: 3 additions & 0 deletions test/bundle/input/35/js_modules/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function a () {
console.log( 'I am module a' );
}
3 changes: 3 additions & 0 deletions test/bundle/input/35/js_modules/c.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function c () {
console.log( 'I am module c' );
}
8 changes: 8 additions & 0 deletions test/bundle/input/35/js_modules/external/dist/external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import a from 'a';
import b from 'b';

export default function external () {
console.log( 'I am an external dependency' );
a();
b();
}
6 changes: 6 additions & 0 deletions test/bundle/input/35/js_modules/external/js_modules/b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import c from 'c';

export default function b () {
console.log( 'I am module b' );
c();
}
6 changes: 6 additions & 0 deletions test/bundle/input/35/js_modules/external/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "external",
"version": "0.1.0",
"main": "dist/external.js",
"jsnext:main": "src/external.js"
}
8 changes: 8 additions & 0 deletions test/bundle/input/35/js_modules/external/src/external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import a from 'a';
import b from 'b';

export default function external () {
console.log( 'I am an external dependency' );
a();
b();
}
3 changes: 3 additions & 0 deletions test/bundle/input/35/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import external from 'external';

external();
26 changes: 26 additions & 0 deletions test/bundle/output/amd/35.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
define(function () {

'use strict';

function a () {
console.log( 'I am module a' );
}

function c () {
console.log( 'I am module c' );
}

function b () {
console.log( 'I am module b' );
c();
}

function external () {
console.log( 'I am an external dependency' );
a();
b();
}

external();

});
26 changes: 26 additions & 0 deletions test/bundle/output/amdDefaults/35.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
define(function () {

'use strict';

function a () {
console.log( 'I am module a' );
}

function c () {
console.log( 'I am module c' );
}

function b () {
console.log( 'I am module b' );
c();
}

function external () {
console.log( 'I am an external dependency' );
a();
b();
}

external();

});
22 changes: 22 additions & 0 deletions test/bundle/output/cjs/35.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

function a () {
console.log( 'I am module a' );
}

function c () {
console.log( 'I am module c' );
}

function b () {
console.log( 'I am module b' );
c();
}

function external () {
console.log( 'I am an external dependency' );
a();
b();
}

external();
22 changes: 22 additions & 0 deletions test/bundle/output/cjsDefaults/35.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

function a () {
console.log( 'I am module a' );
}

function c () {
console.log( 'I am module c' );
}

function b () {
console.log( 'I am module b' );
c();
}

function external () {
console.log( 'I am an external dependency' );
a();
b();
}

external();
24 changes: 24 additions & 0 deletions test/bundle/output/concat/35.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(function () { 'use strict';

function a () {
console.log( 'I am module a' );
}

function c () {
console.log( 'I am module c' );
}

function b () {
console.log( 'I am module b' );
c();
}

function external () {
console.log( 'I am an external dependency' );
a();
b();
}

external();

})();

0 comments on commit 3bc515c

Please sign in to comment.