Skip to content

Instantly share code, notes, and snippets.

@creationix
Created August 12, 2013 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/6212379 to your computer and use it in GitHub Desktop.
Save creationix/6212379 to your computer and use it in GitHub Desktop.
Simple state-machine that scans javascript code for requires.
// Mine a string for require calls and export the module names
// Extract all require calls using a proper state-machine parser.
function mine(js) {
var names = [];
var state = 0;
var ident;
var quote;
var name;
var isIdent = /[a-z0-9_.]/i;
var isWhitespace = /[ \r\n\t]/;
function $start(char) {
if (char === "/") {
return $slash;
}
if (char === "'" || char === '"') {
quote = char;
return $string;
}
if (isIdent.test(char)) {
ident = char;
return $ident;
}
return $start;
}
function $ident(char) {
if (isIdent.test(char)) {
ident += char;
return $ident;
}
if (char === "(" && ident === "require") {
ident = undefined;
return $call;
}
return $start;
}
function $call(char) {
if (isWhitespace.test(char)) return $call;
if (char === "'" || char === '"') {
quote = char;
name = "";
return $name;
}
return $start;
}
function $name(char) {
if (char === quote) {
return $close;
}
name += char;
return $name;
}
function $close(char) {
if (isWhitespace.test(char)) return $close;
if (char === ")") {
names.push(name);
}
name = undefined;
return $start;
}
function $string(char) {
if (char === "\\") {
return $escape;
}
if (char === quote) {
return $start;
}
return $string;
}
function $escape(char) {
return $string;
}
function $slash(char) {
if (char === "/") return $lineComment;
if (char === "*") return $multilineComment;
return $start;
}
function $lineComment(char) {
if (char === "\r" || char === "\n") return $start;
return $lineComment;
}
function $multilineComment(char) {
if (char === "*") return $multilineEnding;
return $multilineComment;
}
function $multilineEnding(char) {
if (char === "/") return $start;
if (char === "*") return $multilingEnding;
return $multilineComment;
}
var state = $start;
for (var i = 0, l = js.length; i < l; i++) {
state = state(js[i]);
}
return names;
}
@mirkokiefer
Copy link

great! would be interesting to test how much faster something like browserify would be with a simple parser like this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment