Ensure plugin registrants are generated in build_web (#41906)

diff --git a/packages/flutter_tools/lib/src/build_system/targets/web.dart b/packages/flutter_tools/lib/src/build_system/targets/web.dart
index d097dcb..ef5a7c8 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/web.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart
@@ -55,12 +55,16 @@
 
     String contents;
     if (hasPlugins) {
+      final String generatedPath = environment.projectDir
+        .childDirectory('lib')
+        .childFile('generated_plugin_registrant.dart')
+        .absolute.uri.toString();
       contents = '''
 import 'dart:ui' as ui;
 
 import 'package:flutter_web_plugins/flutter_web_plugins.dart';
 
-import 'generated_plugin_registrant.dart';
+import '$generatedPath';
 import "$import" as entrypoint;
 
 Future<void> main() async {
diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart
index c924c3e..7644f63 100644
--- a/packages/flutter_tools/lib/src/web/compile.dart
+++ b/packages/flutter_tools/lib/src/web/compile.dart
@@ -27,9 +27,10 @@
   }
   final bool hasWebPlugins = findPlugins(flutterProject)
     .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
+  await injectPlugins(flutterProject, checkProjects: true);
   final Status status = logger.startProgress('Compiling $target for the Web...', timeout: null);
   final Stopwatch sw = Stopwatch()..start();
-  final BuildResult result = await const BuildSystem().build(const WebReleaseBundle(), Environment(
+  final BuildResult result = await buildSystem.build(const WebReleaseBundle(), Environment(
     outputDir: fs.directory(getWebBuildDirectory()),
     projectDir: fs.currentDirectory,
     buildDir: flutterProject.directory
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart
index 555b4d2..72c8e57 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart
@@ -7,6 +7,7 @@
 import 'package:flutter_tools/src/base/file_system.dart';
 import 'package:flutter_tools/src/base/platform.dart';
 import 'package:flutter_tools/src/build_info.dart';
+import 'package:flutter_tools/src/build_system/build_system.dart';
 import 'package:flutter_tools/src/cache.dart';
 import 'package:flutter_tools/src/commands/build.dart';
 import 'package:flutter_tools/src/commands/build_web.dart';
@@ -86,6 +87,70 @@
     FeatureFlags: () => TestFeatureFlags(isWebEnabled: false),
   }));
 
+  test('Builds a web bundle - end to end', () => testbed.run(() async {
+    final CommandRunner<void> runner = createTestCommandRunner(BuildCommand());
+    final List<String> dependencies = <String>[
+      fs.path.join('packages', 'flutter_tools', 'lib', 'src', 'build_system', 'targets', 'web.dart'),
+      fs.path.join('bin', 'cache', 'flutter_web_sdk'),
+      fs.path.join('bin', 'cache', 'dart-sdk', 'bin', 'snapshots', 'dart2js.dart.snapshot'),
+      fs.path.join('bin', 'cache', 'dart-sdk', 'bin', 'dart'),
+      fs.path.join('bin', 'cache', 'dart-sdk '),
+    ];
+    for (String dependency in dependencies) {
+      fs.file(dependency).createSync(recursive: true);
+    }
+
+    // Project files.
+    fs.file('.packages')
+      ..writeAsStringSync('''
+foo:lib/
+fizz:bar/lib/
+''');
+    fs.file('pubspec.yaml')
+      ..writeAsStringSync('''
+name: foo
+
+dependencies:
+  flutter:
+    sdk: flutter
+  fizz:
+    path:
+      bar/
+''');
+    fs.file(fs.path.join('bar', 'pubspec.yaml'))
+      ..createSync(recursive: true)
+      ..writeAsStringSync('''
+name: bar
+
+flutter:
+  plugin:
+    platforms:
+      web:
+        pluginClass: UrlLauncherPlugin
+        fileName: url_launcher_web.dart
+''');
+    fs.file(fs.path.join('bar', 'lib', 'url_launcher_web.dart'))
+      ..createSync(recursive: true)
+      ..writeAsStringSync('''
+class UrlLauncherPlugin {}
+''');
+    fs.file(fs.path.join('lib', 'main.dart'))
+      ..writeAsStringSync('void main() { }');
+
+    // Process calls. We're not testing that these invocations are correct because
+    // that is covered in targets/web_test.dart.
+    when(buildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
+      return BuildResult(success: true);
+    });
+
+    await runner.run(<String>['build', 'web']);
+
+    expect(fs.file(fs.path.join('lib', 'generated_plugin_registrant.dart')).existsSync(), true);
+  }, overrides: <Type, Generator>{
+    FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
+    BuildSystem: () => MockBuildSystem(),
+  }));
+
   test('hidden if feature flag is not enabled', () => testbed.run(() async {
     expect(BuildWebCommand().hidden, true);
   }, overrides: <Type, Generator>{
@@ -99,6 +164,7 @@
   }));
 }
 
+class MockBuildSystem extends Mock implements BuildSystem {}
 class MockWebCompilationProxy extends Mock implements WebCompilationProxy {}
 class MockPlatform extends Mock implements Platform {
   @override
diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
index 0af986a..dac418d 100644
--- a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
@@ -56,7 +56,7 @@
     final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
 
     // Plugins
-    expect(generated, contains("import 'generated_plugin_registrant.dart';"));
+    expect(generated, contains("import 'file:///lib/generated_plugin_registrant.dart';"));
     expect(generated, contains('registerPlugins(webPluginRegistry);'));
 
     // Platform
@@ -77,7 +77,7 @@
     final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
 
     // Plugins
-    expect(generated, contains("import 'generated_plugin_registrant.dart';"));
+    expect(generated, contains("import 'file:///C:/lib/generated_plugin_registrant.dart';"));
     expect(generated, contains('registerPlugins(webPluginRegistry);'));
 
     // Platform
@@ -100,7 +100,7 @@
     final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
 
     // Plugins
-    expect(generated, isNot(contains("import 'generated_plugin_registrant.dart';")));
+    expect(generated, isNot(contains("import 'file:///lib/generated_plugin_registrant.dart';")));
     expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
 
     // Platform
@@ -118,7 +118,7 @@
     final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
 
     // Plugins
-    expect(generated, contains("import 'generated_plugin_registrant.dart';"));
+    expect(generated, contains("import 'file:///lib/generated_plugin_registrant.dart';"));
     expect(generated, contains('registerPlugins(webPluginRegistry);'));
 
     // Platform
@@ -136,7 +136,7 @@
     final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
 
     // Plugins
-    expect(generated, isNot(contains("import 'generated_plugin_registrant.dart';")));
+    expect(generated, isNot(contains("import 'file:///lib/generated_plugin_registrant.dart';")));
     expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
 
     // Platform