Record deferred components assets in AssetManifest.json (#78824)

diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
index 5ddb9f8..80fb166 100644
--- a/packages/flutter_tools/lib/src/asset.dart
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -399,7 +399,7 @@
       _wildcardDirectories[uri] ??= _fileSystem.directory(uri);
     }
 
-    final DevFSStringContent assetManifest  = _createAssetManifest(assetVariants);
+    final DevFSStringContent assetManifest  = _createAssetManifest(assetVariants, deferredComponentsAssetVariants);
     final DevFSStringContent fontManifest = DevFSStringContent(json.encode(fonts));
     final LicenseResult licenseResult = _licenseCollector.obtainLicenses(packageConfig, additionalLicenseFiles);
     if (licenseResult.errorMessages.isNotEmpty) {
@@ -524,16 +524,34 @@
     return deferredComponentsAssetVariants;
   }
 
-  DevFSStringContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
+  DevFSStringContent _createAssetManifest(
+    Map<_Asset, List<_Asset>> assetVariants,
+    Map<String, Map<_Asset, List<_Asset>>> deferredComponentsAssetVariants
+  ) {
     final Map<String, List<String>> jsonObject = <String, List<String>>{};
-    final List<_Asset> assets = assetVariants.keys.toList()
-      ..sort((_Asset left, _Asset right) => left.entryUri.path.compareTo(right.entryUri.path));
+    final List<_Asset> assets = assetVariants.keys.toList();
+    final Map<_Asset, List<String>> jsonEntries = <_Asset, List<String>>{};
     for (final _Asset main in assets) {
-      jsonObject[main.entryUri.path] = <String>[
+      jsonEntries[main] = <String>[
         for (final _Asset variant in assetVariants[main])
           variant.entryUri.path,
       ];
     }
+    if (deferredComponentsAssetVariants != null) {
+      for (final Map<_Asset, List<_Asset>> componentAssets in deferredComponentsAssetVariants.values) {
+        for (final _Asset main in componentAssets.keys) {
+          jsonEntries[main] = <String>[
+            for (final _Asset variant in componentAssets[main])
+              variant.entryUri.path,
+          ];
+        }
+      }
+    }
+    final List<_Asset> sortedKeys = jsonEntries.keys.toList()
+        ..sort((_Asset left, _Asset right) => left.entryUri.path.compareTo(right.entryUri.path));
+    for (final _Asset main in sortedKeys) {
+      jsonObject[main.entryUri.path] = jsonEntries[main];
+    }
     return DevFSStringContent(json.encode(jsonObject));
   }
 
diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart
index 73fe335..e6315d1 100644
--- a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart
+++ b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart
@@ -591,4 +591,41 @@
     ProcessManager: () => FakeProcessManager.any(),
     Platform: () => FakePlatform(operatingSystem: 'linux'),
   });
+
+  testUsingContext('deferred and regular assets are included in manifest alphabetically', () async {
+    globals.fs.file('.packages').writeAsStringSync(r'''
+example:lib/
+''');
+    globals.fs.file('pubspec.yaml')
+      ..createSync()
+      ..writeAsStringSync(r'''
+name: example
+
+flutter:
+  assets:
+    - assets/zebra.jpg
+    - assets/foo.jpg
+
+  deferred-components:
+    - name: component1
+      assets:
+        - assets/bar.jpg
+        - assets/apple.jpg
+''');
+    globals.fs.file('assets/foo.jpg').createSync(recursive: true);
+    globals.fs.file('assets/bar.jpg').createSync();
+    globals.fs.file('assets/apple.jpg').createSync();
+    globals.fs.file('assets/zebra.jpg').createSync();
+    final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
+
+    expect(await bundle.build(manifestPath: 'pubspec.yaml', packagesPath: '.packages'), 0);
+    expect((bundle.entries['FontManifest.json'] as DevFSStringContent).string, '[]');
+    // The assets from deferred components and regular assets
+    // are both included in alphabetical order
+    expect((bundle.entries['AssetManifest.json'] as DevFSStringContent).string, '{"assets/apple.jpg":["assets/apple.jpg"],"assets/bar.jpg":["assets/bar.jpg"],"assets/foo.jpg":["assets/foo.jpg"],"assets/zebra.jpg":["assets/zebra.jpg"]}');
+  }, overrides: <Type, Generator>{
+    FileSystem: () => MemoryFileSystem.test(),
+    ProcessManager: () => FakeProcessManager.any(),
+    Platform: () => FakePlatform(operatingSystem: 'linux'),
+  });
 }