diff --git a/browser/sander.js b/browser/sander.js index 6436076..5dbe4fc 100644 --- a/browser/sander.js +++ b/browser/sander.js @@ -1,3 +1,7 @@ +export function readdirSync () { + throw new Error( 'Cannot use sander.readdirSync inside browser' ); +} + export function readFile () { throw new Error( 'Cannot use sander.readFile inside browser' ); } diff --git a/gobblefile.js b/gobblefile.js index 6036237..55e675c 100644 --- a/gobblefile.js +++ b/gobblefile.js @@ -8,7 +8,7 @@ var node = src entry: 'rollup.js', dest: 'rollup.js', format: 'cjs', - external: [ 'sander', 'acorn' ] + external: [ 'sander' ] }) .transform( 'babel' ); @@ -24,8 +24,7 @@ var browser = src load: function ( id ) { if ( ~id.indexOf( 'sander.js' ) ) return browserPlaceholders.sander; return fs.readFileSync( id ).toString(); - }, - external: [ 'acorn' ] + } }) .transform( 'browserify', { entries: [ './rollup.browser' ], diff --git a/src/Module.js b/src/Module.js index 9964ae2..d47601e 100644 --- a/src/Module.js +++ b/src/Module.js @@ -1,5 +1,5 @@ import { Promise } from 'sander'; -import { parse } from 'acorn'; +import { parse } from 'acorn/src/index'; import MagicString from 'magic-string'; import Statement from './Statement'; import walk from './ast/walk'; diff --git a/src/utils/resolveId.js b/src/utils/resolveId.js index 6b82f0d..1af9378 100644 --- a/src/utils/resolveId.js +++ b/src/utils/resolveId.js @@ -1,5 +1,23 @@ import { absolutePath, dirname, isAbsolute, resolve } from './path'; -import { readFileSync } from 'sander'; +import { readdirSync, readFileSync } from 'sander'; + +function dirExists ( dir ) { + try { + readdirSync( dir ); + return true; + } catch ( err ) { + return false; + } +} + +function fileExists ( dir ) { + try { + readFileSync( dir ); + return true; + } catch ( err ) { + return false; + } +} export function defaultResolver ( importee, importer, options ) { // absolute paths are left untouched @@ -10,8 +28,10 @@ export function defaultResolver ( importee, importer, options ) { // we try to resolve external modules if ( importee[0] !== '.' ) { + const [ id ] = importee.split( /[\/\\]/ ); + // unless we want to keep it external, that is - if ( ~options.external.indexOf( importee ) ) return null; + if ( ~options.external.indexOf( id ) ) return null; return options.resolveExternal( importee, importer, options ); } @@ -24,29 +44,33 @@ export function defaultExternalResolver ( id, importer ) { const root = absolutePath.exec( importer )[0]; let dir = dirname( importer ); + // `foo` should use jsnext:main, but `foo/src/bar` shouldn't + const parts = id.split( /[\/\\]/ ); + while ( dir !== root ) { - const pkgPath = resolve( dir, 'node_modules', id, 'package.json' ); - let pkgJson; + const modulePath = resolve( dir, 'node_modules', parts[0] ); - try { - pkgJson = readFileSync( pkgPath ).toString(); - } catch ( err ) { - // noop - } + if ( dirExists( modulePath ) ) { + // `foo/src/bar` + if ( parts.length > 1 ) { + return resolve( modulePath, ...parts.slice( 1 ) ).replace( /\.js$/, '' ) + '.js'; + } - if ( pkgJson ) { + // `foo` + const pkgPath = resolve( modulePath, 'package.json' ); + let pkgJson; let pkg; try { - pkg = JSON.parse( pkgJson ); + pkg = JSON.parse( readFileSync( pkgPath ).toString() ); } catch ( err ) { - throw new Error( `Malformed JSON: ${pkgPath}` ); + throw new Error( `Missing or malformed package.json: ${modulePath}` ); } 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` ); + throw new Error( `Package ${id} (imported by ${importer}) 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';