mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add analytics events for wasm dry runs on web builds (#171818)
Follow up to https://github.com/flutter/flutter/pull/171682 Depends on https://github.com/dart-lang/tools/pull/2125 --------- Co-authored-by: Nate Biggs <natebiggs@google.com>
This commit is contained in:
parent
4336d5c417
commit
06ce4bb187
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import '../base/file_system.dart';
|
||||
import '../web/compiler_config.dart';
|
||||
import './build_system.dart';
|
||||
@ -14,7 +16,11 @@ abstract class BuildTargets {
|
||||
Target get releaseCopyFlutterBundle;
|
||||
Target get generateLocalizationsTarget;
|
||||
Target get dartPluginRegistrantTarget;
|
||||
Target webServiceWorker(FileSystem fileSystem, List<WebCompilerConfig> compileConfigs);
|
||||
Target webServiceWorker(
|
||||
FileSystem fileSystem,
|
||||
List<WebCompilerConfig> compileConfigs,
|
||||
Analytics analytics,
|
||||
);
|
||||
}
|
||||
|
||||
/// BuildTargets that return NoOpTarget for every action.
|
||||
@ -34,8 +40,11 @@ class NoOpBuildTargets extends BuildTargets {
|
||||
Target get dartPluginRegistrantTarget => const _NoOpTarget();
|
||||
|
||||
@override
|
||||
Target webServiceWorker(FileSystem fileSystem, List<WebCompilerConfig> compileConfigs) =>
|
||||
const _NoOpTarget();
|
||||
Target webServiceWorker(
|
||||
FileSystem fileSystem,
|
||||
List<WebCompilerConfig> compileConfigs,
|
||||
Analytics analytics,
|
||||
) => const _NoOpTarget();
|
||||
}
|
||||
|
||||
/// A [Target] that does nothing.
|
||||
|
||||
@ -6,6 +6,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import '../../artifacts.dart';
|
||||
import '../../base/file_system.dart';
|
||||
@ -273,11 +274,13 @@ class Dart2JSTarget extends Dart2WebTarget {
|
||||
|
||||
/// Compiles a web entry point with dart2wasm.
|
||||
class Dart2WasmTarget extends Dart2WebTarget {
|
||||
Dart2WasmTarget(this.compilerConfig);
|
||||
Dart2WasmTarget(this.compilerConfig, this._analytics);
|
||||
|
||||
@override
|
||||
final WasmCompilerConfig compilerConfig;
|
||||
|
||||
final Analytics _analytics;
|
||||
|
||||
/// List the preconfigured build options for a given build mode.
|
||||
List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) => switch (mode) {
|
||||
BuildMode.debug => <String>[
|
||||
@ -403,22 +406,28 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
||||
final int exitCode = runResult.exitCode;
|
||||
final String stdout = runResult.stdout;
|
||||
final String stderr = runResult.stderr;
|
||||
final String result;
|
||||
String? findingsSummary;
|
||||
|
||||
if (exitCode != 0 && exitCode != 254) {
|
||||
environment.logger.printWarning('Unexpected wasm dry run failure ($exitCode):');
|
||||
if (stderr.isNotEmpty) {
|
||||
environment.logger.printWarning(stdout);
|
||||
environment.logger.printWarning(stderr);
|
||||
}
|
||||
result = 'crash';
|
||||
} else if (exitCode == 0) {
|
||||
environment.logger.printWarning(
|
||||
'Wasm dry run succeeded. Consider building and testing your application with the '
|
||||
'`--wasm` flag. See docs for more info: '
|
||||
'https://docs.flutter.dev/platform-integration/web/wasm',
|
||||
);
|
||||
result = 'success';
|
||||
} else if (stderr.isNotEmpty) {
|
||||
environment.logger.printWarning('Wasm dry run failed:');
|
||||
environment.logger.printWarning(stdout);
|
||||
environment.logger.printWarning(stderr);
|
||||
result = 'failure';
|
||||
} else if (stdout.isNotEmpty) {
|
||||
environment.logger.printWarning('Wasm dry run findings:');
|
||||
environment.logger.printWarning(stdout);
|
||||
@ -426,20 +435,30 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
||||
'Consider addressing these issues to enable wasm builds. See docs for more info: '
|
||||
'https://docs.flutter.dev/platform-integration/web/wasm\n',
|
||||
);
|
||||
result = 'findings';
|
||||
findingsSummary = RegExp(
|
||||
r'\(([0-9]+)\)',
|
||||
).allMatches(stdout).map((RegExpMatch f) => f.group(1)).join(',');
|
||||
} else {
|
||||
result = 'unknown';
|
||||
}
|
||||
environment.logger.printWarning('Use --no-wasm-dry-run to disable these warnings.');
|
||||
|
||||
_analytics.send(
|
||||
Event.flutterWasmDryRun(result: result, exitCode: exitCode, findingsSummary: findingsSummary),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Unpacks the dart2js or dart2wasm compilation and resources to a given
|
||||
/// output directory.
|
||||
class WebReleaseBundle extends Target {
|
||||
WebReleaseBundle(List<WebCompilerConfig> configs)
|
||||
WebReleaseBundle(List<WebCompilerConfig> configs, Analytics analytics)
|
||||
: this._(
|
||||
compileTargets: configs
|
||||
.map(
|
||||
(WebCompilerConfig config) => switch (config) {
|
||||
WasmCompilerConfig() => Dart2WasmTarget(config),
|
||||
WasmCompilerConfig() => Dart2WasmTarget(config, analytics),
|
||||
JsCompilerConfig() => Dart2JSTarget(config),
|
||||
},
|
||||
)
|
||||
@ -743,17 +762,18 @@ class WebBuiltInAssets extends Target {
|
||||
|
||||
/// Generate a service worker for a web target.
|
||||
class WebServiceWorker extends Target {
|
||||
const WebServiceWorker(this.fileSystem, this.compileConfigs);
|
||||
const WebServiceWorker(this.fileSystem, this.compileConfigs, this.analytics);
|
||||
|
||||
final FileSystem fileSystem;
|
||||
final List<WebCompilerConfig> compileConfigs;
|
||||
final Analytics analytics;
|
||||
|
||||
@override
|
||||
String get name => 'web_service_worker';
|
||||
|
||||
@override
|
||||
List<Target> get dependencies => <Target>[
|
||||
WebReleaseBundle(compileConfigs),
|
||||
WebReleaseBundle(compileConfigs, analytics),
|
||||
WebBuiltInAssets(fileSystem),
|
||||
];
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import '../base/file_system.dart';
|
||||
import '../build_system/build_system.dart';
|
||||
import '../build_system/build_targets.dart';
|
||||
@ -27,6 +29,9 @@ class BuildTargetsImpl extends BuildTargets {
|
||||
Target get dartPluginRegistrantTarget => const DartPluginRegistrantTarget();
|
||||
|
||||
@override
|
||||
Target webServiceWorker(FileSystem fileSystem, List<WebCompilerConfig> compileConfigs) =>
|
||||
WebServiceWorker(fileSystem, compileConfigs);
|
||||
Target webServiceWorker(
|
||||
FileSystem fileSystem,
|
||||
List<WebCompilerConfig> compileConfigs,
|
||||
Analytics analytics,
|
||||
) => WebServiceWorker(fileSystem, compileConfigs, analytics);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ class WebBuilder {
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
try {
|
||||
final BuildResult result = await _buildSystem.build(
|
||||
globals.buildTargets.webServiceWorker(_fileSystem, compilerConfigs),
|
||||
globals.buildTargets.webServiceWorker(_fileSystem, compilerConfigs, _analytics),
|
||||
Environment(
|
||||
projectDir: flutterProject.directory,
|
||||
outputDir: outputDirectory,
|
||||
|
||||
@ -53,7 +53,7 @@ dependencies:
|
||||
http_multi_server: 3.2.2
|
||||
convert: 3.1.2
|
||||
async: 2.13.0
|
||||
unified_analytics: 8.0.2
|
||||
unified_analytics: 8.0.5
|
||||
pubspec_parse: 1.5.0
|
||||
|
||||
graphs: 2.3.2
|
||||
@ -126,4 +126,4 @@ dev_dependencies:
|
||||
dartdoc:
|
||||
# Exclude this package from the hosted API docs.
|
||||
nodoc: true
|
||||
# PUBSPEC CHECKSUM: 36e76b
|
||||
# PUBSPEC CHECKSUM: kr614i
|
||||
|
||||
@ -17,6 +17,7 @@ import 'package:flutter_tools/src/isolated/mustache_template.dart';
|
||||
import 'package:flutter_tools/src/web/compile.dart';
|
||||
import 'package:flutter_tools/src/web/file_generators/flutter_service_worker_js.dart';
|
||||
import 'package:flutter_tools/src/web_template.dart';
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/fake_process_manager.dart';
|
||||
@ -133,7 +134,9 @@ name: foo
|
||||
final Directory webResources = environment.projectDir.childDirectory('web');
|
||||
webResources.childFile('index.html').createSync(recursive: true);
|
||||
environment.buildDir.childFile('main.dart.js').createSync();
|
||||
await WebReleaseBundle(<WebCompilerConfig>[const JsCompilerConfig()]).build(environment);
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('version.json'), exists);
|
||||
}),
|
||||
@ -148,7 +151,9 @@ name: foo
|
||||
final Directory webResources = environment.projectDir.childDirectory('web');
|
||||
webResources.childFile('index.html').createSync(recursive: true);
|
||||
environment.buildDir.childFile('main.dart.js').createSync();
|
||||
await WebReleaseBundle(<WebCompilerConfig>[const JsCompilerConfig()]).build(environment);
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
final String versionFile = environment.outputDir.childFile('version.json').readAsStringSync();
|
||||
expect(versionFile, contains('"version":"2.0.0"'));
|
||||
@ -265,7 +270,7 @@ name: foo
|
||||
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const JsCompilerConfig(dumpInfo: true),
|
||||
]).build(environment);
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('foo.txt').readAsStringSync(), 'A');
|
||||
expect(environment.outputDir.childFile('main.dart.js').existsSync(), true);
|
||||
@ -284,7 +289,9 @@ name: foo
|
||||
// Update to arbitrary resource file triggers rebuild.
|
||||
webResources.childFile('foo.txt').writeAsStringSync('B');
|
||||
|
||||
await WebReleaseBundle(<WebCompilerConfig>[const JsCompilerConfig()]).build(environment);
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('foo.txt').readAsStringSync(), 'B');
|
||||
}),
|
||||
@ -304,7 +311,9 @@ name: foo
|
||||
environment.buildDir.childFile('main.dart.mjs')
|
||||
..createSync()
|
||||
..writeAsStringSync('old mjs');
|
||||
await WebReleaseBundle(<WebCompilerConfig>[const WasmCompilerConfig()]).build(environment);
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const WasmCompilerConfig(),
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
expect(environment.outputDir.childFile('main.dart.wasm').readAsStringSync(), 'old wasm');
|
||||
expect(environment.outputDir.childFile('main.dart.mjs').readAsStringSync(), 'old mjs');
|
||||
|
||||
@ -315,7 +324,9 @@ name: foo
|
||||
..createSync()
|
||||
..writeAsStringSync('new mjs');
|
||||
|
||||
await WebReleaseBundle(<WebCompilerConfig>[const WasmCompilerConfig()]).build(environment);
|
||||
await WebReleaseBundle(<WebCompilerConfig>[
|
||||
const WasmCompilerConfig(),
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('main.dart.wasm').readAsStringSync(), 'new wasm');
|
||||
expect(environment.outputDir.childFile('main.dart.mjs').readAsStringSync(), 'new mjs');
|
||||
@ -1198,6 +1209,7 @@ name: foo
|
||||
sourceMaps: sourceMaps,
|
||||
minify: minify,
|
||||
),
|
||||
const NoOpAnalytics(),
|
||||
).build(environment);
|
||||
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
@ -1267,7 +1279,7 @@ name: foo
|
||||
];
|
||||
|
||||
final Iterable<String> buildKeys = testConfigs.map((WasmCompilerConfig config) {
|
||||
final Dart2WasmTarget target = Dart2WasmTarget(config);
|
||||
final Dart2WasmTarget target = Dart2WasmTarget(config, const NoOpAnalytics());
|
||||
return target.buildKey;
|
||||
});
|
||||
|
||||
@ -1404,7 +1416,7 @@ name: foo
|
||||
..writeAsStringSync('A');
|
||||
await WebServiceWorker(globals.fs, <WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
]).build(environment);
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('flutter_service_worker.js'), exists);
|
||||
// Contains file hash.
|
||||
@ -1435,7 +1447,7 @@ name: foo
|
||||
..writeAsStringSync('A');
|
||||
await WebServiceWorker(globals.fs, <WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
]).build(environment);
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
expect(environment.outputDir.childFile('flutter_service_worker.js'), exists);
|
||||
// Contains the same file hash for both `/` and the root index.html file.
|
||||
@ -1464,7 +1476,7 @@ name: foo
|
||||
environment.outputDir.childFile('main.dart.js.map').createSync(recursive: true);
|
||||
await WebServiceWorker(globals.fs, <WebCompilerConfig>[
|
||||
const JsCompilerConfig(),
|
||||
]).build(environment);
|
||||
], const NoOpAnalytics()).build(environment);
|
||||
|
||||
// No caching of source maps.
|
||||
expect(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user