1010
1111var libfs = require ( 'fs' ) ,
1212 vm = require ( 'vm' ) ,
13- contextForRunInContext = vm . createContext ( {
14- require : null ,
15- module : null ,
16- console : { } ,
17- window : { } ,
18- document : { } ,
19- global : { }
20- } ) ;
13+ context = vm . createContext ( { } ) ;
2114
2215module . exports = {
2316 detect : detect ,
@@ -36,7 +29,11 @@ Analyze a javascript file, collecting the module or modules information when pos
3629function extract ( file ) {
3730 var mods = [ ] ;
3831
39- contextForRunInContext . YUI = {
32+ /**
33+ YUI detection is based on a simple rule:
34+ - if `YUI.add()` is called
35+ **/
36+ context . YUI = {
4037 add : function ( name , fn , version , config ) {
4138 mods . push ( {
4239 type : 'yui' ,
@@ -46,21 +43,61 @@ function extract(file) {
4643 } ) ;
4744 }
4845 } ;
49- contextForRunInContext . define = function ( name , fn , version , config ) {
46+
47+
48+ /**
49+ AMD detection is based on a simple rule:
50+ - if `define()` is called
51+ **/
52+ context . define = function ( name , fn , version , config ) {
5053 mods . push ( {
5154 type : 'amd' ,
5255 name : name ,
5356 version : version ,
5457 config : config
5558 } ) ;
5659 } ;
60+
61+
62+ /**
63+ CommonJS detection is based on simple rules:
64+ - if the script calls `require()`
65+ - or if the script tries to export a function thru `module.exports`
66+ - or if the script tries to export an object thru `module.exports`
67+ - or if the script tries to export a function thru `exports`
68+ - or if the script tries to export an object thru `exports`
69+ - or if the script tries to add a new member to `module.exports`
70+ **/
71+ context . require = function ( ) {
72+ mods . push ( {
73+ type : 'cjs'
74+ } ) ;
75+ throw new Error ( 'Common JS script detected' ) ;
76+ } ;
77+ context . module = {
78+ exports : { }
79+ } ;
80+ context . exports = context . module . exports ;
81+
82+
83+ // executing the content of the file into a new context to avoid leaking
84+ // globals during the detection process.
5785 try {
58- vm . runInContext ( libfs . readFileSync ( file , 'utf8' ) , contextForRunInContext , file ) ;
86+ vm . runInContext ( libfs . readFileSync ( file , 'utf8' ) , context , file ) ;
5987 } catch ( e ) {
88+ // console.log(e.stack || e);
6089 // very dummy detection process for ES modules
6190 if ( e . toString ( ) === 'SyntaxError: Unexpected reserved word' ) {
6291 mods . push ( { type : 'es' } ) ;
6392 }
93+ } finally {
94+ // very dummy detection process for CommonJS modules
95+ if ( typeof context . module . exports === 'function'
96+ || typeof context . exports === 'function'
97+ || Object . keys ( context . module . exports ) > 0
98+ || Object . keys ( context . exports ) > 0 ) {
99+ mods . push ( { type : 'cjs' } ) ;
100+ }
64101 }
65102 // returning an array when more than one module is defined in the file
66103 return mods . length > 1 ? mods : mods [ 0 ] ;
0 commit comments