dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.3k stars 1.59k forks source link

Flutter tool needs to traverse/walk pub dependencies, should it (long-term)? #56968

Open matanlurey opened 1 month ago

matanlurey commented 1 month ago

Forking this from an internal discussion:

@matanlurey:

I am doing a bit of research into what it would take to exclude dev_dependencies that are Flutter plugins from a release Flutter build (https://github.com/flutter/flutter/issues/56591); without this capability we include plugins (including ones provided by package:integration_test) even in release mode.

One difficulty of implementing this is knowledge of what dependencies of a package are dev dependencies:

  1. package_config.json doesn't retain this information (somewhat understandably, it's resolution only)
  2. pubspec.lock doesn't retain this information (it would have been nice)

In fact, the only thing I can tell is pubspec.yaml, but that means for transitive dev dependencies, I'd have to re-implement (something) like what already pub resolution does in the flutter CLI, which seems wasteful and potentially error-prone (though the CLI is so big, maybe it already does this).

Any thoughts on what to do here?

My solution ended up being to use dart pub deps --json and some parsing; see https://github.com/flutter/flutter/pull/157462.

From talking to @sigurdm and @jonasfj, we may want to pick an alternate strategy in the future. Some discussion:

Whether a package is in dev_dependencies or not, is not something that is designed to influence the build process. Build processes are intended to consume .dart_tool/package_config.json.

@matanlurey:

To be clear, the build process does consume that file - but if you remember, the plugin configuration is in pubspec.yaml. Here is one example: https://github.com/flutter/packages/blob/e0c4f55cd355a704981b96914edf9e93c50a76af/packages/video_player/video_player_android/pubspec.yaml#L11-L18 - so the pub dependency tree is read and is required as part of the (Flutter) build process today.

Maybe package_config.json should be extensible and be able to include more things? But it does not today.

Perhaps it's smarter to use treeshaking to find out which plugins should be compiled into the app. And if that's complicated, maybe looking towards native-assets

@matanlurey:

I could misunderstand, but let's explain really briefly what we're trying to do. Today, we (transitively) read all pubspec.yaml files, and build a file called .flutter-plugins-dependencies, which is sort of like package_config.json but for plugins. It looks something like this:

{
  "dependencyGraph": {
    "camera": {
      "name": "camera",
      "version": "0.10.0",
      "dependencies": {
        "flutter": "0.0.0"
      }
    },
    "shared_preferences": {
      "name": "shared_preferences",
      "version": "2.0.15",
      "dependencies": {
        "flutter": "0.0.0"
      }
    }
  },
  "flutter": {
    "frameworkRevision": "3a0f99d4f2",
    "channel": "stable"
  }
}

(https://docs.flutter.dev/release/breaking-changes/flutter-plugins-configuration)

That file in turn is read by various native build systems (like Gradle, or Xcode), and used to assemble the right Gradle/Xcode/etc projects to include these native plugins. One such example:

// settings.gradle.kts
plugins {
    id("dev.flutter.flutter-plugin-loader") version "1.0.0"
}

(https://github.com/flutter/flutter/blob/add7e81f4f5cb9903cbfe583f06e08f4566c5639/examples/hello_world/android/settings.gradle.kts#L35-L36)

/cc @dcharkes as well.

dart-github-bot commented 1 month ago

Summary: The issue is about excluding dev dependencies from Flutter release builds. Currently, Flutter includes all dependencies, including dev dependencies, in release builds. This is problematic because it can lead to unnecessary code being included in the final app. The issue proposes a solution to identify and exclude dev dependencies from the build process.