Browse Source

better handling of external modules

contingency-plan
Rich Harris 10 years ago
parent
commit
ce3d61745b
  1. 38
      src/Bundle.js
  2. 3
      src/Module.js
  3. 11
      src/utils/resolvePath.js
  4. 3
      test/samples/allows-external-modules-from-nested-module/_config.js
  5. 6
      test/samples/allows-external-modules-from-nested-module/foo.js
  6. 8
      test/samples/allows-external-modules-from-nested-module/main.js
  7. 2
      test/samples/allows-external-modules/_config.js
  8. 3
      test/samples/export-from-internal-module/_config.js

38
src/Bundle.js

@ -8,13 +8,16 @@ import ExternalModule from './ExternalModule';
import finalisers from './finalisers/index'; import finalisers from './finalisers/index';
import replaceIdentifiers from './utils/replaceIdentifiers'; import replaceIdentifiers from './utils/replaceIdentifiers';
import makeLegalIdentifier from './utils/makeLegalIdentifier'; import makeLegalIdentifier from './utils/makeLegalIdentifier';
import { defaultResolver } from './utils/resolvePath';
export default class Bundle { export default class Bundle {
constructor ( options ) { constructor ( options ) {
this.base = options.base; this.base = options.base || process.cwd();
this.entryPath = resolve( this.base, options.entry ); this.entryPath = resolve( this.base, options.entry ).replace( /\.js$/, '' ) + '.js';
this.entryModule = null; this.entryModule = null;
this.resolvePath = options.resolvePath || defaultResolver;
this.modulePromises = {}; this.modulePromises = {};
this.modules = {}; this.modules = {};
@ -28,9 +31,19 @@ export default class Bundle {
this.externalModules = []; this.externalModules = [];
} }
fetchModule ( path, id ) { fetchModule ( importee, importer ) {
// TODO currently, we'll get different ExternalModule objects const path = this.resolvePath( importee, importer );
// depending on where they're imported from...
if ( !path ) {
// external module
if ( !has( this.modulePromises, importee ) ) {
const module = new ExternalModule( importee );
this.externalModules.push( module );
this.modulePromises[ importee ] = Promise.resolve( module );
}
return this.modulePromises[ importee ];
}
if ( !has( this.modulePromises, path ) ) { if ( !has( this.modulePromises, path ) ) {
this.modulePromises[ path ] = readFile( path, { encoding: 'utf-8' }) this.modulePromises[ path ] = readFile( path, { encoding: 'utf-8' })
@ -43,21 +56,6 @@ export default class Bundle {
this.modules[ path ] = module; this.modules[ path ] = module;
return module; return module;
}, err => {
if ( err.code === 'ENOENT' ) {
if ( id[0] === '.' ) {
// external modules can't have relative paths
throw err;
}
// most likely an external module
// TODO fire an event, or otherwise allow some way for
// users to control external modules better?
const module = new ExternalModule( id );
this.externalModules.push( module );
return module;
}
}); });
} }

3
src/Module.js

@ -184,9 +184,8 @@ export default class Module {
// The definition for this name is in a different module // The definition for this name is in a different module
if ( has( this.imports, name ) ) { if ( has( this.imports, name ) ) {
const importDeclaration = this.imports[ name ]; const importDeclaration = this.imports[ name ];
const path = resolve( dirname( this.path ), importDeclaration.source ) + '.js';
promise = this.bundle.fetchModule( path, importDeclaration.source ) promise = this.bundle.fetchModule( importDeclaration.source, this.path )
.then( module => { .then( module => {
importDeclaration.module = module; importDeclaration.module = module;

11
src/utils/resolvePath.js

@ -0,0 +1,11 @@
import { dirname, isAbsolute, resolve } from 'path';
export function defaultResolver ( importee, importer ) {
// absolute paths are left untouched
if ( isAbsolute( importee ) ) return importee;
// external modules stay external
if ( importee[0] !== '.' ) return false;
return resolve( dirname( importer ), importee ).replace( /\.js$/, '' ) + '.js';
}

3
test/samples/allows-external-modules-from-nested-module/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'imports external modules from nested internal modules'
};

6
test/samples/allows-external-modules-from-nested-module/foo.js

@ -0,0 +1,6 @@
import { relative } from 'path';
var path = 'a/b/c';
var path2 = 'a/c/b';
export default relative( path, path2 );

8
test/samples/allows-external-modules-from-nested-module/main.js

@ -0,0 +1,8 @@
import { relative } from 'path';
import foo from './foo';
var path = 'foo/bar/baz';
var path2 = 'foo/baz/bar';
assert.equal( relative( path, path2 ), '../../baz/bar' );
assert.equal( foo, '../../c/b' );

2
test/samples/allows-external-modules/_config.js

@ -1,3 +1,3 @@
module.exports = { module.exports = {
description: 'Non-existent modules are assumed to be external' description: 'Non-absolute and non-relative modules are assumed to be external'
}; };

3
test/samples/export-from-internal-module/_config.js

@ -2,6 +2,5 @@ module.exports = {
description: 'exports from an internal module', description: 'exports from an internal module',
exports: function ( exports, assert ) { exports: function ( exports, assert ) {
assert.equal( exports.foo, 42 ); assert.equal( exports.foo, 42 );
}, }
solo: true
}; };
Loading…
Cancel
Save