使用dart创建JavaScript库

44

问题

我目前正在使用JavaScript库,为了减少错误数量,我认为我的库可能会受益于使用Dart的静态类型化机制。首先,因为我的库既没有与HTML也没有与其他JavaScript库进行任何互操作,所以仅是纯JavaScript对象操作之类的东西。但是我没有在网上找到任何信息显示如何使用dart构建JS库。所以我尝试自己做,创建了初始的dart文件:

library Repo;

class Type {
  final String name;
  final TypeCategory category;
  
  Type(String name, TypeCategory category) : name = name, category = category {
    category.types[name] = this;
  }
}

class TypeCategory {
  final String name;
  final Map<String, Type> types = new Map();
  
  TypeCategory(this.name);
}

class Branch {
  
}

class Descriptor {
  
}

class TableDescriptor extends Descriptor {
  TableDescriptor.ctor() {
    
  }
}

class Repo {
  Descriptor descriptor(String name) {
    
  }
  
  Branch branch(String name) {
    
  }
  
  void Merge() {
    
  }
}


main() {
  return Repo;
}

使用dart2js将其编译为JavaScript,以查看我的状态:

// Generated by dart2js, the Dart to JavaScript compiler version: 1.3.6.
// The code supports the following hooks:
// dartPrint(message):
//    if this function is defined it is called instead of the Dart [print]
//    method.
//
// dartMainRunner(main, args):
//    if this function is defined, the Dart [main] method will not be invoked
//    directly. Instead, a closure that will invoke [main], and its arguments
//    [args] is passed to [dartMainRunner].
(function($) {
function dart(){ this.x = 0 }var A = new dart;
delete A.x;
var B = new dart;
delete B.x;
var C = new dart;
delete C.x;
var D = new dart;
delete D.x;
var E = new dart;
delete E.x;
var F = new dart;
delete F.x;
var G = new dart;
delete G.x;
var H = new dart;
delete H.x;
var J = new dart;
delete J.x;
var K = new dart;
delete K.x;
var L = new dart;
delete L.x;
var M = new dart;
delete M.x;
var N = new dart;
delete N.x;
var O = new dart;
delete O.x;
var P = new dart;
delete P.x;
var Q = new dart;
delete Q.x;
var R = new dart;
delete R.x;
var S = new dart;
delete S.x;
var T = new dart;
delete T.x;
var U = new dart;
delete U.x;
var V = new dart;
delete V.x;
var W = new dart;
delete W.x;
var X = new dart;
delete X.x;
var Y = new dart;
delete Y.x;
var Z = new dart;
delete Z.x;
function Isolate() {}
init();

$ = Isolate.$isolateProperties;
var $$ = {};

(function (reflectionData) {
  "use strict";
  function map(x){x={x:x};delete x.x;return x}
    function processStatics(descriptor) {
      for (var property in descriptor) {
        if (!hasOwnProperty.call(descriptor, property)) continue;
        if (property === "^") continue;
        var element = descriptor[property];
        var firstChar = property.substring(0, 1);
        var previousProperty;
        if (firstChar === "+") {
          mangledGlobalNames[previousProperty] = property.substring(1);
          var flag = descriptor[property];
          if (flag > 0) descriptor[previousProperty].$reflectable = flag;
          if (element && element.length) init.typeInformation[previousProperty] = element;
        } else if (firstChar === "@") {
          property = property.substring(1);
          $[property]["@"] = element;
        } else if (firstChar === "*") {
          globalObject[previousProperty].$defaultValues = element;
          var optionalMethods = descriptor.$methodsWithOptionalArguments;
          if (!optionalMethods) {
            descriptor.$methodsWithOptionalArguments = optionalMethods = {}
          }
          optionalMethods[property] = previousProperty;
        } else if (typeof element === "function") {
          globalObject[previousProperty = property] = element;
          functions.push(property);
          init.globalFunctions[property] = element;
        } else if (element.constructor === Array) {
          addStubs(globalObject, element, property, true, descriptor, functions);
        } else {
          previousProperty = property;
          var newDesc = {};
          var previousProp;
          for (var prop in element) {
            if (!hasOwnProperty.call(element, prop)) continue;
            firstChar = prop.substring(0, 1);
            if (prop === "static") {
              processStatics(init.statics[property] = element[prop]);
            } else if (firstChar === "+") {
              mangledNames[previousProp] = prop.substring(1);
              var flag = element[prop];
              if (flag > 0) element[previousProp].$reflectable = flag;
            } else if (firstChar === "@" && prop !== "@") {
              newDesc[prop.substring(1)]["@"] = element[prop];
            } else if (firstChar === "*") {
              newDesc[previousProp].$defaultValues = element[prop];
              var optionalMethods = newDesc.$methodsWithOptionalArguments;
              if (!optionalMethods) {
                newDesc.$methodsWithOptionalArguments = optionalMethods={}
              }
              optionalMethods[prop] = previousProp;
            } else {
              var elem = element[prop];
              if (prop !== "^" && elem != null && elem.constructor === Array && prop !== "<>") {
                addStubs(newDesc, elem, prop, false, element, []);
              } else {
                newDesc[previousProp = prop] = elem;
              }
            }
          }
          $$[property] = [globalObject, newDesc];
          classes.push(property);
        }
      }
    }
  function addStubs(descriptor, array, name, isStatic, originalDescriptor, functions) {
    var f, funcs = [originalDescriptor[name] = descriptor[name] = f = array[0]];
    f.$stubName = name;
    functions.push(name);
    for (var index = 0; index < array.length; index += 2) {
      f = array[index + 1];
      if (typeof f != "function") break;
      f.$stubName = array[index + 2];
      funcs.push(f);
      if (f.$stubName) {
        originalDescriptor[f.$stubName] = descriptor[f.$stubName] = f;
        functions.push(f.$stubName);
      }
    }
    for (var i = 0; i < funcs.length; index++, i++) {
      funcs[i].$callName = array[index + 1];
    }
    var getterStubName = array[++index];
    array = array.slice(++index);
    var requiredParameterInfo = array[0];
    var requiredParameterCount = requiredParameterInfo >> 1;
    var isAccessor = (requiredParameterInfo & 1) === 1;
    var isSetter = requiredParameterInfo === 3;
    var isGetter = requiredParameterInfo === 1;
    var optionalParameterInfo = array[1];
    var optionalParameterCount = optionalParameterInfo >> 1;
    var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
    var isIntercepted = requiredParameterCount + optionalParameterCount != funcs[0].length;
    var functionTypeIndex = array[2];
    var unmangledNameIndex =  2 * optionalParameterCount + requiredParameterCount + 3;
    var isReflectable = array.length > unmangledNameIndex;

    if (getterStubName) {
      f = tearOff(funcs, array, isStatic, name, isIntercepted);
      f.getterStub = true;
      if (isStatic) init.globalFunctions[name] = f;
      originalDescriptor[getterStubName] = descriptor[getterStubName] = f;
      funcs.push(f);
      if (getterStubName) functions.push(getterStubName);
      f.$stubName = getterStubName;
      f.$callName = null;
      if (isIntercepted) init.interceptedNames[getterStubName] = true;
    }
    if (isReflectable) {
      for (var i = 0; i < funcs.length; i++) {
        funcs[i].$reflectable = 1;
        funcs[i].$reflectionInfo = array;
      }
      var mangledNames = isStatic ? init.mangledGlobalNames : init.mangledNames;
      var unmangledName = array[unmangledNameIndex];
      var reflectionName = unmangledName;
      if (getterStubName) mangledNames[getterStubName] = reflectionName;
      if (isSetter) {
        reflectionName += "=";
      } else if (!isGetter) {
        reflectionName += ":" + requiredParameterCount + ":" + optionalParameterCount;
      }
      mangledNames[name] = reflectionName;
      funcs[0].$reflectionName = reflectionName;
      funcs[0].$metadataIndex = unmangledNameIndex + 1;
      if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0];
    }
  }
  function tearOffGetterNoCsp(funcs, reflectionInfo, name, isIntercepted) {
    return isIntercepted
        ? new Function("funcs", "reflectionInfo", "name", "H", "c",
            "return function tearOff_" + name + (functionCounter++)+ "(x) {" +
              "if (c === null) c = H.closureFromTearOff(" +
                  "this, funcs, reflectionInfo, false, [x], name);" +
              "return new c(this, funcs[0], x, name);" +
            "}")(funcs, reflectionInfo, name, H, null)
        : new Function("funcs", "reflectionInfo", "name", "H", "c",
            "return function tearOff_" + name + (functionCounter++)+ "() {" +
              "if (c === null) c = H.closureFromTearOff(" +
                  "this, funcs, reflectionInfo, false, [], name);" +
              "return new c(this, funcs[0], null, name);" +
            "}")(funcs, reflectionInfo, name, H, null)
  }
  function tearOffGetterCsp(funcs, reflectionInfo, name, isIntercepted) {
    var cache = null;
    return isIntercepted
        ? function(x) {
            if (cache === null) cache = H.closureFromTearOff(this, funcs, reflectionInfo, false, [x], name);
            return new cache(this, funcs[0], x, name)
          }
        : function() {
            if (cache === null) cache = H.closureFromTearOff(this, funcs, reflectionInfo, false, [], name);
            return new cache(this, funcs[0], null, name)
          }
  }
  function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) {
    var cache;
    return isStatic
        ? function() {
            if (cache === void 0) cache = H.closureFromTearOff(this, funcs, reflectionInfo, true, [], name).prototype;
            return cache;
          }
        : tearOffGetter(funcs, reflectionInfo, name, isIntercepted);
  }
  var functionCounter = 0;
  var tearOffGetter = (typeof dart_precompiled == "function")
      ? tearOffGetterCsp : tearOffGetterNoCsp;
  if (!init.libraries) init.libraries = [];
  if (!init.mangledNames) init.mangledNames = map();
  if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
  if (!init.statics) init.statics = map();
  if (!init.typeInformation) init.typeInformation = map();
  if (!init.globalFunctions) init.globalFunctions = map();
  if (!init.interceptedNames) init.interceptedNames = map();
  var libraries = init.libraries;
  var mangledNames = init.mangledNames;
  var mangledGlobalNames = init.mangledGlobalNames;
  var hasOwnProperty = Object.prototype.hasOwnProperty;
  var length = reflectionData.length;
  for (var i = 0; i < length; i++) {
    var data = reflectionData[i];
    var name = data[0];
    var uri = data[1];
    var metadata = data[2];
    var globalObject = data[3];
    var descriptor = data[4];
    var isRoot = !!data[5];
    var fields = descriptor && descriptor["^"];
    var classes = [];
    var functions = [];
    processStatics(descriptor);
    libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
                    globalObject]);
  }
})
([
["Repo", "repo.dart", , F, {
  "^": "",
  main: function() {
    return C.Type_Jeh;
  }
},
1],
["_js_helper", "dart:_js_helper", , H, {
  "^": "",
  createRuntimeType: function($name) {
    return new H.TypeImpl($name, null);
  },
  TypeImpl: {
    "^": "Object;_typeName,_unmangledName"
  }
}],
["dart.core", "dart:core", , P, {
  "^": "",
  Null: {
    "^": "Object;"
  },
  Object: {
    "^": ";"
  }
}],
]);
Isolate.$finishClasses($$, $, null);
$$ = null;

// Runtime type support
// getInterceptor methods
C.Type_Jeh = H.createRuntimeType('Repo');
$.libraries_to_load = {};
$.Closure_functionCounter = 0;
$.BoundClosure_selfFieldNameCache = null;
$.BoundClosure_receiverFieldNameCache = null;

init.functionAliases = {};
;
init.metadata = [];
$ = null;
Isolate = Isolate.$finishIsolateConstructor(Isolate);
$ = new Isolate();
function convertToFastObject(properties) {
  function MyClass() {};
  MyClass.prototype = properties;
  new MyClass();
  return properties;
}
A = convertToFastObject(A);
B = convertToFastObject(B);
C = convertToFastObject(C);
D = convertToFastObject(D);
E = convertToFastObject(E);
F = convertToFastObject(F);
G = convertToFastObject(G);
H = convertToFastObject(H);
J = convertToFastObject(J);
K = convertToFastObject(K);
L = convertToFastObject(L);
M = convertToFastObject(M);
N = convertToFastObject(N);
O = convertToFastObject(O);
P = convertToFastObject(P);
Q = convertToFastObject(Q);
R = convertToFastObject(R);
S = convertToFastObject(S);
T = convertToFastObject(T);
U = convertToFastObject(U);
V = convertToFastObject(V);
W = convertToFastObject(W);
X = convertToFastObject(X);
Y = convertToFastObject(Y);
Z = convertToFastObject(Z);
// BEGIN invoke [main].
;(function (callback) {
  if (typeof document === "undefined") {
    callback(null);
    return;
  }
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }

  var scripts = document.scripts;
  function onLoad(event) {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener("load", onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener("load", onLoad, false);
  }
})(function(currentScript) {
  init.currentScript = currentScript;

  if (typeof dartMainRunner === "function") {
    dartMainRunner(F.main, []);
  } else {
    F.main([]);
  }
});
// END invoke [main].
function init() {
  Isolate.$isolateProperties = {};
  function generateAccessor(fieldDescriptor, accessors, cls) {
    var fieldInformation = fieldDescriptor.split("-");
    var field = fieldInformation[0];
    var len = field.length;
    var code = field.charCodeAt(len - 1);
    var reflectable;
    if (fieldInformation.length > 1)
      reflectable = true;
    else
      reflectable = false;
    code = code >= 60 && code <= 64 ? code - 59 : code >= 123 && code <= 126 ? code - 117 : code >= 37 && code <= 43 ? code - 27 : 0;
    if (code) {
      var getterCode = code & 3;
      var setterCode = code >> 2;
      var accessorName = field = field.substring(0, len - 1);
      var divider = field.indexOf(":");
      if (divider > 0) {
        accessorName = field.substring(0, divider);
        field = field.substring(divider + 1);
      }
      if (getterCode) {
        var args = getterCode & 2 ? "receiver" : "";
        var receiver = getterCode & 1 ? "this" : "receiver";
        var body = "return " + receiver + "." + field;
        var property = cls + ".prototype.get$" + accessorName + "=";
        var fn = "function(" + args + "){" + body + "}";
        if (reflectable)
          accessors.push(property + "$reflectable(" + fn + ");\n");
        else
          accessors.push(property + fn + ";\n");
      }
      if (setterCode) {
        var args = setterCode & 2 ? "receiver, value" : "value";
        var receiver = setterCode & 1 ? "this" : "receiver";
        var body = receiver + "." + field + " = value";
        var property = cls + ".prototype.set$" + accessorName + "=";
        var fn = "function(" + args + "){" + body + "}";
        if (reflectable)
          accessors.push(property + "$reflectable(" + fn + ");\n");
        else
          accessors.push(property + fn + ";\n");
      }
    }
    return field;
  }
  Isolate.$isolateProperties.$generateAccessor = generateAccessor;
  function defineClass(name, cls, fields) {
    var accessors = [];
    var str = "function " + cls + "(";
    var body = "";
    for (var i = 0; i < fields.length; i++) {
      if (i != 0)
        str += ", ";
      var field = generateAccessor(fields[i], accessors, cls);
      var parameter = "parameter_" + field;
      str += parameter;
      body += "this." + field + " = " + parameter + ";\n";
    }
    str += ") {\n" + body + "}\n";
    str += cls + ".builtin$cls=\"" + name + "\";\n";
    str += "$desc=$collectedClasses." + cls + ";\n";
    str += "if($desc instanceof Array) $desc = $desc[1];\n";
    str += cls + ".prototype = $desc;\n";
    if (typeof defineClass.name != "string") {
      str += cls + ".name=\"" + cls + "\";\n";
    }
    str += accessors.join("");
    return str;
  }
  var inheritFrom = function() {
    function tmp() {
    }
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    return function(constructor, superConstructor) {
      tmp.prototype = superConstructor.prototype;
      var object = new tmp();
      var properties = constructor.prototype;
      for (var member in properties)
        if (hasOwnProperty.call(properties, member))
          object[member] = properties[member];
      object.constructor = constructor;
      constructor.prototype = object;
      return object;
    };
  }();
  Isolate.$finishClasses = function(collectedClasses, isolateProperties, existingIsolateProperties) {
    var pendingClasses = {};
    if (!init.allClasses)
      init.allClasses = {};
    var allClasses = init.allClasses;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    if (typeof dart_precompiled == "function") {
      var constructors = dart_precompiled(collectedClasses);
    } else {
      var combinedConstructorFunction = "function $reflectable(fn){fn.$reflectable=1;return fn};\n" + "var $desc;\n";
      var constructorsList = [];
    }
    for (var cls in collectedClasses) {
      if (hasOwnProperty.call(collectedClasses, cls)) {
        var desc = collectedClasses[cls];
        if (desc instanceof Array)
          desc = desc[1];
        var classData = desc["^"], supr, name = cls, fields = classData;
        if (typeof classData == "string") {
          var split = classData.split("/");
          if (split.length == 2) {
            name = split[0];
            fields = split[1];
          }
        }
        var s = fields.split(";");
        fields = s[1] == "" ? [] : s[1].split(",");
        supr = s[0];
        split = supr.split(":");
        if (split.length == 2) {
          supr = split[0];
          var functionSignature = split[1];
          if (functionSignature)
            desc.$signature = function(s) {
              return function() {
                return init.metadata[s];
              };
            }(functionSignature);
        }
        if (typeof dart_precompiled != "function") {
          combinedConstructorFunction += defineClass(name, cls, fields);
          constructorsList.push(cls);
        }
        if (supr)
          pendingClasses[cls] = supr;
      }
    }
    if (typeof dart_precompiled != "function") {
      combinedConstructorFunction += "return [\n  " + constructorsList.join(",\n  ") + "\n]";
      var constructors = new Function("$collectedClasses", combinedConstructorFunction)(collectedClasses);
      combinedConstructorFunction = null;
    }
    for (var i = 0; i < constructors.length; i++) {
      var constructor = constructors[i];
      var cls = constructor.name;
      var desc = collectedClasses[cls];
      var globalObject = isolateProperties;
      if (desc instanceof Array) {
        globalObject = desc[0] || isolateProperties;
        desc = desc[1];
      }
      allClasses[cls] = constructor;
      globalObject[cls] = constructor;
    }
    constructors = null;
    var finishedClasses = {};
    init.interceptorsByTag = Object.create(null);
    init.leafTags = {};
    function finishClass(cls) {
      var hasOwnProperty = Object.prototype.hasOwnProperty;
      if (hasOwnProperty.call(finishedClasses, cls))
        return;
      finishedClasses[cls] = true;
      var superclass = pendingClasses[cls];
      if (!superclass || typeof superclass != "string")
        return;
      finishClass(superclass);
      var constructor = allClasses[cls];
      var superConstructor = allClasses[superclass];
      if (!superConstructor)
        superConstructor = existingIsolateProperties[superclass];
      var prototype = inheritFrom(constructor, superConstructor);
    }
    for (var cls in pendingClasses)
      finishClass(cls);
  };
  Isolate.$lazy = function(prototype, staticName, fieldName, getterName, lazyValue) {
    var sentinelUndefined = {};
    var sentinelInProgress = {};
    prototype[fieldName] = sentinelUndefined;
    prototype[getterName] = function() {
      var result = $[fieldName];
      try {
        if (result === sentinelUndefined) {
          $[fieldName] = sentinelInProgress;
          try {
            result = $[fieldName] = lazyValue();
          } finally {
            if (result === sentinelUndefined) {
              if ($[fieldName] === sentinelInProgress) {
                $[fieldName] = null;
              }
            }
          }
        } else {
          if (result === sentinelInProgress)
            H.throwCyclicInit(staticName);
        }
        return result;
      } finally {
        $[getterName] = function() {
          return this[fieldName];
        };
      }
    };
  };
  Isolate.$finishIsolateConstructor = function(oldIsolate) {
    var isolateProperties = oldIsolate.$isolateProperties;
    function Isolate() {
      var hasOwnProperty = Object.prototype.hasOwnProperty;
      for (var staticName in isolateProperties)
        if (hasOwnProperty.call(isolateProperties, staticName))
          this[staticName] = isolateProperties[staticName];
      function ForceEfficientMap() {
      }
      ForceEfficientMap.prototype = this;
      new ForceEfficientMap();
    }
    Isolate.prototype = oldIsolate.prototype;
    Isolate.prototype.constructor = Isolate;
    Isolate.$isolateProperties = isolateProperties;
    Isolate.$finishClasses = oldIsolate.$finishClasses;
    return Isolate;
  };
}
})()

//# sourceMappingURL=out.js.map
//@ sourceMappingURL=out.js.map

就是这样,我扔掉了Dart,因为我不知道该如何处理生成的JS文件,而且我对于保持生成的库接口整洁并与我正在使用的库接口相似,可能会花费大量时间使用JavaScript。

问题

  1. 如何公开在Dart中创建的类定义,然后在JavaScript中使用它们?
  2. 当几乎所有潜在的库用户都将使用JS版本时,您认为进入Dart值得吗?(由于社区规模的差异,使用飞镖已经对我不利,这意味着更少的人会发现为我的图书馆做贡献很容易)
  3. 您认为我该怎么办?
贡特·佐赫鲍尔(GünterZöchbauer)

即使Dart支持此用例,但如果您以JavaScript开发人员为目标,我仍会坚持使用JavaScript。

@AlexandreArdhuin在对使用JavaScript公开Dart函数的答案中展示了如何使Dart函数可用于JavaScript。
有许多示例如何进行函数调用以及在Dart和JavaScript之间传递数据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Dart中使用JavaScript库amCharts?

来自分类Dev

有关使用Javascript库的Dart教程

来自分类Dev

如何在dart中使用javascript ui库

来自分类Dev

使用constructor.prototype方法创建JavaScript库

来自分类Dev

如何使用javascript创建迷你图片库?

来自分类Dev

dart可以产生可读的JavaScript库吗?

来自分类Dev

如何使用dart:html库编写文件?

来自分类Dev

创建Polymer dart Web组件库的正确方法?

来自分类Dev

如何使用intellij Dart插件在dart中创建新语句

来自分类Dev

如何使用Pure Javascript或Pure Javascript库创建背景图像的幻灯片

来自分类Dev

如何使用Dart创建Http响应

来自分类Dev

如何使用Dart创建Http响应

来自分类Dev

使用Browserify和Gulp使用共享的公共库创建单独的JavaScript包

来自分类Dev

创建和使用jar库

来自分类Dev

库不是使用makefile创建的

来自分类Dev

使用Java库创建JSON

来自分类Dev

如何使用模块创建库?

来自分类Dev

使用Haskell的JavaScript库

来自分类Dev

使用Haskell的JavaScript库

来自分类Dev

从cpp文件创建动态库,并使用clang创建静态库

来自分类Dev

使用Google Maps API和数据库Javascript MySQL PHP中的坐标创建线

来自分类Dev

使用Javascript按网页上的创建日期顺序从SharePoint库文件夹中加载内容

来自分类Dev

如何使用javascript从数据库创建自动计算值和新值

来自分类Dev

如何在SQLite中创建数据库,使用javascript实现添加编辑删除

来自分类Dev

使用Google Maps API和数据库Javascript MySQL PHP中的坐标创建线

来自分类Dev

使用 JavaScript 在 SharePoint 库中创建文件夹结构

来自分类Dev

在JavaScript中创建趋势图的库

来自分类Dev

使用JavaScript创建表

来自分类Dev

使用JavaScript创建HTML

Related 相关文章

热门标签

归档