6363- `entryModulePath` - the path to the entry point of the project to be
6464concatenated. This might be an `index.js` file, for example.
6565- `options` - object to specify any of the following options
66- - `outputPath` - the path where the concatenated project file will be
67- written. Provide this whenever possible to ensure that instances
68- of `__dirname` and `__filename` are replaced properly. If
69- `__dirname` and `__filename` are not used in your project or your
70- project dependencies, it is not necessary to provide this path.
71- - `excludeFiles` - An Array of files that should be excluded from the
72- project even if they were referenced by a `require(...)`.
73-
74- Note: These `require` statements should probably be wrapped with a
75- conditional or a try/catch block to prevent uncaught exceptions.
76- - `excludeNodeModules` - Set to `true` if modules loaded from
77- `node_modules` folders should be excluded from the project.
78- - `browser` - Set to `true` when concatenating this project for the
79- browser. In this case, whenever a required library is loaded from
80- `node_modules`, the `browser` field in the `package.json` file (if
81- found) is used to determine which file to actually include in the
82- project.
66+ - `outputPath`
67+ - `excludeFiles`
68+ - `excludeNodeModules`
69+ - `extensions`
70+ - `compilers`
71+ - `browser`
8372
8473See README.md for more details.
8574*/
@@ -95,6 +84,29 @@ class ModuleConcatStream extends Readable {
9584opts . excludeFiles [ i ] = path . resolve ( opts . excludeFiles [ i ] ) ;
9685}
9786}
87+ // Configure default file extensions
88+ if ( ! Array . isArray ( opts . extensions ) ) {
89+ opts . extensions = opts . extensions ? [ opts . extensions ] :
90+ [ ".js" , ".json" ] ;
91+ }
92+ // Add ".node" to the list to allow us to find native modules
93+ opts . extensions . push ( ".node" ) ;
94+ // Configure default compilers
95+ opts . compilers = opts . compilers || { } ;
96+ if ( typeof opts . compilers [ ".json" ] === "undefined" ) {
97+ opts . compilers [ ".json" ] =
98+ ( src , options ) => "module.exports = " + src ;
99+ }
100+ /* Use package.json `browser` field instead of `main` if `browser`
101+ option is set */
102+ if ( opts . browser ) {
103+ opts . packageFilter = ( parsedPkgJson , pkgPath ) => {
104+ if ( parsedPkgJson . browser ) {
105+ parsedPkgJson . main = parsedPkgJson . browser ;
106+ }
107+ return parsedPkgJson ;
108+ } ;
109+ }
98110// List of files already included in the project or pending inclusion
99111this . _files = [ entryModulePath ] ;
100112// Index pointing to the next file to included in the project
@@ -105,12 +117,9 @@ class ModuleConcatStream extends Readable {
105117this . _headerWritten = false ;
106118}
107119
108- // Called when we should start/continue processing
120+ /* Called when we should start/continue processing.
121+ We should stop processing whenever `this.push` returns `false`. */
109122_read ( size ) {
110- this . _continueProcessing ( ) ;
111- }
112-
113- _continueProcessing ( ) {
114123// Write the project header
115124if ( ! this . _headerWritten ) {
116125this . _headerWritten = true ;
@@ -119,23 +128,30 @@ class ModuleConcatStream extends Readable {
119128}
120129// Write the next file in the project
121130while ( this . _fileIndex < this . _files . length ) {
122- if ( ! this . _addFile ( this . _files [ this . _fileIndex ] ) )
131+ if ( ! this . push ( this . _addFile ( this . _files [ this . _fileIndex ] ) ) ) {
123132return ;
133+ }
124134}
125135// Write the project footer
126136this . push ( FOOTER ) ;
127137// Write EOF
128138this . push ( null ) ;
129139}
130140
131- /* Adds the file from the given `filePath` to the project. Returns `true`
132- if more data can be added to the stream; `false` otherwise. */
141+ /* Adds the file from the given `filePath` to the project. Returns the
142+ modified module contents (with header/footer added), which should be
143+ added to the stream. */
133144_addFile ( filePath ) {
134145try {
135146// Read the file synchronously from disk
136147let code = fs . readFileSync ( filePath , { "encoding" : "utf8" } ) ;
137148// Mark this file as included in the project
138149this . _fileIndex ++ ;
150+ // Compile this file if needed
151+ let compiler = this . _options . compilers [ path . extname ( filePath ) ] ;
152+ if ( compiler ) {
153+ code = compiler ( code , this . _options ) ;
154+ }
139155// Remove some line comments from code
140156code = code . replace ( / (?: \r \n ? | \n ) \s * \/ \/ .* / g, "" ) ;
141157/* Scan file for `require(...)`, `__dirname`, and `__filename`
@@ -170,24 +186,11 @@ class ModuleConcatStream extends Readable {
170186return match ;
171187}
172188// Get ready to resolve the module
173- var resolveOpts = {
174- "basedir" : path . dirname ( filePath ) ,
175- "extensions" : [ "" , ".js" , ".json" , ".node" ]
176- } ;
177- /* Use package.json `browser` field instead of `main` if
178- `browser` option is set */
179- if ( this . _options . browser ) {
180- resolveOpts . packageFilter = ( parsedPkgJson , pkgPath ) => {
181- if ( parsedPkgJson . browser ) {
182- parsedPkgJson . main = parsedPkgJson . browser ;
183- }
184- return parsedPkgJson ;
185- } ;
186- }
189+ this . _options . basedir = path . dirname ( filePath ) ;
187190// Thank you, node-resolve for making this easy!
188191try {
189192// Resolve the module path
190- modulePath = resolve . sync ( modulePath , resolveOpts ) ;
193+ modulePath = resolve . sync ( modulePath , this . _options ) ;
191194// Do not replace core modules
192195if ( resolve . isCore ( modulePath ) ) {
193196return match ;
@@ -201,10 +204,11 @@ class ModuleConcatStream extends Readable {
201204// Lookup this module's ID
202205var index = this . _files . indexOf ( modulePath ) ;
203206if ( index < 0 ) {
204- // Not found; add this module to the project
207+ // Not added to project yet; try to add it
205208if ( ! this . _options . excludeFiles ||
206209this . _options . excludeFiles . indexOf ( modulePath ) < 0 )
207210{
211+ // Not excluded, so we're good to go!
208212index = this . _files . push ( modulePath ) - 1 ;
209213}
210214else {
@@ -233,28 +237,21 @@ class ModuleConcatStream extends Readable {
233237path . relative ( path . dirname ( outputPath ) , filePath )
234238) + ")" ) ;
235239}
236- /* Prepend module header and append module footer and write the
237- included module to the stream */
238- return this . push (
239- // Add file header
240- FILE_HEADER
240+ /* Return the modified module contents, prepending the module header
241+ and appending the module footer. */
242+ return FILE_HEADER
241243. replace ( / \$ \{ i d \} / g, this . _files . indexOf ( filePath ) )
242244. replace ( / \$ \{ p a t h \} / g, filePath ) +
243- // Add extra header bit if this is a JSON file
244- ( path . extname ( filePath ) === ".json" ?
245- "module.exports = " : "" ) +
246- // Add modified project file
247245code +
248- // Add file footer
249246FILE_FOOTER
250247. replace ( / \$ \{ i d \} / g, this . _files . indexOf ( filePath ) )
251- . replace ( / \$ \{ p a t h \} / g, filePath )
252- ) ;
248+ . replace ( / \$ \{ p a t h \} / g, filePath ) ;
253249} catch ( err ) {
254250process . nextTick ( ( ) => {
255251this . emit ( "error" , err ) ;
256252} ) ;
257- return false ;
253+ // Return EOF
254+ return null ;
258255}
259256}
260257
0 commit comments