From 259373d62bf2f3e512181a2fee284df18d103242 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 22 Nov 2022 15:57:25 -0800 Subject: [PATCH] [flutter_tools] Add --dump-info, --no-frequency-based-minification flags (#115862) * [flutter_tools] Add --dump-info, --no-frequency-based-minification flags Also some cleanup to named arguments to the buildWeb function Fixes https://github.com/flutter/flutter/issues/115854 * fix tests --- .../lib/src/build_system/targets/web.dart | 10 +++ .../lib/src/commands/build_web.dart | 14 +++- .../lib/src/isolated/resident_web_runner.dart | 5 +- .../flutter_tools/lib/src/web/compile.dart | 12 ++-- .../hermetic/build_web_test.dart | 4 ++ .../build_system/targets/web_test.dart | 68 +++++++++++++++++++ 6 files changed, 103 insertions(+), 10 deletions(-) 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 a72213a1a16..5f116c740d9 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/web.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart @@ -36,6 +36,12 @@ const String kHasWebPlugins = 'HasWebPlugins'; /// Valid values are O1 (lowest, profile default) to O4 (highest, release default). const String kDart2jsOptimization = 'Dart2jsOptimization'; +/// If `--dump-info` should be passed to dart2js. +const String kDart2jsDumpInfo = 'Dart2jsDumpInfo'; + +// If `--no-frequency-based-minification` should be based to dart2js +const String kDart2jsNoFrequencyBasedMinification = 'Dart2jsNoFrequencyBasedMinification'; + /// Whether to disable dynamic generation code to satisfy csp policies. const String kCspMode = 'cspMode'; @@ -217,6 +223,8 @@ class Dart2JSTarget extends Target { } final String? dart2jsOptimization = environment.defines[kDart2jsOptimization]; + final bool dumpInfo = environment.defines[kDart2jsDumpInfo] == 'true'; + final bool noFrequencyBasedMinification = environment.defines[kDart2jsNoFrequencyBasedMinification] == 'true'; final File outputJSFile = environment.buildDir.childFile('main.dart.js'); final bool csp = environment.defines[kCspMode] == 'true'; @@ -224,6 +232,8 @@ class Dart2JSTarget extends Target { ...sharedCommandOptions, if (dart2jsOptimization != null) '-$dart2jsOptimization' else '-O4', if (buildMode == BuildMode.profile) '--no-minify', + if (dumpInfo) '--dump-info', + if (noFrequencyBasedMinification) '--no-frequency-based-minification', if (csp) '--csp', '-o', outputJSFile.path, diff --git a/packages/flutter_tools/lib/src/commands/build_web.dart b/packages/flutter_tools/lib/src/commands/build_web.dart index 1c5ad38da70..e30c6253482 100644 --- a/packages/flutter_tools/lib/src/commands/build_web.dart +++ b/packages/flutter_tools/lib/src/commands/build_web.dart @@ -70,6 +70,14 @@ class BuildWebCommand extends BuildSubCommand { help: 'Sets the optimization level used for Dart compilation to JavaScript. ' 'Valid values range from O0 to O4.' ); + argParser.addFlag('dump-info', negatable: false, + help: 'Passes "--dump-info" to the Javascript compiler which generates ' + 'information about the generated code is a .js.info.json file.' + ); + argParser.addFlag('no-frequency-based-minification', negatable: false, + help: 'Disables the frequency based minifier. ' + 'Useful for comparing the output between builds.' + ); } final FileSystem _fileSystem; @@ -132,9 +140,11 @@ class BuildWebCommand extends BuildSubCommand { stringArgDeprecated('pwa-strategy')!, boolArgDeprecated('source-maps'), boolArgDeprecated('native-null-assertions'), - baseHref, - stringArgDeprecated('dart2js-optimization'), + baseHref: baseHref, + dart2jsOptimization: stringArgDeprecated('dart2js-optimization'), outputDirectoryPath: outputDirectoryPath, + dumpInfo: boolArgDeprecated('dump-info'), + noFrequencyBasedMinification: boolArgDeprecated('no-frequency-based-minification'), ); return FlutterCommandResult.success(); } diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart index e8bb48dad88..55a9a7bb2c2 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -298,8 +298,6 @@ class ResidentWebRunner extends ResidentRunner { kNoneWorker, true, debuggingOptions.nativeNullAssertions, - null, - null, ); } await device!.device!.startApp( @@ -372,8 +370,7 @@ class ResidentWebRunner extends ResidentRunner { kNoneWorker, true, debuggingOptions.nativeNullAssertions, - kBaseHref, - null, + baseHref: kBaseHref, ); } on ToolExit { return OperationResult(1, 'Failed to recompile application.'); diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index 8d093c5732d..63106d92798 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -25,11 +25,13 @@ Future buildWeb( bool csp, String serviceWorkerStrategy, bool sourceMaps, - bool nativeNullAssertions, - String? baseHref, + bool nativeNullAssertions, { String? dart2jsOptimization, - {String? outputDirectoryPath} -) async { + String? baseHref, + bool dumpInfo = false, + bool noFrequencyBasedMinification = false, + String? outputDirectoryPath, +}) async { final bool hasWebPlugins = (await findPlugins(flutterProject)) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); final Directory outputDirectory = outputDirectoryPath == null @@ -66,6 +68,8 @@ Future buildWeb( kServiceWorkerStrategy: serviceWorkerStrategy, if (dart2jsOptimization != null) kDart2jsOptimization: dart2jsOptimization, + kDart2jsDumpInfo: dumpInfo.toString(), + kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(), ...buildInfo.toBuildSystemEnvironment(), }, artifacts: globals.artifacts!, 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 23d17e0d7cb..4573319542f 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 @@ -130,6 +130,8 @@ void main() { 'SourceMaps': 'false', 'NativeNullAssertions': 'true', 'ServiceWorkerStrategy': 'offline-first', + 'Dart2jsDumpInfo': 'false', + 'Dart2jsNoFrequencyBasedMinification': 'false', 'Dart2jsOptimization': 'O3', 'BuildMode': 'release', 'DartDefines': 'Zm9vPWE=,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==', @@ -179,6 +181,8 @@ void main() { 'SourceMaps': 'false', 'NativeNullAssertions': 'true', 'ServiceWorkerStrategy': 'offline-first', + 'Dart2jsDumpInfo': 'false', + 'Dart2jsNoFrequencyBasedMinification': 'false', 'BuildMode': 'release', 'DartDefines': 'RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==', 'DartObfuscation': 'false', 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 ac54d6c0186..45f3d9d94ce 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 @@ -659,6 +659,74 @@ void main() { ProcessManager: () => processManager, })); + test('Dart2JSTarget calls dart2js with expected args with dump-info', () => testbed.run(() async { + environment.defines[kBuildMode] = 'profile'; + environment.defines[kDart2jsDumpInfo] = 'true'; + processManager.addCommand(FakeCommand( + command: [ + ...kDart2jsLinuxArgs, + '-Ddart.vm.profile=true', + '--no-source-maps', + '-o', + environment.buildDir.childFile('app.dill').absolute.path, + '--packages=.dart_tool/package_config.json', + '--cfe-only', + environment.buildDir.childFile('main.dart').absolute.path, + ] + )); + processManager.addCommand(FakeCommand( + command: [ + ...kDart2jsLinuxArgs, + '-Ddart.vm.profile=true', + '--no-source-maps', + '-O4', + '--no-minify', + '--dump-info', + '-o', + environment.buildDir.childFile('main.dart.js').absolute.path, + environment.buildDir.childFile('app.dill').absolute.path, + ] + )); + + await const Dart2JSTarget().build(environment); + }, overrides: { + ProcessManager: () => processManager, + })); + + test('Dart2JSTarget calls dart2js with expected args with no-frequency-based-minification', () => testbed.run(() async { + environment.defines[kBuildMode] = 'profile'; + environment.defines[kDart2jsNoFrequencyBasedMinification] = 'true'; + processManager.addCommand(FakeCommand( + command: [ + ...kDart2jsLinuxArgs, + '-Ddart.vm.profile=true', + '--no-source-maps', + '-o', + environment.buildDir.childFile('app.dill').absolute.path, + '--packages=.dart_tool/package_config.json', + '--cfe-only', + environment.buildDir.childFile('main.dart').absolute.path, + ] + )); + processManager.addCommand(FakeCommand( + command: [ + ...kDart2jsLinuxArgs, + '-Ddart.vm.profile=true', + '--no-source-maps', + '-O4', + '--no-minify', + '--no-frequency-based-minification', + '-o', + environment.buildDir.childFile('main.dart.js').absolute.path, + environment.buildDir.childFile('app.dill').absolute.path, + ] + )); + + await const Dart2JSTarget().build(environment); + }, overrides: { + ProcessManager: () => processManager, + })); + test('Generated service worker is empty with none-strategy', () { final String result = generateServiceWorker({'/foo': 'abcd'}, [], serviceWorkerStrategy: ServiceWorkerStrategy.none);