@ -11,10 +11,6 @@ const path = require('path');
const internalModuleReadFile = process . binding ( 'fs' ) . internalModuleReadFile ;
const internalModuleStat = process . binding ( 'fs' ) . internalModuleStat ;
const splitRe = process . platform === 'win32' ? /[\/\\]/ : /\// ;
const isIndexRe = /^index\.\w+?$/ ;
const shebangRe = /^\#\!.*/ ;
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
@ -84,8 +80,8 @@ function readPackage(requestPath) {
return packageMainCache [ requestPath ] ;
}
var jsonPath = path . resolve ( requestPath , 'package.json' ) ;
var json = internalModuleReadFile ( path . _ makeLong ( jsonPath ) ) ;
const jsonPath = path . resolve ( requestPath , 'package.json' ) ;
const json = internalModuleReadFile ( path . _ makeLong ( jsonPath ) ) ;
if ( json === undefined ) {
return false ;
@ -107,7 +103,8 @@ function tryPackage(requestPath, exts) {
if ( ! pkg ) return false ;
var filename = path . resolve ( requestPath , pkg ) ;
return tryFile ( filename ) || tryExtensions ( filename , exts ) ||
return tryFile ( filename ) ||
tryExtensions ( filename , exts ) ||
tryExtensions ( path . resolve ( filename , 'index' ) , exts ) ;
}
@ -128,8 +125,8 @@ function toRealPath(requestPath) {
// given a path check a the file exists with any of the set extensions
function tryExtensions ( p , exts ) {
for ( var i = 0 , EL = exts . length ; i < EL ; i ++ ) {
var filename = tryFile ( p + exts [ i ] ) ;
for ( var i = 0 ; i < exts . length ; i ++ ) {
const filename = tryFile ( p + exts [ i ] ) ;
if ( filename ) {
return filename ;
@ -142,21 +139,25 @@ var warned = false;
Module . _ findPath = function ( request , paths ) {
if ( path . isAbsolute ( request ) ) {
paths = [ '' ] ;
} else if ( ! paths || paths . length === 0 ) {
return false ;
}
var cacheKey = JSON . stringify ( { request : request , paths : paths } ) ;
const cacheKey = JSON . stringify ( { request : request , paths : paths } ) ;
if ( Module . _ pathCache [ cacheKey ] ) {
return Module . _ pathCache [ cacheKey ] ;
}
const exts = Object . keys ( Module . _ extensions ) ;
const trailingSlash = request . slice ( - 1 ) === '/' ;
var exts ;
const trailingSlash = request . length > 0 &&
request . charCodeAt ( request . length - 1 ) === 47 /*/*/ ;
// For each path
for ( var i = 0 , PL = paths . length ; i < PL ; i ++ ) {
for ( var i = 0 ; i < paths . length ; i ++ ) {
// Don't search further if path doesn't exist
if ( paths [ i ] && stat ( paths [ i ] ) < 1 ) continue ;
var basePath = path . resolve ( paths [ i ] , request ) ;
const curPath = paths [ i ] ;
if ( curPath && stat ( curPath ) < 1 ) continue ;
var basePath = path . resolve ( curPath , request ) ;
var filename ;
if ( ! trailingSlash ) {
@ -164,11 +165,15 @@ Module._findPath = function(request, paths) {
if ( rc === 0 ) { // File.
filename = toRealPath ( basePath ) ;
} else if ( rc === 1 ) { // Directory.
if ( exts === undefined )
exts = Object . keys ( Module . _ extensions ) ;
filename = tryPackage ( basePath , exts ) ;
}
if ( ! filename ) {
// try it with each of the extensions
if ( exts === undefined )
exts = Object . keys ( Module . _ extensions ) ;
filename = tryExtensions ( basePath , exts ) ;
}
}
@ -179,6 +184,8 @@ Module._findPath = function(request, paths) {
if ( ! filename ) {
// try it with each of the extensions at "index"
if ( exts === undefined )
exts = Object . keys ( Module . _ extensions ) ;
filename = tryExtensions ( path . resolve ( basePath , 'index' ) , exts ) ;
}
@ -198,38 +205,95 @@ Module._findPath = function(request, paths) {
return false ;
} ;
// 'from' is the __dirname of the module.
Module . _ nodeModulePaths = function ( from ) {
// 'node_modules' character codes reversed
var nmChars = [ 115 , 101 , 108 , 117 , 100 , 111 , 109 , 95 , 101 , 100 , 111 , 110 ] ;
var nmLen = nmChars . length ;
if ( process . platform === 'win32' ) {
// 'from' is the __dirname of the module.
Module . _ nodeModulePaths = function ( from ) {
// guarantee that 'from' is absolute.
from = path . resolve ( from ) ;
// note: this approach *only* works when the path is guaranteed
// to be absolute. Doing a fully-edge-case-correct path.split
// that works on both Windows and Posix is non-trivial.
var paths = [ ] ;
var parts = from . split ( splitRe ) ;
const paths = [ ] ;
var p = 0 ;
var last = from . length ;
for ( var i = from . length - 1 ; i >= 0 ; -- i ) {
const code = from . charCodeAt ( i ) ;
if ( code === 92 /*\*/ || code === 47 /*/*/ ) {
if ( p !== nmLen )
paths . push ( from . slice ( 0 , last ) + '\\node_modules' ) ;
last = i ;
p = 0 ;
} else if ( p !== - 1 && p < nmLen ) {
if ( nmChars [ p ] === code ) {
++ p ;
} else {
p = - 1 ;
}
}
}
return paths ;
} ;
} else { // posix
// 'from' is the __dirname of the module.
Module . _ nodeModulePaths = function ( from ) {
// guarantee that 'from' is absolute.
from = path . resolve ( from ) ;
// Return early not only to avoid unnecessary work, but to *avoid* returning
// an array of two items for a root: [ '//node_modules', '/node_modules' ]
if ( from === '/' )
return [ '/node_modules' ] ;
for ( var tip = parts . length - 1 ; tip >= 0 ; tip -- ) {
// don't search in .../node_modules/node_modules
if ( parts [ tip ] === 'node_modules' ) continue ;
var dir = parts . slice ( 0 , tip + 1 ) . concat ( 'node_modules' ) . join ( path . sep ) ;
paths . push ( dir ) ;
// note: this approach *only* works when the path is guaranteed
// to be absolute. Doing a fully-edge-case-correct path.split
// that works on both Windows and Posix is non-trivial.
const paths = [ ] ;
var p = 0 ;
var last = from . length ;
for ( var i = from . length - 1 ; i >= 0 ; -- i ) {
const code = from . charCodeAt ( i ) ;
if ( code === 47 /*/*/ ) {
if ( p !== nmLen )
paths . push ( from . slice ( 0 , last ) + '/node_modules' ) ;
last = i ;
p = 0 ;
} else if ( p !== - 1 && p < nmLen ) {
if ( nmChars [ p ] === code ) {
++ p ;
} else {
p = - 1 ;
}
}
}
return paths ;
} ;
} ;
}
// 'index.' character codes
var indexChars = [ 105 , 110 , 100 , 101 , 120 , 46 ] ;
var indexLen = indexChars . length ;
Module . _ resolveLookupPaths = function ( request , parent ) {
if ( NativeModule . nonInternalExists ( request ) ) {
return [ request , [ ] ] ;
}
var start = request . substring ( 0 , 2 ) ;
if ( start !== './' && start !== '..' ) {
var reqLen = request . length ;
// Check for relative path
if ( reqLen < 2 ||
request . charCodeAt ( 0 ) !== 46 /*.*/ ||
( request . charCodeAt ( 1 ) !== 46 /*.*/ &&
request . charCodeAt ( 1 ) !== 47 /*/*/ ) ) {
var paths = modulePaths ;
if ( parent ) {
if ( ! parent . paths ) parent . paths = [ ] ;
if ( ! parent . paths )
paths = parent . paths = [ ] ;
else
paths = parent . paths . concat ( paths ) ;
}
@ -237,9 +301,9 @@ Module._resolveLookupPaths = function(request, parent) {
// by putting the module's directory in front of the lookup paths.
if ( request === '.' ) {
if ( parent && parent . filename ) {
paths . splice ( 0 , 0 , path . dirname ( parent . filename ) ) ;
paths . unshift ( path . dirname ( parent . filename ) ) ;
} else {
paths . splice ( 0 , 0 , path . resolve ( request ) ) ;
paths . unshift ( path . resolve ( request ) ) ;
}
}
@ -257,8 +321,39 @@ Module._resolveLookupPaths = function(request, parent) {
// Is the parent an index module?
// We can assume the parent has a valid extension,
// as it already has been accepted as a module.
var isIndex = isIndexRe . test ( path . basename ( parent . filename ) ) ;
var parentIdPath = isIndex ? parent . id : path . dirname ( parent . id ) ;
const base = path . basename ( parent . filename ) ;
var parentIdPath ;
if ( base . length > indexLen ) {
var i = 0 ;
for ( ; i < indexLen ; ++ i ) {
if ( indexChars [ i ] !== base . charCodeAt ( i ) )
break ;
}
if ( i === indexLen ) {
// We matched 'index.', let's validate the rest
for ( ; i < base . length ; ++ i ) {
const code = base . charCodeAt ( i ) ;
if ( code !== 95 /*_*/ &&
( code < 48 /*0*/ || code > 57 /*9*/ ) &&
( code < 65 /*A*/ || code > 90 /*Z*/ ) &&
( code < 97 /*a*/ || code > 122 /*z*/ ) )
break ;
}
if ( i === base . length ) {
// Is an index module
parentIdPath = parent . id ;
} else {
// Not an index module
parentIdPath = path . dirname ( parent . id ) ;
}
} else {
// Not an index module
parentIdPath = path . dirname ( parent . id ) ;
}
} else {
// Not an index module
parentIdPath = path . dirname ( parent . id ) ;
}
var id = path . resolve ( parentIdPath , request ) ;
// make sure require('./path') and require('path') get distinct ids, even
@ -307,19 +402,22 @@ Module._load = function(request, parent, isMain) {
Module . _ cache [ filename ] = module ;
var hadException = true ;
tryModuleLoad ( module , filename ) ;
return module . exports ;
} ;
function tryModuleLoad ( module , filename ) {
var threw = true ;
try {
module . load ( filename ) ;
hadException = false ;
threw = false ;
} finally {
if ( hadException ) {
if ( threw ) {
delete Module . _ cache [ filename ] ;
}
}
return module . exports ;
} ;
}
Module . _ resolveFilename = function ( request , parent ) {
if ( NativeModule . nonInternalExists ( request ) ) {
@ -377,8 +475,33 @@ var resolvedArgv;
// the file.
// Returns exception, if any.
Module . prototype . _ compile = function ( content , filename ) {
// remove shebang
content = content . replace ( shebangRe , '' ) ;
// Remove shebang
var contLen = content . length ;
if ( contLen >= 2 ) {
if ( content . charCodeAt ( 0 ) === 35 /*#*/ &&
content . charCodeAt ( 1 ) === 33 /*!*/ ) {
if ( contLen === 2 ) {
// Exact match
content = '' ;
} else {
// Find end of shebang line and slice it off
var i = 2 ;
for ( ; i < contLen ; ++ i ) {
var code = content . charCodeAt ( i ) ;
if ( code === 10 /*\n*/ || code === 13 /*\r*/ )
break ;
}
if ( i === contLen )
content = '' ;
else {
// Note that this actually includes the newline character(s) in the
// new output. This duplicates the behavior of the regular expression
// that was previously used to replace the shebang line
content = content . slice ( i ) ;
}
}
}
}
// create wrapper function
var wrapper = Module . wrap ( content ) ;
@ -408,12 +531,12 @@ Module.prototype._compile = function(content, filename) {
global . v8debug . Debug . setBreakPoint ( compiledWrapper , 0 , 0 ) ;
}
}
const dirname = path . dirname ( filename ) ;
const require = internalModule . makeRequireFunction . call ( this ) ;
const args = [ this . exports , require , this , filename , dirname ] ;
const depth = internalModule . requireDepth ;
var dirname = path . dirname ( filename ) ;
var require = internalModule . makeRequireFunction . call ( this ) ;
var args = [ this . exports , require , this , filename , dirname ] ;
var depth = internalModule . requireDepth ;
if ( depth === 0 ) stat . cache = new Map ( ) ;
const result = compiledWrapper . apply ( this . exports , args ) ;
var result = compiledWrapper . apply ( this . exports , args ) ;
if ( depth === 0 ) stat . cache = null ;
return result ;
} ;