@@ -78,6 +78,8 @@ var header = fs.readFileSync(__dirname + "/lib/header.js").toString("utf8")
7878
7979Note: These `require` statements should probably be wrapped in a
8080try, catch block to prevent uncaught exceptions.
81+ - `includeNodeModules` - Set to `true` if node_modules should be
82+ included in the `outputFile`
8183- `cb` - Callback of the form `cb(err, files)` where `files` is an Array
8284of files that have been included in the project.
8385*/
@@ -94,8 +96,22 @@ module.exports = function concat(entryModule, outputFile, opts, cb) {
9496opts . excludeFiles [ i ] = path . resolve ( opts . excludeFiles [ i ] ) ;
9597}
9698}
99+ // Ensure that `includeNodeModules` will work properly
100+ var _nodeModulePaths ;
101+ if ( opts . includeNodeModules ) {
102+ try {
103+ _nodeModulePaths = require ( "module" ) . _nodeModulePaths ;
104+ if ( typeof _nodeModulePaths !== "function" ) {
105+ opts . includeNodeModules = false ;
106+ }
107+ } catch ( err ) {
108+ opts . includeNodeModules = false ;
109+ }
110+ }
97111// A list of all of the files read and included in the output thus far
98112var files = [ ] ;
113+ // A list of all of the native modules not included in the output thus far
114+ var nativeModules = [ ] ;
99115// The file descriptor pointing to the `outputFile`
100116var fd ;
101117
@@ -119,10 +135,10 @@ module.exports = function concat(entryModule, outputFile, opts, cb) {
119135} ) . once ( "done" , function ( err ) {
120136if ( fd ) {
121137fs . close ( fd , function ( closeErr ) {
122- cb ( err || closeErr , files ) ;
138+ cb ( err || closeErr , files , nativeModules ) ;
123139} ) ;
124140} else {
125- cb ( err , files ) ;
141+ cb ( err , files , nativeModules ) ;
126142}
127143} ) ;
128144
@@ -147,48 +163,83 @@ module.exports = function concat(entryModule, outputFile, opts, cb) {
147163// Read file
148164fs . readFile ( filePath , { "encoding" : "utf8" } , this ) ;
149165} , function processFile ( code ) {
166+ // Remove some line comments from code
167+ code = code . replace ( / (?: \r \n ? | \n ) \s * \/ \/ .* / g, "" ) ;
150168// Scan file for `require(...)`, `__dirname`, and `__filename`
151169/* Quick notes about the somewhat intense `requireRegex`:
152170- require('...') and require("...") is matched
153171- The single or double quote matched is group 1
154172- Whitespace can go anywhere
155173- The module path matched is group 2
156- - Backslashes in the module path are escaped (i.e. for Windows paths)
174+ - Backslashes are allowed as escape characters only if followed
175+ by another backlash (to support Windows paths)
157176*/
158- var requireRegex = / r e q u i r e \s * \( \s * ( [ " ' ] ) ( (?: (? = ( \\ ? ) ) \3. ) * ) \1\s * \) / g,
177+ var requireRegex = / r e q u i r e \s * \( \s * ( [ " ' ] ) ( (?: (?: (? ! \1 ) [ ^ \\ ] | (?: \\ \\ ) ) ) * ) \1\s * \) / g,
159178dirnameRegex = / _ _ d i r n a m e / g,
160179filenameRegex = / _ _ f i l e n a m e / g;
161180code = code . replace ( requireRegex , function ( match , quote , modulePath ) {
181+ // First thing is to replace "\\" with "\"
182+ modulePath = modulePath . replace ( "\\\\" , "\\" ) ;
162183// Check to see if this require path begins with "./" or "../" or "/"
163184if ( modulePath . match ( / ^ \. ? \. ? \/ / ) !== null ) {
164185try {
165186modulePath = require . resolve ( path . resolve (
166187path . join ( path . dirname ( filePath ) , modulePath )
167188) ) ;
168- // Lookup this module's ID
169- var index = files . indexOf ( modulePath ) ;
170- if ( index < 0 ) {
171- // Not found; add this module to the project
172- if ( ! opts . excludeFiles ||
173- opts . excludeFiles . indexOf ( modulePath ) < 0 )
174- {
175- index = files . push ( modulePath ) - 1 ;
176- }
177- else {
178- // Ignore; do not replace
179- return match ;
180- }
181- }
182- // Replace the `require` statement with `__require`
183- return "__require(" + index + ")" ;
189+ // Include module in project at end of this function
184190} catch ( e ) {
185191// Ignore; do not replace
186192return match ;
187193}
194+ } else if ( opts . includeNodeModules ) {
195+ var oldPaths = module . paths ;
196+ /* Temporarily overwrite `module.paths` to make
197+ `require.resolve` work properly */
198+ module . paths = _nodeModulePaths ( path . dirname ( filePath ) ) ;
199+ try {
200+ var modulePath = require . resolve ( modulePath ) ;
201+ } catch ( err ) {
202+ // Module not found; do not replace
203+ return match ;
204+ } finally {
205+ // Restore old `module.paths`
206+ module . paths = oldPaths ;
207+ }
208+ // Detect core module
209+ if ( modulePath . match ( / ^ [ a - z _ ] + $ / ) ) {
210+ // Core module; do not replace
211+ return match ;
212+ }
213+ // Include module in project at end of this function
188214} else {
189215// Ignore; do not replace
190216return match ;
191217}
218+ /* If we reached this point, we need to include `modulePath`
219+ in our project */
220+ // If this is a native module, abort
221+ if ( path . extname ( modulePath ) . toLowerCase ( ) === ".node" ) {
222+ // This is a native module; do not replace
223+ nativeModules . push ( modulePath ) ;
224+ return match ;
225+ }
226+ // Lookup this module's ID
227+ var index = files . indexOf ( modulePath ) ;
228+ if ( index < 0 ) {
229+ // Not found; add this module to the project
230+ if ( ! opts . excludeFiles ||
231+ opts . excludeFiles . indexOf ( modulePath ) < 0 )
232+ {
233+ index = files . push ( modulePath ) - 1 ;
234+ }
235+ else {
236+ // Ignore; do not replace
237+ return match ;
238+ }
239+ }
240+ // Replace the `require` statement with `__require`
241+ var parentIndex = files . indexOf ( filePath ) ;
242+ return "__require(" + index + "," + parentIndex + ")" ;
192243} )
193244// Replace `__dirname` with `__getDirname(...)`
194245. replace ( dirnameRegex , "__getDirname(" +
0 commit comments