diff --git a/dev/devicelab/lib/tasks/web_benchmarks.dart b/dev/devicelab/lib/tasks/web_benchmarks.dart index 031d478fcfab..b08fa4111356 100644 --- a/dev/devicelab/lib/tasks/web_benchmarks.dart +++ b/dev/devicelab/lib/tasks/web_benchmarks.dart @@ -34,9 +34,9 @@ Future runWebBenchmark(WebBenchmarkOptions benchmarkOptions) async { await evalFlutter('build', options: [ 'web', if (benchmarkOptions.useWasm) ...[ + '--O4', '--wasm', - '--wasm-opt=debug', - '--omit-type-checks', + '--no-strip-wasm', ], '--dart-define=FLUTTER_WEB_ENABLE_PROFILING=true', if (!benchmarkOptions.useWasm) '--web-renderer=${benchmarkOptions.webRenderer}', diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart index a5d0022bc910..7f705ece1612 100644 --- a/packages/flutter_tools/lib/src/artifacts.dart +++ b/packages/flutter_tools/lib/src/artifacts.dart @@ -44,8 +44,6 @@ enum Artifact { dart2jsSnapshot, /// The dart snapshot of the dart2wasm compiler. dart2wasmSnapshot, - /// The wasm-opt binary that ships with the dart-sdk - wasmOptBinary, /// The root of the Linux desktop sources. linuxDesktopPath, @@ -194,8 +192,6 @@ String? _artifactToFileName(Artifact artifact, Platform hostPlatform, [ BuildMod return 'dart2js.dart.snapshot'; case Artifact.dart2wasmSnapshot: return 'dart2wasm_product.snapshot'; - case Artifact.wasmOptBinary: - return 'wasm-opt$exe'; case Artifact.frontendServerSnapshotForEngineDartSdk: return 'frontend_server_aot.dart.snapshot'; case Artifact.linuxDesktopPath: @@ -566,7 +562,6 @@ class CachedArtifacts implements Artifacts { case Artifact.engineDartAotRuntime: case Artifact.dart2jsSnapshot: case Artifact.dart2wasmSnapshot: - case Artifact.wasmOptBinary: case Artifact.frontendServerSnapshotForEngineDartSdk: case Artifact.constFinder: case Artifact.flutterFramework: @@ -608,7 +603,6 @@ class CachedArtifacts implements Artifacts { case Artifact.engineDartAotRuntime: case Artifact.dart2jsSnapshot: case Artifact.dart2wasmSnapshot: - case Artifact.wasmOptBinary: case Artifact.frontendServerSnapshotForEngineDartSdk: case Artifact.constFinder: case Artifact.flutterMacOSFramework: @@ -668,7 +662,6 @@ class CachedArtifacts implements Artifacts { case Artifact.engineDartAotRuntime: case Artifact.dart2jsSnapshot: case Artifact.dart2wasmSnapshot: - case Artifact.wasmOptBinary: case Artifact.frontendServerSnapshotForEngineDartSdk: case Artifact.icuData: case Artifact.isolateSnapshotData: @@ -708,11 +701,6 @@ class CachedArtifacts implements Artifacts { _dartSdkPath(_cache), 'bin', 'snapshots', _artifactToFileName(artifact, _platform), ); - case Artifact.wasmOptBinary: - return _fileSystem.path.join( - _dartSdkPath(_cache), 'bin', 'utils', - _artifactToFileName(artifact, _platform), - ); case Artifact.flutterTester: case Artifact.vmSnapshotData: case Artifact.isolateSnapshotData: @@ -1039,8 +1027,6 @@ class CachedLocalEngineArtifacts implements Artifacts { case Artifact.dart2wasmSnapshot: case Artifact.frontendServerSnapshotForEngineDartSdk: return _fileSystem.path.join(_getDartSdkPath(), 'bin', 'snapshots', artifactFileName); - case Artifact.wasmOptBinary: - return _fileSystem.path.join(_getDartSdkPath(), 'bin', 'utils', artifactFileName); case Artifact.flutterToolsFileGenerators: return _getFileGeneratorsPath(); case Artifact.flutterPreviewDevice: @@ -1178,11 +1164,6 @@ class CachedLocalWebSdkArtifacts implements Artifacts { _getDartSdkPath(), 'bin', 'snapshots', _artifactToFileName(artifact, _platform, mode), ); - case Artifact.wasmOptBinary: - return _fileSystem.path.join( - _getDartSdkPath(), 'bin', 'utils', - _artifactToFileName(artifact, _platform, mode), - ); case Artifact.genSnapshot: case Artifact.flutterTester: case Artifact.flutterFramework: diff --git a/packages/flutter_tools/lib/src/commands/build_web.dart b/packages/flutter_tools/lib/src/commands/build_web.dart index 7be2209167ce..1242aa753b05 100644 --- a/packages/flutter_tools/lib/src/commands/build_web.dart +++ b/packages/flutter_tools/lib/src/commands/build_web.dart @@ -55,6 +55,18 @@ class BuildWebCommand extends BuildSubCommand { usesWebRendererOption(); usesWebResourcesCdnFlag(); + // + // Common compilation options among JavaScript and Wasm + // + argParser.addOption( + 'optimization-level', + abbr: 'O', + help: + 'Sets the optimization level used for Dart compilation to JavaScript/Wasm.', + defaultsTo: '${WebCompilerConfig.kDefaultOptimizationLevel}', + allowed: const ['1', '2', '3', '4'], + ); + // // JavaScript compilation options // @@ -72,10 +84,9 @@ class BuildWebCommand extends BuildSubCommand { ); argParser.addOption('dart2js-optimization', help: 'Sets the optimization level used for Dart compilation to JavaScript. ' - 'Valid values range from O1 to O4.', - defaultsTo: JsCompilerConfig.kDart2jsDefaultOptimizationLevel, - allowed: const ['O1', 'O2', 'O3', 'O4'], - ); + 'Deprecated: Please use "-O=" / "--optimization-level=".', + allowed: const ['O1', 'O2', 'O3', '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.' @@ -98,19 +109,9 @@ class BuildWebCommand extends BuildSubCommand { hide: !featureFlags.isFlutterWebWasmEnabled, ); argParser.addFlag( - 'omit-type-checks', - help: 'Omit type checks in Wasm output.\n' - 'Reduces code size and improves performance, but may affect runtime correctness. Use with care.', - negatable: false, - hide: !featureFlags.isFlutterWebWasmEnabled, - ); - argParser.addOption( - 'wasm-opt', - help: - 'Optimize output wasm using the Binaryen (https://github.com/WebAssembly/binaryen) tool.', - defaultsTo: WasmOptLevel.defaultValue.cliName, - allowed: WasmOptLevel.values.map((WasmOptLevel e) => e.cliName), - allowedHelp: CliEnum.allowedHelp(WasmOptLevel.values), + 'strip-wasm', + help: 'Whether to strip the resulting wasm file of static symbol names.', + defaultsTo: true, hide: !featureFlags.isFlutterWebWasmEnabled, ); } @@ -138,6 +139,13 @@ class BuildWebCommand extends BuildSubCommand { throwToolExit('"build web" is not currently supported. To enable, run "flutter config --enable-web".'); } + final int optimizationLevel = int.parse(stringArg('optimization-level')!); + + final String? dart2jsOptimizationLevelValue = stringArg('dart2js-optimization'); + final int jsOptimizationLevel = dart2jsOptimizationLevelValue != null + ? int.parse(dart2jsOptimizationLevelValue.substring(1)) + : optimizationLevel; + final List compilerConfigs; if (boolArg('wasm')) { if (!featureFlags.isFlutterWebWasmEnabled) { @@ -155,13 +163,13 @@ class BuildWebCommand extends BuildSubCommand { compilerConfigs = [ WasmCompilerConfig( - omitTypeChecks: boolArg('omit-type-checks'), - wasmOpt: WasmOptLevel.values.byName(stringArg('wasm-opt')!), + optimizationLevel: optimizationLevel, + stripWasm: boolArg('strip-wasm'), renderer: WebRendererMode.skwasm, ), JsCompilerConfig( csp: boolArg('csp'), - optimizationLevel: stringArg('dart2js-optimization') ?? JsCompilerConfig.kDart2jsDefaultOptimizationLevel, + optimizationLevel: jsOptimizationLevel, dumpInfo: boolArg('dump-info'), nativeNullAssertions: boolArg('native-null-assertions'), noFrequencyBasedMinification: boolArg('no-frequency-based-minification'), @@ -175,7 +183,7 @@ class BuildWebCommand extends BuildSubCommand { } compilerConfigs = [JsCompilerConfig( csp: boolArg('csp'), - optimizationLevel: stringArg('dart2js-optimization') ?? JsCompilerConfig.kDart2jsDefaultOptimizationLevel, + optimizationLevel: jsOptimizationLevel, dumpInfo: boolArg('dump-info'), nativeNullAssertions: boolArg('native-null-assertions'), noFrequencyBasedMinification: boolArg('no-frequency-based-minification'), diff --git a/packages/flutter_tools/lib/src/web/compiler_config.dart b/packages/flutter_tools/lib/src/web/compiler_config.dart index f2a3ca52dbfa..d99f4357d81e 100644 --- a/packages/flutter_tools/lib/src/web/compiler_config.dart +++ b/packages/flutter_tools/lib/src/web/compiler_config.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '../base/utils.dart'; import '../convert.dart'; import 'compile.dart'; @@ -12,7 +11,18 @@ enum CompileTarget { } sealed class WebCompilerConfig { - const WebCompilerConfig({required this.renderer}); + const WebCompilerConfig({required this.renderer, required this.optimizationLevel}); + + /// The default optimization level for dart2js/dart2wasm. + static const int kDefaultOptimizationLevel = 4; + + /// Build environment flag for [optimizationLevel]. + static const String kOptimizationLevel = 'OptimizationLevel'; + + /// The compiler optimization level. + /// + /// Valid values are O1 (lowest, profile default) to O4 (highest, release default). + final int optimizationLevel; /// Returns which target this compiler outputs (js or wasm) CompileTarget get compileTarget; @@ -20,7 +30,14 @@ sealed class WebCompilerConfig { String get buildKey; - Map get buildEventAnalyticsValues => {}; + Map get buildEventAnalyticsValues => { + 'optimizationLevel': optimizationLevel, + }; + + + Map get _buildKeyMap => { + 'optimizationLevel': optimizationLevel, + }; } /// Configuration for the Dart-to-Javascript compiler (dart2js). @@ -29,7 +46,7 @@ class JsCompilerConfig extends WebCompilerConfig { this.csp = false, this.dumpInfo = false, this.nativeNullAssertions = false, - this.optimizationLevel = kDart2jsDefaultOptimizationLevel, + super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel, this.noFrequencyBasedMinification = false, this.sourceMaps = true, super.renderer = WebRendererMode.auto, @@ -41,18 +58,10 @@ class JsCompilerConfig extends WebCompilerConfig { required WebRendererMode renderer, }) : this( nativeNullAssertions: nativeNullAssertions, - optimizationLevel: kDart2jsDefaultOptimizationLevel, + optimizationLevel: WebCompilerConfig.kDefaultOptimizationLevel , renderer: renderer, ); - /// The default optimization level for dart2js. - /// - /// Maps to [kDart2jsOptimization]. - static const String kDart2jsDefaultOptimizationLevel = 'O4'; - - /// Build environment flag for [optimizationLevel]. - static const String kDart2jsOptimization = 'Dart2jsOptimization'; - /// Build environment flag for [dumpInfo]. static const String kDart2jsDumpInfo = 'Dart2jsDumpInfo'; @@ -82,12 +91,6 @@ class JsCompilerConfig extends WebCompilerConfig { // TODO(kevmoo): consider renaming this to be "positive". Double negatives are confusing. final bool noFrequencyBasedMinification; - /// The compiler optimization level. - /// - /// Valid values are O1 (lowest, profile default) to O4 (highest, release default). - // TODO(kevmoo): consider storing this as an [int] and validating it! - final String optimizationLevel; - /// `true` if the JavaScript compiler build should output source maps. final bool sourceMaps; @@ -105,7 +108,7 @@ class JsCompilerConfig extends WebCompilerConfig { /// Includes the contents of [toSharedCommandOptions]. List toCommandOptions() => [ ...toSharedCommandOptions(), - '-$optimizationLevel', + '-O$optimizationLevel', if (dumpInfo) '--dump-info', if (noFrequencyBasedMinification) '--no-frequency-based-minification', if (csp) '--csp', @@ -114,11 +117,11 @@ class JsCompilerConfig extends WebCompilerConfig { @override String get buildKey { final Map settings = { + ...super._buildKeyMap, 'csp': csp, 'dumpInfo': dumpInfo, 'nativeNullAssertions': nativeNullAssertions, 'noFrequencyBasedMinification': noFrequencyBasedMinification, - 'optimizationLevel': optimizationLevel, 'sourceMaps': sourceMaps, }; return jsonEncode(settings); @@ -128,79 +131,33 @@ class JsCompilerConfig extends WebCompilerConfig { /// Configuration for the Wasm compiler. class WasmCompilerConfig extends WebCompilerConfig { const WasmCompilerConfig({ - this.omitTypeChecks = false, - this.wasmOpt = WasmOptLevel.defaultValue, + super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel, + this.stripWasm = true, super.renderer = WebRendererMode.auto, }); - /// Build environment for [omitTypeChecks]. - static const String kOmitTypeChecks = 'WasmOmitTypeChecks'; - - /// Build environment for [wasmOpt]. - static const String kRunWasmOpt = 'RunWasmOpt'; - - /// If `omit-type-checks` should be passed to `dart2wasm`. - final bool omitTypeChecks; + /// Build environment for [stripWasm]. + static const String kStripWasm = 'StripWasm'; - /// Run wasm-opt on the resulting module. - final WasmOptLevel wasmOpt; + /// Whether to strip the wasm file of static symbols. + final bool stripWasm; @override CompileTarget get compileTarget => CompileTarget.wasm; List toCommandOptions() { - // -O1: Optimizes - // -O2: Same as -O1 but also minifies (still semantics preserving) - // -O3: Same as -O2 but also omits implicit type checks. - // -O4: Same as -O3 but also omits explicit type checks. - // (NOTE: This differs from dart2js -O4 semantics atm.) - - // Ortogonal: The name section is always kept by default and we emit it only - // in [WasmOptLevel.full] mode (similar to `--strip` of static symbols in - // AOT mode). - final String level = !omitTypeChecks ? '-O2' : '-O4'; - return switch (wasmOpt) { - WasmOptLevel.none => ['-O0'], - WasmOptLevel.debug => [level, '--no-minify'], - WasmOptLevel.full => [level, '--no-name-section'], - }; + return [ + '-O$optimizationLevel', + '--${stripWasm? 'no-' : ''}name-section', + ]; } - @override - Map get buildEventAnalyticsValues => { - ...super.buildEventAnalyticsValues, - kOmitTypeChecks: omitTypeChecks.toString(), - kRunWasmOpt: wasmOpt.name, - }; - @override String get buildKey { final Map settings = { - 'omitTypeChecks': omitTypeChecks, - 'wasmOpt': wasmOpt.name, + ...super._buildKeyMap, + 'stripWasm': stripWasm, }; return jsonEncode(settings); } - -} - -enum WasmOptLevel implements CliEnum { - full, - debug, - none; - - static const WasmOptLevel defaultValue = WasmOptLevel.full; - - @override - String get cliName => name; - - @override - String get helpText => switch (this) { - WasmOptLevel.none => - 'wasm-opt is not run. Fastest build; bigger, slower output.', - WasmOptLevel.debug => - 'Similar to `${WasmOptLevel.full.name}`, but member names are preserved. Debugging is easier, but size is a bit bigger.', - WasmOptLevel.full => - 'wasm-opt is run. Build time is slower, but output is smaller and faster.', - }; } diff --git a/packages/flutter_tools/test/general.shard/artifacts_test.dart b/packages/flutter_tools/test/general.shard/artifacts_test.dart index bb0915c25ddd..5d174c6433a2 100644 --- a/packages/flutter_tools/test/general.shard/artifacts_test.dart +++ b/packages/flutter_tools/test/general.shard/artifacts_test.dart @@ -427,13 +427,6 @@ void main() { fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk', 'bin', 'snapshots', 'dart2js.dart.snapshot'), ); - expect( - artifacts.getArtifactPath( - Artifact.wasmOptBinary, - platform: TargetPlatform.web_javascript), - fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk', - 'bin', 'utils', 'wasm-opt'), - ); }); testWithoutContext('getEngineType', () { 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 4059abc3443b..3fb3c81e5a6f 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 @@ -615,7 +615,6 @@ void main() { test('Dart2JSTarget calls dart2js with expected args in release with dart2js optimization override', () => testbed.run(() async { environment.defines[kBuildMode] = 'release'; - environment.defines[JsCompilerConfig.kDart2jsOptimization] = 'O3'; processManager.addCommand(FakeCommand( command: [ ..._kDart2jsLinuxArgs, @@ -644,7 +643,7 @@ void main() { await Dart2JSTarget( const JsCompilerConfig( - optimizationLevel: 'O3', + optimizationLevel: 3, sourceMaps: false, ) ).build(environment); @@ -901,176 +900,61 @@ void main() { ProcessManager: () => processManager, })); - test('Dart2WasmTarget invokes dart2wasm with dart defines', () => testbed.run(() async { - environment.defines[kBuildMode] = 'profile'; - environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name; - environment.defines[kDartDefines] = encodeDartDefines(['FOO=bar', 'BAZ=qux']); - - final File depFile = environment.buildDir.childFile('dart2wasm.d'); - - final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); - processManager.addCommand(FakeCommand( - command: [ - ..._kDart2WasmLinuxArgs, - '-Ddart.vm.profile=true', - '-DFOO=bar', - '-DBAZ=qux', - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=true', - '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O2', - '--no-name-section', - '-o', - environment.buildDir.childFile('main.dart.wasm').absolute.path, - environment.buildDir.childFile('main.dart').absolute.path, - ], - onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')) - ); - - await Dart2WasmTarget( - const WasmCompilerConfig( - renderer: WebRendererMode.canvaskit - ) - ).build(environment); - - expect(outputJsFile.existsSync(), isTrue); - }, overrides: { - ProcessManager: () => processManager, - })); - - test('Dart2WasmTarget invokes dart2wasm with omit checks', () => testbed.run(() async { - environment.defines[kBuildMode] = 'release'; - environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name; - environment.defines[WasmCompilerConfig.kOmitTypeChecks] = 'true'; - - final File depFile = environment.buildDir.childFile('dart2wasm.d'); - - final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); - processManager.addCommand(FakeCommand( - command: [ - ..._kDart2WasmLinuxArgs, - '-Ddart.vm.product=true', - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=true', - '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O4', - '--no-name-section', - '-o', - environment.buildDir.childFile('main.dart.wasm').absolute.path, - environment.buildDir.childFile('main.dart').absolute.path, - ], - onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')) - ); - - await Dart2WasmTarget( - const WasmCompilerConfig( - omitTypeChecks: true, - renderer: WebRendererMode.canvaskit - ) - ).build(environment); - - expect(outputJsFile.existsSync(), isTrue); - }, overrides: { - ProcessManager: () => processManager, - })); - - test('Dart2WasmTarget invokes dart2wasm and wasm-opt with debug info in wasmopt debug mode', () => testbed.run(() async { - environment.defines[kBuildMode] = 'release'; - environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.debug.name; - - final File depFile = environment.buildDir.childFile('dart2wasm.d'); - - final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); - processManager.addCommand(FakeCommand( - command: [ - ..._kDart2WasmLinuxArgs, - '-Ddart.vm.product=true', - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=true', - '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O2', - '--no-minify', - '-o', - environment.buildDir.childFile('main.dart.wasm').absolute.path, - environment.buildDir.childFile('main.dart').absolute.path, - ], onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))); - - await Dart2WasmTarget( - const WasmCompilerConfig( - wasmOpt: WasmOptLevel.debug, - renderer: WebRendererMode.canvaskit - ) - ).build(environment); - - expect(outputJsFile.existsSync(), isTrue); - }, overrides: { - ProcessManager: () => processManager, - })); - - test('Dart2WasmTarget invokes dart2wasm (but not wasm-opt) with wasm-opt none option', () => testbed.run(() async { - environment.defines[kBuildMode] = 'debug'; - environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.none.name; - - final File depFile = environment.buildDir.childFile('dart2wasm.d'); - - final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); - processManager.addCommand(FakeCommand( - command: [ - ..._kDart2WasmLinuxArgs, - '-Ddart.vm.product=true', - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=true', - '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O0', - '-o', - environment.buildDir.childFile('main.dart.wasm').absolute.path, - environment.buildDir.childFile('main.dart').absolute.path, - ], onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))); - - await Dart2WasmTarget( - const WasmCompilerConfig( - wasmOpt: WasmOptLevel.none, - renderer: WebRendererMode.canvaskit - ) - ).build(environment); - }, overrides: { - ProcessManager: () => processManager, - })); - - test('Dart2WasmTarget with skwasm renderer adds extra flags', () => testbed.run(() async { - environment.defines[kBuildMode] = 'release'; - environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name; - final File depFile = environment.buildDir.childFile('dart2wasm.d'); - - final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); - processManager.addCommand(FakeCommand( - command: [ - ..._kDart2WasmLinuxArgs, - '--extra-compiler-option=--import-shared-memory', - '--extra-compiler-option=--shared-memory-max-pages=32768', - '-Ddart.vm.product=true', - '-DFLUTTER_WEB_AUTO_DETECT=false', - '-DFLUTTER_WEB_USE_SKIA=false', - '-DFLUTTER_WEB_USE_SKWASM=true', - '--extra-compiler-option=--depfile=${depFile.absolute.path}', - '-O2', - '--no-name-section', - '-o', - environment.buildDir.childFile('main.dart.wasm').absolute.path, - environment.buildDir.childFile('main.dart').absolute.path, - ], - onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')) - ); - - - await Dart2WasmTarget( - const WasmCompilerConfig( - renderer: WebRendererMode.skwasm, - ) - ).build(environment); - }, overrides: { - ProcessManager: () => processManager, - })); + for (final WebRendererMode renderer in [WebRendererMode.canvaskit, WebRendererMode.skwasm]) { + for (int level = 1; level <= 4; level++) { + for (final bool strip in [true, false]) { + for (final List defines in const >[[], ['FOO=bar', 'BAZ=qux']]) { + test('Dart2WasmTarget invokes dart2wasm with renderer=$renderer, -O$level, stripping=$strip, defines=$defines', () => testbed.run(() async { + environment.defines[kBuildMode] = 'release'; + environment.defines[kDartDefines] = encodeDartDefines(defines); + + final File depFile = environment.buildDir.childFile('dart2wasm.d'); + + final File outputJsFile = environment.buildDir.childFile('main.dart.mjs'); + processManager.addCommand(FakeCommand( + command: [ + ..._kDart2WasmLinuxArgs, + if (renderer == WebRendererMode.skwasm) ...[ + '--extra-compiler-option=--import-shared-memory', + '--extra-compiler-option=--shared-memory-max-pages=32768', + ], + '-Ddart.vm.product=true', + ...defines.map((String define) => '-D$define'), + if (renderer == WebRendererMode.skwasm) ...[ + '-DFLUTTER_WEB_AUTO_DETECT=false', + '-DFLUTTER_WEB_USE_SKIA=false', + '-DFLUTTER_WEB_USE_SKWASM=true', + ], + if (renderer == WebRendererMode.canvaskit) ...[ + '-DFLUTTER_WEB_AUTO_DETECT=false', + '-DFLUTTER_WEB_USE_SKIA=true', + ], + '--extra-compiler-option=--depfile=${depFile.absolute.path}', + '-O$level', + if (strip) '--no-name-section' else '--name-section', + '-o', + environment.buildDir.childFile('main.dart.wasm').absolute.path, + environment.buildDir.childFile('main.dart').absolute.path, + ], + onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')) + ); + + await Dart2WasmTarget( + WasmCompilerConfig( + optimizationLevel: level, + stripWasm: strip, + renderer: renderer, + ) + ).build(environment); + + expect(outputJsFile.existsSync(), isTrue); + }, overrides: { + ProcessManager: () => processManager, + })); + } + } + } + } test('Generated service worker is empty with none-strategy', () => testbed.run(() { final String fileGeneratorsPath = diff --git a/packages/flutter_tools/test/general.shard/web/compile_web_test.dart b/packages/flutter_tools/test/general.shard/web/compile_web_test.dart index 39a8b12e610e..8aba49542268 100644 --- a/packages/flutter_tools/test/general.shard/web/compile_web_test.dart +++ b/packages/flutter_tools/test/general.shard/web/compile_web_test.dart @@ -74,7 +74,8 @@ void main() { ServiceWorkerStrategy.offlineFirst, compilerConfigs: [ const WasmCompilerConfig( - wasmOpt: WasmOptLevel.none, + optimizationLevel: 0, + stripWasm: false, renderer: WebRendererMode.skwasm, ), const JsCompilerConfig.run( @@ -103,7 +104,8 @@ void main() { label: 'web-compile', parameters: CustomDimensions( buildEventSettings: - 'RunWasmOpt: none; WasmOmitTypeChecks: false; web-renderer: skwasm,canvaskit; web-target: wasm,js;', + 'optimizationLevel: 4; web-renderer: skwasm,canvaskit; web-target: wasm,js;', + ), ), ], @@ -116,7 +118,7 @@ void main() { Event.flutterBuildInfo( label: 'web-compile', buildType: 'web', - settings: 'RunWasmOpt: none; WasmOmitTypeChecks: false; web-renderer: skwasm,canvaskit; web-target: wasm,js;', + settings: 'optimizationLevel: 4; web-renderer: skwasm,canvaskit; web-target: wasm,js;', ), ]), );