Browse Source

allow imports of individual files from external modules

gh-109
Rich-Harris 10 years ago
parent
commit
3c37dc43e7
  1. 4
      browser/sander.js
  2. 5
      gobblefile.js
  3. 2
      src/Module.js
  4. 50
      src/utils/resolveId.js

4
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' );
}

5
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' ],

2
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';

50
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';

Loading…
Cancel
Save