linkjs.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import os
  2. import re
  3. import sys
  4. def extract_require(s):
  5. m = re.search('(//)?(.*)require\\("(.*)"\\)', s)
  6. if not m or m.group(1):
  7. return None
  8. prefix = m.group(2)
  9. if prefix and len(prefix):
  10. prefix = prefix[-1]
  11. if prefix.isalpha() or prefix.isdigit() or prefix == '_':
  12. return None
  13. return m.group(3)
  14. def resolve_require(req, out, resolved, resolving):
  15. if not os.path.exists(req):
  16. raise Exception('cannot resolve "%s"' % req)
  17. process(req, out, resolved, resolving)
  18. def process(path, out, resolved, resolving):
  19. module_name = os.path.splitext(os.path.basename(path))[0]
  20. if module_name in resolving:
  21. raise Exception('cyclic import detected: "%s"' % module_name)
  22. result = 'imports["%s"] = {};\n' % path
  23. result += '(function %s(exports){\n' % module_name
  24. with open(path) as f:
  25. for l in f:
  26. req = extract_require(l)
  27. if req and not req in resolved:
  28. try:
  29. resolve_require(req, out, resolved, resolving + [module_name])
  30. except Exception, e:
  31. print 'while resolving "%s"...' % module_name
  32. raise e
  33. result += l
  34. result += '\n})(imports["%s"]);\n' % path
  35. out.write(result)
  36. resolved += [path]
  37. if __name__ == '__main__':
  38. if len(sys.argv) != 3:
  39. raise Exception("Usage: linkjs.py <input js> <output js>")
  40. input_path = sys.argv[1]
  41. output_path = sys.argv[2]
  42. with open(output_path, "w") as out:
  43. prolog = "var imports = {};\n"
  44. prolog += 'function require(module){return imports[module];}\n'
  45. out.write(prolog)
  46. process(input_path, out, [], [])