bug描述 require('tmpl', '<%var a=12/3;%><div><%=a%></div>'); require('page', function(require, exports, module){ console.log('page'); }) 如上代码,如果使用seajs 2.2.1版本,将会出现模块解析的错误。原因是require(‘tmpl’),模板字符串中有算数表达式12/3。而seajs在计算模块依赖时,使用的正则表达式未处理到这种情况。 seajs 2.2.1版本 var REQUIRE_RE = /"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\/\*[\S\s]*?\*\/|\/(?:\\\/|[^\/\r\n])+\/(?=[^\/])|\/\/.*|\.\s*require|(?:^|[^$])\brequire\s*\(\s*(["'])(.+?)\1\s*\)/g var SLASH_RE = /\\\\/g function parseDependencies(code) { var ret = [] code.replace(SLASH_RE, "") .replace(REQUIRE_RE, function(m, m1, m2) { if (m2) { ret.push(m2) } }) return ret } 新版本seajs改进之后,bug得以解决 function parseDependencies(s) { if(s.indexOf('require') == -1) { return [] } var index = 0, peek, length = s.length, isReg = 1, modName = 0, parentheseState = 0, parentheseStack = [], res = [] while(index < length) { readch() if(isBlank()) { } else if(isQuote()) { dealQuote() isReg = 1 } else if(peek == '/') { readch() if(peek == '/') { index = s.indexOf('\n', index) if(index == -1) { index = s.length } } else if(peek == '*') { index = s.indexOf('*/', index) if(index == -1) { index = length } else { index += 2 } } else if(isReg) { dealReg() isReg = 0 } else { index-- isReg = 1 } } else if(isWord()) { dealWord() } else if(isNumber()) { dealNumber() } else if(peek == '(') { parentheseStack.push(parentheseState) isReg = 1 } else if(peek == ')') { isReg = parentheseStack.pop() } else { isReg = peek != ']' modName = 0 } } return res function readch() { peek = s.charAt(index++) } function isBlank() { return /\s/.test(peek) } function isQuote() { return peek == '"' || peek == "'" } function dealQuote() { var start = index var c = peek var end = s.indexOf(c, start) if(end == -1) { index = length } else if(s.charAt(end - 1) != '\\') { index = end + 1 } else { while(index < length) { readch() if(peek == '\\') { index++ } else if(peek == c) { break } } } if(modName) { res.push(s.slice(start, index - 1)) modName = 0 } } function dealReg() { index-- while(index < length) { readch() if(peek == '\\') { index++ } else if(peek == '/') { break } else if(peek == '[') { while(index < length) { readch() if(peek == '\\') { index++ } else if(peek == ']') { break } } } } } function isWord() { return /[a-z_$]/i.test(peek) } function dealWord() { var s2 = s.slice(index - 1) var r = /^[\w$]+/.exec(s2)[0] parentheseState = { 'if': 1, 'for': 1, 'while': 1, 'with': 1 }[r] isReg = { 'break': 1, 'case': 1, 'continue': 1, 'debugger': 1, 'delete': 1, 'do': 1, 'else': 1, 'false': 1, 'if': 1, 'in': 1, 'instanceof': 1, 'return': 1, 'typeof': 1, 'void': 1 }[r] modName = /^require\s*\(\s*(['"]).+?\1\s*\)/.test(s2) if(modName) { r = /^require\s*\(\s*['"]/.exec(s2)[0] index += r.length - 2 } else { index += /^[\w$]+(?:\s*\.\s*[\w$]+)*/.exec(s2)[0].length - 1 } } function isNumber() { return /\d/.test(peek) || peek == '.' && /\d/.test(s.charAt(index)) } function dealNumber() { var s2 = s.slice(index - 1) var r if(peek == '.') { r = /^\.\d+(?:E[+-]?\d*)?\s*/i.exec(s2)[0] } else if(/^0x[\da-f]*/i.test(s2)) { r = /^0x[\da-f]*\s*/i.exec(s2)[0] } else { r = /^\d+\.?\d*(?:E[+-]?\d*)?\s*/i.exec(s2)[0] } index += r.length - 1 isReg = 0 } } aslinwang / 2016-09-05 in categories 前端 tagged with seajs Please enable JavaScript to view the comments powered by DuoShuo.