【问题标题】:Dart Transformer fails to overwrite an AssetDart Transformer 无法覆盖资产
【发布时间】:2016-02-14 22:50:18
【问题描述】:

我写了一个 AggregateTransformer,它应该用更新的版本覆盖 main.dart 文件(更改导入)。

Asset mainAsset = await _getFileAsset(transform, "main.dart");
Asset updatedMainAsset = await _replaceDefaultImport(mainAsset, transform.package, "default.dart", newLibFileName);

//overwrite mainAsset because mainAsset and updatedMainAsset have the same id
transform.addOutput(updatedMainAsset);

(在添加新版本之前先删除资产不会改变任何东西:)

transform.consumePrimary(mainAsset.id);
transform.addOutput(updatedMainAsset);

但更新后的版本消失得无影无踪。尝试通过 id 检索它会产生原始内容:

Asset updatedMainAssetRetrieved = await transform.getInput(updatedMainAsset.id);

转换器输出 mainAsset 和 updatedMainAsset 的内容,因此您可以检查 updatedMainAsset 的内容是否确实更新了。通过调用 pub run main.dart 来调用转换器。

完整的代码/伪代码如下所示:

class ReplacePackageTransformer extends AggregateTransformer {
  ReplacePackageTransformer.asPlugin();

  @override
  String classifyPrimary(AssetId id) => id.toString().endsWith(".dart") ? "dart-files" : null;

  @override
  apply(AggregateTransform transform) {
    //capture the whole execution to allow better stacktraces if an error occurs
    Chain.capture(() async {
      //create a file lib/replacement.dart that defines the same method as lib/default.dart
      final newLibFileName = "replacement.dart";
      final newLibAsset = _createReplacementAsset(...);
      //add this new asset
      transform.addOutput(newLibAsset);

      //rewrite main.dart to import replacement.dart instead of default.dart. To that end:
      //1) retrieve the asset for main.dart
      Asset mainAsset = await _getFileAsset(transform, "main.dart");
      //2) create a new asset with the same id as mainAsset but with updated content
      Asset updatedMainAsset = await _replaceDefaultImport(mainAsset, ...);
      //3) adding this asset should overwrite/replace the original main.dart-asset because they use the same id
      transform.addOutput(updatedMainAsset);
    });
  }

  //helper methods ...
}

您可以找到整个转换器(以及项目的其余部分)here

更新/解决方案

丹尼斯·卡塞洛是对的!我的转换器的应用方法必须返回一个 Future(以便后续转换器可以等待它完成)!在调用 Chain.capture 之前添加 return 就足够了(因为我捕获的回调具有异步主体并因此返回捕获将转发/返回的 Future)。

所以改变

apply(AggregateTransform transform) {
  Chain.capture(() async {...});
  //no return statement so void is returned
}

Future apply(AggregateTransform transform) {
  return Chain.capture(() async {...});
  //() async {...} returns a Future that Chain.capture and apply forward/return
}

解决了我的问题!

【问题讨论】:

标签: dart dart-pub


【解决方案1】:

解决方案非常简单:只需在您的Chain.capture 前面添加一个return

apply 的 dartdoc 说:

如果这是异步工作,它应该返回一个在完成后完成的 [Future]。

如果您在转换后访问输入,输入仍将是原始输入。你也不需要打电话给transform.consumeInput

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-14
    • 2014-03-31
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    相关资源
    最近更新 更多