Browse Source

resolve jsnext:main in node_modules by default, allow resolveExternal to be overridden

contingency-plan
Rich Harris 10 years ago
parent
commit
8bad2598b7
  1. 5
      src/Bundle.js
  2. 12
      src/rollup.js
  3. 39
      src/utils/resolvePath.js
  4. 15
      test/function/custom-external-resolver-async/_config.js
  5. 1
      test/function/custom-external-resolver-async/js_modules/external.js
  6. 3
      test/function/custom-external-resolver-async/main.js
  7. 14
      test/function/custom-external-resolver-sync/_config.js
  8. 1
      test/function/custom-external-resolver-sync/js_modules/external.js
  9. 3
      test/function/custom-external-resolver-sync/main.js

5
src/Bundle.js

@ -7,7 +7,7 @@ import ExternalModule from './ExternalModule';
import finalisers from './finalisers/index'; import finalisers from './finalisers/index';
import makeLegalIdentifier from './utils/makeLegalIdentifier'; import makeLegalIdentifier from './utils/makeLegalIdentifier';
import ensureArray from './utils/ensureArray'; import ensureArray from './utils/ensureArray';
import { defaultResolver } from './utils/resolvePath'; import { defaultResolver, defaultExternalResolver } from './utils/resolvePath';
import { defaultLoader } from './utils/load'; import { defaultLoader } from './utils/load';
function badExports ( option, keys ) { function badExports ( option, keys ) {
@ -23,7 +23,8 @@ export default class Bundle {
this.load = options.load || defaultLoader; this.load = options.load || defaultLoader;
this.resolvePathOptions = { this.resolvePathOptions = {
external: ensureArray( options.external ) external: ensureArray( options.external ),
resolveExternal: options.resolveExternal || defaultExternalResolver
}; };
this.loadOptions = { this.loadOptions = {

12
src/rollup.js

@ -20,16 +20,8 @@ export function rollup ( options ) {
throw new Error( 'You must supply options.dest to bundle.write' ); throw new Error( 'You must supply options.dest to bundle.write' );
} }
let { code, map } = bundle.generate({ const dest = options.dest;
dest, let { code, map } = bundle.generate( options );
format: options.format,
globalName: options.globalName,
// sourcemap options
sourceMap: !!options.sourceMap,
sourceMapFile: options.sourceMapFile,
// sourceMapRoot: options.sourceMapRoot
});
let promises = [ writeFile( dest, code ) ]; let promises = [ writeFile( dest, code ) ];

39
src/utils/resolvePath.js

@ -1,4 +1,5 @@
import { dirname, isAbsolute, resolve } from 'path'; import { dirname, isAbsolute, resolve } from 'path';
import { readFileSync } from 'sander';
export function defaultResolver ( importee, importer, options ) { export function defaultResolver ( importee, importer, options ) {
// absolute paths are left untouched // absolute paths are left untouched
@ -9,14 +10,46 @@ export function defaultResolver ( importee, importer, options ) {
// unless we want to keep it external, that is // unless we want to keep it external, that is
if ( ~options.external.indexOf( importee ) ) return null; if ( ~options.external.indexOf( importee ) ) return null;
return resolveExternal( importee, importer, options ); return options.resolveExternal( importee, importer, options );
} }
return resolve( dirname( importer ), importee ).replace( /\.js$/, '' ) + '.js'; return resolve( dirname( importer ), importee ).replace( /\.js$/, '' ) + '.js';
} }
function resolveExternal ( id, importer, options ) { export function defaultExternalResolver ( id, importer, options ) {
// for now, only node_modules is supported, and only jsnext:main // for now, only node_modules is supported, and only jsnext:main
let dir = dirname( importer );
throw new Error( "TODO" ); while ( dir !== '/' ) {
const pkgPath = resolve( dir, 'node_modules', id, 'package.json' );
let pkgJson;
try {
pkgJson = readFileSync( pkgPath ).toString();
} catch ( err ) {
// noop
}
if ( pkgJson ) {
let pkg;
try {
pkg = JSON.parse( pkgJson );
} catch ( err ) {
throw new Error( `Malformed JSON: ${pkgPath}` );
}
const main = pkg[ 'jsnext:main' ];
if ( !main ) {
throw new Error( `Package ${id} does not have a jsnext:main field, and so cannot be included in your rollup. Try adding it as an external module instead (e.g. options.external = ['${id}']). See https://github.com/rollup/rollup/wiki/jsnext:main for more info` );
}
return resolve( dirname( pkgPath ), main ).replace( /\.js$/, '' ) + '.js';
}
dir = dirname( dir );
}
throw new Error( `Could not find package ${id} (required by ${importer})` );
} }

15
test/function/custom-external-resolver-async/_config.js

@ -0,0 +1,15 @@
var path = require( 'path' );
var assert = require( 'assert' );
var Promise = require( 'sander' ).Promise;
module.exports = {
description: 'uses a custom external path resolver (asynchronous)',
options: {
resolveExternal: function ( id, importer, options ) {
return Promise.resolve( path.resolve( __dirname, 'js_modules', id + '.js' ) );
}
},
exports: function ( exports ) {
assert.ok( exports.success );
}
};

1
test/function/custom-external-resolver-async/js_modules/external.js

@ -0,0 +1 @@
export default { isExternal: true };

3
test/function/custom-external-resolver-async/main.js

@ -0,0 +1,3 @@
import external from 'external';
export default { success: external.isExternal };

14
test/function/custom-external-resolver-sync/_config.js

@ -0,0 +1,14 @@
var path = require( 'path' );
var assert = require( 'assert' );
module.exports = {
description: 'uses a custom external path resolver (synchronous)',
options: {
resolveExternal: function ( id, importer, options ) {
return path.resolve( __dirname, 'js_modules', id + '.js' );
}
},
exports: function ( exports ) {
assert.ok( exports.success );
}
};

1
test/function/custom-external-resolver-sync/js_modules/external.js

@ -0,0 +1 @@
export default { isExternal: true };

3
test/function/custom-external-resolver-sync/main.js

@ -0,0 +1,3 @@
import external from 'external';
export default { success: external.isExternal };
Loading…
Cancel
Save