diff --git a/lib/cjs.js b/lib/cjs.js index 57f0d540..5e8916f6 100644 --- a/lib/cjs.js +++ b/lib/cjs.js @@ -7,30 +7,42 @@ var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.]|module\.)exports\s*(\[['"]|\.)|(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])module\.exports\s*[=,]/; // RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339 var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; - var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; + var commentRegEx = /(^|[^\\])(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; + + var stringRegEx = /(?:"[^"\\\n\r]*(?:\\.[^"\\\n\r]*)*"|'[^'\\\n\r]*(?:\\.[^'\\\n\r]*)*')/g; function getCJSDeps(source) { - cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = 0; + cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = stringRegEx.lastIndex = 0; var deps = []; - // track comments in the source var match; - - var commentLocations = []; + + // track string and comment locations for unminified source + var stringLocations = [], commentLocations = []; + + function inLocation(locations, match, starts) { + var inLocation = false; + for (var i = 0; i < locations.length; i++) + if (locations[i][0] < match.index && locations[i][1] > match.index + (!starts ? match[0].length : 0)) + return true; + return false; + } + if (source.length / source.split('\n').length < 200) { - while (match = commentRegEx.exec(source)) - commentLocations.push([match.index, match.index + match[0].length]); + while (match = stringRegEx.exec(source)) + stringLocations.push([match.index, match.index + match[0].length]); + + while (match = commentRegEx.exec(source)) { + // only track comments not starting in strings + if (!inLocation(stringLocations, match, true)) + commentLocations.push([match.index, match.index + match[0].length]); + } } while (match = cjsRequireRegEx.exec(source)) { - // ensure we're not in a comment location - var inComment = false; - for (var i = 0; i < commentLocations.length; i++) { - if (commentLocations[i][0] < match.index && commentLocations[i][1] > match.index + match[0].length) - inComment = true; - } - if (!inComment) + // ensure we're not within a string or comment location + if (!inLocation(stringLocations, match) && !inLocation(commentLocations, match)) deps.push(match[1].substr(1, match[1].length - 2)); } diff --git a/test/test.js b/test/test.js index 54b97e0a..f9f6dec5 100644 --- a/test/test.js +++ b/test/test.js @@ -365,8 +365,9 @@ asyncTest('CommonJS require variations', function() { ok(m.d1 == 'd'); ok(m.d2 == 'd'); ok(m.d3 == "require('not a dep')"); - // ok(m.d4 == "text require('still not a dep') text"); - // ok(m.d5 == 'text \'quote\' require("yet still not a dep")'); + ok(m.d4 == "text/* require('still not a dep') text"); + ok(m.d5 == 'text \'quote\' require("yet still not a dep")'); + ok(m.d6 == 'd6'); start(); }, err); }); diff --git a/test/tests/commonjs-d2.js b/test/tests/commonjs-d2.js new file mode 100644 index 00000000..3b340b2e --- /dev/null +++ b/test/tests/commonjs-d2.js @@ -0,0 +1 @@ +module.exports = 'd6'; \ No newline at end of file diff --git a/test/tests/commonjs-requires.js b/test/tests/commonjs-requires.js index a13e00d3..1e6f622f 100644 --- a/test/tests/commonjs-requires.js +++ b/test/tests/commonjs-requires.js @@ -5,8 +5,16 @@ exports.d1 = require( exports.d2 = (require ("./commonjs-d.js")); +var regex = / \/* /; + exports.d3 = "require('not a dep')"; -// exports.d4 = "text require('still not a dep') text"; +exports.d4 = "text/* require('still not a dep') text"; -// exports.d5 = 'text \'quote\' require("yet still not a dep")'; +exports.d5 = 'text \'quote\' require("yet still not a dep")'; + +var regexWithString = /asdfasdf " /; + +exports.d6 = require('./commonjs-d2.js'); + +var regexClose = /asdf " */; \ No newline at end of file