compile.dart 5.9 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import '../artifacts.dart';
6 7
import '../base/common.dart';
import '../base/file_system.dart';
8
import '../base/logger.dart';
9
import '../base/project_migrator.dart';
10
import '../build_info.dart';
11 12
import '../build_system/build_system.dart';
import '../build_system/targets/web.dart';
13
import '../cache.dart';
14
import '../flutter_plugins.dart';
15
import '../globals.dart' as globals;
16 17
import '../platform_plugins.dart';
import '../plugins.dart';
18
import '../project.dart';
19
import 'migrations/scrub_generated_plugin_registrant.dart';
20

21 22 23 24
Future<void> buildWeb(
  FlutterProject flutterProject,
  String target,
  BuildInfo buildInfo,
25
  bool csp,
26
  String serviceWorkerStrategy,
27
  bool sourceMaps,
28 29
  bool nativeNullAssertions,
  bool isWasm, {
30
  String? dart2jsOptimization,
31 32 33 34 35
  String? baseHref,
  bool dumpInfo = false,
  bool noFrequencyBasedMinification = false,
  String? outputDirectoryPath,
}) async {
36
  final bool hasWebPlugins = (await findPlugins(flutterProject))
37
    .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
38
  final Directory outputDirectory = outputDirectoryPath == null
39
      ? globals.fs.directory(getWebBuildDirectory(isWasm))
40
      : globals.fs.directory(outputDirectoryPath);
41 42
  outputDirectory.createSync(recursive: true);

43 44 45 46 47 48
  // The migrators to apply to a Web project.
  final List<ProjectMigrator> migrators = <ProjectMigrator>[
    ScrubGeneratedPluginRegistrant(flutterProject.web, globals.logger),
  ];

  final ProjectMigration migration = ProjectMigration(migrators);
49
  migration.run();
50

51
  final Status status = globals.logger.startProgress('Compiling $target for the Web...');
52
  final Stopwatch sw = Stopwatch()..start();
53
  try {
54
    final BuildResult result = await globals.buildSystem.build(
55
      WebServiceWorker(globals.fs, globals.cache, buildInfo.webRenderer, isWasm),
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
      Environment(
        projectDir: globals.fs.currentDirectory,
        outputDir: outputDirectory,
        buildDir: flutterProject.directory
          .childDirectory('.dart_tool')
          .childDirectory('flutter_build'),
        defines: <String, String>{
          kTargetFile: target,
          kHasWebPlugins: hasWebPlugins.toString(),
          kCspMode: csp.toString(),
          if (baseHref != null)
            kBaseHref : baseHref,
          kSourceMapsEnabled: sourceMaps.toString(),
          kNativeNullAssertions: nativeNullAssertions.toString(),
          kServiceWorkerStrategy: serviceWorkerStrategy,
          if (dart2jsOptimization != null)
72
            kDart2jsOptimization: dart2jsOptimization,
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
          kDart2jsDumpInfo: dumpInfo.toString(),
          kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
          ...buildInfo.toBuildSystemEnvironment(),
        },
        artifacts: globals.artifacts!,
        fileSystem: globals.fs,
        logger: globals.logger,
        processManager: globals.processManager,
        platform: globals.platform,
        usage: globals.flutterUsage,
        cacheDir: globals.cache.getRoot(),
        engineVersion: globals.artifacts!.isLocalEngine
          ? null
          : globals.flutterVersion.engineRevision,
        flutterRootDir: globals.fs.directory(Cache.flutterRoot),
        // Web uses a different Dart plugin registry.
        // https://github.com/flutter/flutter/issues/80406
        generateDartPluginRegistry: false,
91 92
    ));
    if (!result.success) {
93
      for (final ExceptionMeasurement measurement in result.exceptions.values) {
94
        globals.printError('Target ${measurement.target} failed: ${measurement.exception}',
95 96 97 98
          stackTrace: measurement.fatal
            ? measurement.stackTrace
            : null,
        );
99 100
      }
      throwToolExit('Failed to compile application for the Web.');
101
    }
102
  } on Exception catch (err) {
103 104 105
    throwToolExit(err.toString());
  } finally {
    status.stop();
106
  }
107
  globals.flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
108
}
109

110 111 112 113 114 115 116 117 118 119 120
/// Web rendering backend mode.
enum WebRendererMode {
  /// Auto detects which rendering backend to use.
  autoDetect,
  /// Always uses canvaskit.
  canvaskit,
  /// Always uses html.
  html,
}

/// The correct precompiled artifact to use for each build and render mode.
121 122 123 124
const Map<WebRendererMode, Map<NullSafetyMode, HostArtifact>> kDartSdkJsArtifactMap = <WebRendererMode, Map<NullSafetyMode, HostArtifact>>{
  WebRendererMode.autoDetect: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledCanvaskitAndHtmlSoundSdk,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledCanvaskitAndHtmlSdk,
125
  },
126 127 128
  WebRendererMode.canvaskit: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledCanvaskitSoundSdk,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledCanvaskitSdk,
129
  },
130 131 132
  WebRendererMode.html: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledSoundSdk,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledSdk,
133 134 135 136
  },
};

/// The correct source map artifact to use for each build and render mode.
137 138 139 140
const Map<WebRendererMode, Map<NullSafetyMode, HostArtifact>> kDartSdkJsMapArtifactMap = <WebRendererMode, Map<NullSafetyMode, HostArtifact>>{
  WebRendererMode.autoDetect: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledCanvaskitAndHtmlSoundSdkSourcemaps,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledCanvaskitAndHtmlSdkSourcemaps,
141
  },
142 143 144
  WebRendererMode.canvaskit: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledCanvaskitSoundSdkSourcemaps,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledCanvaskitSdkSourcemaps,
145
  },
146 147 148
  WebRendererMode.html: <NullSafetyMode, HostArtifact> {
    NullSafetyMode.sound: HostArtifact.webPrecompiledSoundSdkSourcemaps,
    NullSafetyMode.unsound: HostArtifact.webPrecompiledSdkSourcemaps,
149 150
  },
};