You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart/Flutter gRPC:导入protos.dart提示URI目标不存在,求解决

Flutter/Dart gRPC导入错误:URI目标不存在问题

问题背景

我是Dart/Flutter gRPC新手,已完成以下步骤:

  • 在pubspec.yaml中安装grpc: ^4.0.1和protobuf: ^3.1.0
  • 完成protoc安装、proto文件创建及dart文件生成,流程无异常

但在main.dart中导入protos.dart时触发错误:

Target of URI doesn't exist: 'package:dave_knows/protos/lib/protos.dart'

当前文件结构

  • /lib/main.dart 导入语句:
import 'package:dave_knows/protos/lib/protos.dart';
import 'package:grpc/grpc.dart';
  • /protos/lib/protos.dart 内容:
library;
export 'package:protos/src/protos_base.dart';
export 'package:protos/generated/configure_new_user.pb.dart';
export 'package:protos/generated/configure_new_user.pbenum.dart';
export 'package:protos/generated/configure_new_user.pbjson.dart' ;
export 'package:protos/generated/configure_new_user.pbgrpc.dart' ;
export 'package:protos/generated/google/protobuf/empty.pb.dart' ;
export 'package:protos/generated/google/protobuf/empty.pbenum.dart' ;
export 'package:protos/generated/google/protobuf/empty.pbjson.dart' ;
export 'package:grpc/grpc.dart';
  • package:protos/generated/configure_new_user.pbgrpc.dart 核心内容:
import 'dart:async' as $async;
import 'dart:core' as $core;

import 'package:grpc/service_api.dart' as $grpc;
import 'package:protobuf/protobuf.dart' as $pb;

import 'configure_new_user.pb.dart' as $0;
import 'google/protobuf/empty.pb.dart' as $1;

@$pb.GrpcServiceName('ConfigureNewUser')
class ConfigureNewUserClient extends $grpc.Client {
  static final _$configureNewUser = $grpc.ClientMethod<$0.NewUser, $1.Empty>(
      '/ConfigureNewUser/configureNewUser',
      ($0.NewUser value) => value.writeToBuffer(),
      ($core.List<$core.int> value) => $1.Empty.fromBuffer(value));

  ConfigureNewUserClient($grpc.ClientChannel channel,
      {$grpc.CallOptions? options,
      $core.Iterable<$grpc.ClientInterceptor>? interceptors})
      : super(channel, options: options,
        interceptors: interceptors);

  $grpc.ResponseFuture<$1.Empty> configureNewUser($0.NewUser request, {$grpc.CallOptions? options}) {
    return $createUnaryCall(_$configureNewUser, request, options: options);
  }
}

@$pb.GrpcServiceName('ConfigureNewUser')
abstract class ConfigureNewUserServiceBase extends $grpc.Service {
  $core.String get $name => 'ConfigureNewUser';

  ConfigureNewUserServiceBase() {
    $addMethod($grpc.ServiceMethod<$0.NewUser, $1.Empty>(
        'configureNewUser',
        configureNewUser_Pre,
        false,
        false,
        ($core.List<$core.int> value) => $0.NewUser.fromBuffer(value),
        ($1.Empty value) => value.writeToBuffer()));
  }

  $async.Future<$1.Empty> configureNewUser_Pre($grpc.ServiceCall call, $async.Future<$0.NewUser> request) async {
    return configureNewUser(call, await request);
  }

  $async.Future<$1.Empty> configureNewUser($grpc.ServiceCall call, $0.NewUser request);
}

额外问题

IDE自动创建protos.dart时,会生成到/lib/protos/lib/protos.dart,而非期望的/protos/lib/protos.dart。

环境版本

Flutter 3.28.0-2.0.pre.38785 • channel master • https://github.com/flutter/flutter.git
Framework • revision b9e86a565f (6 days ago) • 2025-01-17 18:26:17 -0800
Engine • revision b9e86a565f
Tools • Dart 3.8.0 (build 3.8.0-1.0.dev) • DevTools 2.42.0

问题根源

  1. 包导入路径逻辑错误:Dart中package:开头的导入路径以项目的lib目录为根,你的protos目录在项目根目录而非lib下,因此package:dave_knows/protos/lib/protos.dart这个路径不存在。
  2. IDE默认生成规则:IDE会默认在lib目录下创建源码文件,因为Dart包的标准源码目录就是lib,你期望的根目录下protos不属于包的源码路径范围。

解决方案

方案1:调整文件结构到lib目录(简单直接)

  • 将项目根目录下的protos文件夹移动到lib目录内,最终结构变为lib/protos/lib/protos.dart
  • 保持main.dart中的导入语句不变,此时路径会被正确识别
  • 更优的结构优化:可以将protos目录下的层级简化,比如直接把protos.dart放在lib/protos/下,导入语句改为import 'package:dave_knows/protos/protos.dart';

方案2:将protos作为独立本地包(推荐,适合多模块复用)

  1. 在protos目录下创建pubspec.yaml,声明为独立Dart包:
name: protos
description: Generated gRPC proto definitions
version: 1.0.0
environment:
  sdk: ">=3.8.0 <4.0.0"
dependencies:
  grpc: ^4.0.1
  protobuf: ^3.1.0
  1. 在项目根目录的pubspec.yaml中添加本地依赖:
dependencies:
  grpc: ^4.0.1
  protobuf: ^3.1.0
  protos:
    path: ./protos
  1. 修改main.dart中的导入语句为:
import 'package:protos/protos.dart';
  1. 调整protos/lib/protos.dart中的内部导入路径,确保所有package:protos/...的引用正确(如果是相对路径生成的,可改为相对当前文件的路径,比如./src/protos_base.dart)

方案3:临时使用相对路径导入(不推荐正式项目)

如果不想调整结构,可直接用相对路径从main.dart指向目标文件:

import '../../protos/lib/protos.dart';

这种方式在项目结构变动时容易失效,仅适合临时测试。


内容的提问来源于stack exchange,提问作者S. Yacko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:55:58