草庐IT

Dart build_runner 只能扫描/读取/写入web/目录下的文件?

coder 2023-07-22 原文

我正在开发一个 Flutter 应用程序,并想编写一个构建脚本来将某种原始文件(CSV 格式)转换为格式化的 JSON 文件,以作为 Flutter Assets 包含在内。

通过使用像 json_serializablejaguar_serializer 这样的库,我了解了 build_runner,所以看起来我要编写自己的 Builder 并通过 build_runner 调用它是一种明智的方式。

由于有关编写我们自己的构建脚本的资源非常有限,我首先修改找到的示例 here .但是我在尝试更改输入和输出文件的路径时卡住了:当我运行 flutter pub pub run build_runner build 时,结果发现 Dart 仅在 [ project_dir]/web 目录,只允许我将文件写入此 web 目录。所以这段代码

buildStep.writeAsString(new AssetId(buildStep.inputId.package, 'assets/resources/foo.json'), '[]');

将产生以下异常:

UnexpectedOutputException: myapp|assets/resources/foo.json
Expected only: {myapp|web/.json}
[SEVERE] Failed after 24.4s

json_serializablejaguar_serializer 可以在任何地方自由生成代码这一事实似乎表明我的配置存在问题。但是我在我的代码和 build.yaml 文件中的任何地方都找不到这个 web 东西,所以这真的很令人费解。

FWIW,这是我的 builder.yaml 文件的内容:

builders:
  jsonBuilder:
    import: "package:myapp/builder.dart"
    builder_factories: ["jsonFileBuilder"]
    build_extensions: {"source.csv": [".json"]}
    build_to: source
    auto_apply: root_package

这是 builder.dart 文件

import 'dart:async';
import 'package:build/build.dart';

Builder jsonFileBuilder(BuilderOptions options) => new JsonFileBuilder();

class JsonFileBuilder implements Builder {
  @override
  Future build(BuildStep buildStep) async {
    await buildStep.writeAsString(
        new AssetId(buildStep.inputId.package, 'assets/resources/foo.json'),
        'hello');
  }

  @override
  final buildExtensions = const {
    'source.csv': const ['.json']
  };
}

提前致谢!

最佳答案

好吧,看来这个问题实际上是双重的。

关于输入

我的问题是,如果我将源 CSV 文件放在某个任意目录下(例如 offline),我的构建脚本将不会运行,因为没有找到匹配的文件。但是当我将文件放在 web 下时(如示例中所示),脚本将被调用。这让我产生了文件扫描仅限于web/的错觉。事实上,有一个列表 hard-coded file/directory whitelist :

const List<String> _defaultRootPackageWhitelist = const [
  'benchmark/**',
  'bin/**',
  'example/**',
  'lib/**',
  'test/**',
  'tool/**',
  'web/**',
  'pubspec.yaml',
  'pubspec.lock',
];

如果我将 CSV 文件放在 lib/ 下,我的构建脚本也会被调用。

要将我的非白名单文件附加到列表中,我必须将以下部分添加到 build.yaml

targets:
  $default:
    sources: 
    # Need to replicate the default whitelist here or other build will break:
    - "benchmark/**"
    - "bin/**"
    - "example/**"
    - "lib/**"
    - "test/**"
    - "tool/**"
    - "web/**"
    - "pubspec.yaml"
    - "pubspec.lock"
    # My new source
    - "offline/source.csv"

关于输出

我的问题是我无法写入任意目录,构建系统一直提示我只能写入web/。所以我以为文件写入被锁定到web/。同样,这也不完全正确,因为文件写入实际上锁定到输入文件的目录。这意味着我只能在构建运行器成功识别此目录中的文件后才能写入 offline/

文件写入权限的检查由this method in build_step_impl.dart控制:

  void _checkOutput(AssetId id) {
    if (!_expectedOutputs.contains(id)) {
      throw new UnexpectedOutputException(id, expected: _expectedOutputs);
    }
  }

_expectedOutputs 是我的构建器类的 buildExtensions 映射的扁平化值。所以如果我真的想写入 assets/resources/foo.json 我必须这样写:

  @override
  final buildExtensions = const {
    'source.csv': const ['/../../assets/resources/foo.json']
  };

必须对 build.yaml 进行类似的调整:

build_extensions: {".csv": ["/../../assets/resources/foo.json"]}

这基本上解决了我的大部分问题,但还有一些问题:

首先,我打算编写一个读取单个文件并写入多个文件的构建脚本。文件的数量及其文件名取决于源文件的内容。鉴于检查代码,这似乎不是受支持的功能。不是障碍物,但有点不方便。

第二个是关于输出文件路径。您可以看到我的源文件位于 [projectDir]/offline 中,我想写入 [projectDir]/assets,但输出文件名显示为 /。 ./../assets/...,向上两层。这是因为原始文件名(没有扩展名)被添加到输出路径之前,这就是为什么人们会在生成 Dart 代码的构建器配置中看到 .g.dart 的原因。我需要编写 /../../assets 这样我的文件的完整输出路径将变为 [projectDir]/offline/source/../../assets 使其解析为所需的输出文件路径。但是默认行为给我的印象是构建系统不希望我的脚本写入当前文件目录之外的任何地方,而我所做的是对系统的黑客攻击或滥用。

关于Dart build_runner 只能扫描/读取/写入web/目录下的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51188114/

有关Dart build_runner 只能扫描/读取/写入web/目录下的文件?的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  3. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  4. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

  5. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  8. ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出? - 2

    我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.

  9. ruby-on-rails - 没有这样的文件或目录 - 用 Mini Magick 识别 - 2

    在我让另一个人重做我的前端UI之前,我的Rails应用程序运行平稳。我已经尝试解决此错误3天了。这是错误:Nosuchfileordirectory-identifyExtractedsource(aroundline#59):575859606162@post=Post.find(params[:id])authorize@postif@post.update_attributes(post_params)flash[:notice]="Postwasupdated."redirect_to[@topic,@post]else{"utf8"=>"✓","_method"=>"patc

  10. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

随机推荐