mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Allow minification to be toggled for wasm builds (#171211)
Provides extra minification controls for web builds. Updates the existing `--minify` flag to pass its value to both JS and wasm (instead of just JS). Also adds two new flags `--minify-js` and `--minify-wasm` which toggle minification for just one of the web targets. While JS minification has a huge impact on code size, wasm minification has a much smaller effect on the program's size. Since minification can obfuscate useful info (like errors) one may want to turn off minification for wasm but leave it on for JS. The plan is to temporarily use `--no-minify-wasm` for devtools to help debug some exceptions being seen. --------- Co-authored-by: Nate Biggs <natebiggs@google.com>
This commit is contained in:
parent
771b631eae
commit
85486ffffc
@ -99,9 +99,16 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addFlag(
|
||||
'minify',
|
||||
'minify-js',
|
||||
help:
|
||||
'Generate minified output. '
|
||||
'Generate minified output for js. '
|
||||
'If not explicitly set, uses the compilation mode (debug, profile, release).',
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addFlag(
|
||||
'minify-wasm',
|
||||
help:
|
||||
'Generate minified output for wasm. '
|
||||
'If not explicitly set, uses the compilation mode (debug, profile, release).',
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
@ -175,7 +182,8 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
);
|
||||
|
||||
final bool sourceMaps = boolArg('source-maps');
|
||||
final bool? minify = argResults!.wasParsed('minify') ? boolArg('minify') : null;
|
||||
final bool? minifyJs = argResults!.wasParsed('minify-js') ? boolArg('minify-js') : null;
|
||||
final bool? minifyWasm = argResults!.wasParsed('minify-wasm') ? boolArg('minify-wasm') : null;
|
||||
|
||||
final List<WebCompilerConfig> compilerConfigs;
|
||||
|
||||
@ -194,11 +202,12 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
optimizationLevel: optimizationLevel,
|
||||
stripWasm: boolArg('strip-wasm'),
|
||||
sourceMaps: sourceMaps,
|
||||
minify: minifyWasm,
|
||||
),
|
||||
JsCompilerConfig(
|
||||
csp: boolArg('csp'),
|
||||
dumpInfo: boolArg('dump-info'),
|
||||
minify: minify,
|
||||
minify: minifyJs,
|
||||
nativeNullAssertions: boolArg('native-null-assertions'),
|
||||
noFrequencyBasedMinification: boolArg('no-frequency-based-minification'),
|
||||
optimizationLevel: jsOptimizationLevel,
|
||||
@ -210,7 +219,7 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
JsCompilerConfig(
|
||||
csp: boolArg('csp'),
|
||||
dumpInfo: boolArg('dump-info'),
|
||||
minify: minify,
|
||||
minify: minifyJs,
|
||||
nativeNullAssertions: boolArg('native-null-assertions'),
|
||||
noFrequencyBasedMinification: boolArg('no-frequency-based-minification'),
|
||||
optimizationLevel: jsOptimizationLevel,
|
||||
|
||||
@ -146,6 +146,7 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
||||
const WasmCompilerConfig({
|
||||
super.optimizationLevel,
|
||||
this.stripWasm = true,
|
||||
this.minify = true,
|
||||
super.sourceMaps = true,
|
||||
super.renderer = WebRendererMode.defaultForWasm,
|
||||
});
|
||||
@ -156,6 +157,8 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
||||
/// Whether to strip the wasm file of static symbols.
|
||||
final bool stripWasm;
|
||||
|
||||
final bool? minify;
|
||||
|
||||
@override
|
||||
CompileTarget get compileTarget => CompileTarget.wasm;
|
||||
|
||||
@ -179,6 +182,7 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
||||
'-O${optimizationLevelForBuildMode(buildMode)}',
|
||||
'--${stripSymbols ? '' : 'no-'}strip-wasm',
|
||||
if (!sourceMaps) '--no-source-maps',
|
||||
if (minify ?? buildMode == BuildMode.release) '--minify' else '--no-minify',
|
||||
if (buildMode == BuildMode.debug) '--extra-compiler-option=--enable-asserts',
|
||||
];
|
||||
}
|
||||
@ -188,6 +192,7 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
||||
final Map<String, dynamic> settings = <String, dynamic>{
|
||||
...super._buildKeyMap,
|
||||
kStripWasm: stripWasm,
|
||||
'minify': minify,
|
||||
WebCompilerConfig.kSourceMapsEnabled: sourceMaps,
|
||||
};
|
||||
return jsonEncode(settings);
|
||||
|
||||
@ -435,7 +435,7 @@ void main() {
|
||||
);
|
||||
|
||||
testUsingContext(
|
||||
'Defaults to web renderer skwasm mode for wasm when no option is specified',
|
||||
'Defaults to web renderer skwasm mode and minify for wasm when no option is specified',
|
||||
() async {
|
||||
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);
|
||||
final CommandRunner<void> runner = createTestCommandRunner(buildCommand);
|
||||
@ -459,6 +459,123 @@ void main() {
|
||||
expect(configs[0].compileTarget, CompileTarget.wasm);
|
||||
expect(configs[1].renderer, WebRendererMode.canvaskit);
|
||||
expect(configs[1].compileTarget, CompileTarget.js);
|
||||
|
||||
expect(configs[0].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[0].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
testUsingContext(
|
||||
'Passes minify to only wasm when minify-wasm specified',
|
||||
() async {
|
||||
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);
|
||||
final CommandRunner<void> runner = createTestCommandRunner(buildCommand);
|
||||
setupFileSystemForEndToEndTest(fileSystem);
|
||||
await runner.run(<String>['build', 'web', '--no-pub', '--wasm', '--minify-wasm']);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Platform: () => fakePlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
ProcessManager: () => processManager,
|
||||
BuildSystem:
|
||||
() => TestBuildSystem.all(BuildResult(success: true), (
|
||||
Target target,
|
||||
Environment environment,
|
||||
) {
|
||||
final List<WebCompilerConfig> configs = (target as WebServiceWorker).compileConfigs;
|
||||
|
||||
expect(configs[0].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[0].toCommandOptions(BuildMode.debug), contains('--minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
testUsingContext(
|
||||
'Passes no-minify to wasm when no-minify-wasm specified',
|
||||
() async {
|
||||
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);
|
||||
final CommandRunner<void> runner = createTestCommandRunner(buildCommand);
|
||||
setupFileSystemForEndToEndTest(fileSystem);
|
||||
await runner.run(<String>['build', 'web', '--no-pub', '--wasm', '--no-minify-wasm']);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Platform: () => fakePlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
ProcessManager: () => processManager,
|
||||
BuildSystem:
|
||||
() => TestBuildSystem.all(BuildResult(success: true), (
|
||||
Target target,
|
||||
Environment environment,
|
||||
) {
|
||||
final List<WebCompilerConfig> configs = (target as WebServiceWorker).compileConfigs;
|
||||
|
||||
expect(configs[0].toCommandOptions(BuildMode.release), contains('--no-minify'));
|
||||
expect(configs[0].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
testUsingContext(
|
||||
'Passes minify to js when minify-js specified',
|
||||
() async {
|
||||
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);
|
||||
final CommandRunner<void> runner = createTestCommandRunner(buildCommand);
|
||||
setupFileSystemForEndToEndTest(fileSystem);
|
||||
await runner.run(<String>['build', 'web', '--no-pub', '--wasm', '--minify-js']);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Platform: () => fakePlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
ProcessManager: () => processManager,
|
||||
BuildSystem:
|
||||
() => TestBuildSystem.all(BuildResult(success: true), (
|
||||
Target target,
|
||||
Environment environment,
|
||||
) {
|
||||
final List<WebCompilerConfig> configs = (target as WebServiceWorker).compileConfigs;
|
||||
|
||||
expect(configs[0].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[0].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.debug), contains('--minify'));
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
testUsingContext(
|
||||
'Passes no-minify to js when no-minify-js specified',
|
||||
() async {
|
||||
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);
|
||||
final CommandRunner<void> runner = createTestCommandRunner(buildCommand);
|
||||
setupFileSystemForEndToEndTest(fileSystem);
|
||||
await runner.run(<String>['build', 'web', '--no-pub', '--wasm', '--no-minify-js']);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Platform: () => fakePlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
ProcessManager: () => processManager,
|
||||
BuildSystem:
|
||||
() => TestBuildSystem.all(BuildResult(success: true), (
|
||||
Target target,
|
||||
Environment environment,
|
||||
) {
|
||||
final List<WebCompilerConfig> configs = (target as WebServiceWorker).compileConfigs;
|
||||
|
||||
expect(configs[0].toCommandOptions(BuildMode.release), contains('--minify'));
|
||||
expect(configs[0].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.release), contains('--no-minify'));
|
||||
expect(configs[1].toCommandOptions(BuildMode.debug), contains('--no-minify'));
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
@ -1138,75 +1138,82 @@ name: foo
|
||||
]) {
|
||||
for (final String buildMode in const <String>['profile', 'release', 'debug']) {
|
||||
for (final bool sourceMaps in const <bool>[true, false]) {
|
||||
test(
|
||||
'Dart2WasmTarget invokes dart2wasm with renderer=$renderer, -O$level, stripping=$strip, defines=$defines, modeMode=$buildMode sourceMaps=$sourceMaps',
|
||||
() => testbed.run(() async {
|
||||
final int expectedLevel =
|
||||
level ??
|
||||
switch (buildMode) {
|
||||
'debug' => 0,
|
||||
'profile' || 'release' => 2,
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
environment.defines[kBuildMode] = buildMode;
|
||||
environment.defines[kDartDefines] = encodeDartDefines(defines);
|
||||
for (final bool minify in const <bool>[true, false]) {
|
||||
test(
|
||||
'Dart2WasmTarget invokes dart2wasm with renderer=$renderer, -O$level, stripping=$strip, defines=$defines, modeMode=$buildMode sourceMaps=$sourceMaps minify=$minify',
|
||||
() => testbed.run(() async {
|
||||
final int expectedLevel =
|
||||
level ??
|
||||
switch (buildMode) {
|
||||
'debug' => 0,
|
||||
'profile' || 'release' => 2,
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
environment.defines[kBuildMode] = buildMode;
|
||||
environment.defines[kDartDefines] = encodeDartDefines(defines);
|
||||
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(
|
||||
FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
'-Ddart.vm.profile=${buildMode == 'profile'}',
|
||||
'-Ddart.vm.product=${buildMode == 'release'}',
|
||||
if (buildMode != 'debug') ...<String>[
|
||||
'--extra-compiler-option=--delete-tostring-package-uri=dart:ui',
|
||||
'--extra-compiler-option=--delete-tostring-package-uri=package:flutter',
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(
|
||||
FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
'-Ddart.vm.profile=${buildMode == 'profile'}',
|
||||
'-Ddart.vm.product=${buildMode == 'release'}',
|
||||
if (buildMode != 'debug') ...<String>[
|
||||
'--extra-compiler-option=--delete-tostring-package-uri=dart:ui',
|
||||
'--extra-compiler-option=--delete-tostring-package-uri=package:flutter',
|
||||
],
|
||||
if (renderer == WebRendererMode.skwasm) ...<String>[
|
||||
'--extra-compiler-option=--import-shared-memory',
|
||||
'--extra-compiler-option=--shared-memory-max-pages=32768',
|
||||
],
|
||||
...defines.map((String define) => '-D$define'),
|
||||
if (renderer == WebRendererMode.skwasm) ...<String>[
|
||||
'-DFLUTTER_WEB_USE_SKIA=false',
|
||||
'-DFLUTTER_WEB_USE_SKWASM=true',
|
||||
],
|
||||
if (renderer == WebRendererMode.canvaskit) ...<String>[
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'-DFLUTTER_WEB_USE_SKWASM=false',
|
||||
],
|
||||
'-DFLUTTER_WEB_CANVASKIT_URL=https://www.gstatic.com/flutter-canvaskit/abcdefghijklmnopqrstuvwxyz/',
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O$expectedLevel',
|
||||
if (strip && buildMode == 'release')
|
||||
'--strip-wasm'
|
||||
else
|
||||
'--no-strip-wasm',
|
||||
if (!sourceMaps) '--no-source-maps',
|
||||
if (minify) '--minify' else '--no-minify',
|
||||
if (buildMode == 'debug') '--extra-compiler-option=--enable-asserts',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
],
|
||||
if (renderer == WebRendererMode.skwasm) ...<String>[
|
||||
'--extra-compiler-option=--import-shared-memory',
|
||||
'--extra-compiler-option=--shared-memory-max-pages=32768',
|
||||
],
|
||||
...defines.map((String define) => '-D$define'),
|
||||
if (renderer == WebRendererMode.skwasm) ...<String>[
|
||||
'-DFLUTTER_WEB_USE_SKIA=false',
|
||||
'-DFLUTTER_WEB_USE_SKWASM=true',
|
||||
],
|
||||
if (renderer == WebRendererMode.canvaskit) ...<String>[
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'-DFLUTTER_WEB_USE_SKWASM=false',
|
||||
],
|
||||
'-DFLUTTER_WEB_CANVASKIT_URL=https://www.gstatic.com/flutter-canvaskit/abcdefghijklmnopqrstuvwxyz/',
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O$expectedLevel',
|
||||
if (strip && buildMode == 'release') '--strip-wasm' else '--no-strip-wasm',
|
||||
if (!sourceMaps) '--no-source-maps',
|
||||
if (buildMode == 'debug') '--extra-compiler-option=--enable-asserts',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
],
|
||||
onRun:
|
||||
(_) =>
|
||||
outputJsFile
|
||||
..createSync()
|
||||
..writeAsStringSync('foo'),
|
||||
),
|
||||
);
|
||||
onRun:
|
||||
(_) =>
|
||||
outputJsFile
|
||||
..createSync()
|
||||
..writeAsStringSync('foo'),
|
||||
),
|
||||
);
|
||||
|
||||
await Dart2WasmTarget(
|
||||
WasmCompilerConfig(
|
||||
optimizationLevel: level,
|
||||
stripWasm: strip,
|
||||
renderer: renderer,
|
||||
sourceMaps: sourceMaps,
|
||||
),
|
||||
).build(environment);
|
||||
await Dart2WasmTarget(
|
||||
WasmCompilerConfig(
|
||||
optimizationLevel: level,
|
||||
stripWasm: strip,
|
||||
renderer: renderer,
|
||||
sourceMaps: sourceMaps,
|
||||
minify: minify,
|
||||
),
|
||||
).build(environment);
|
||||
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
}, overrides: <Type, Generator>{ProcessManager: () => processManager}),
|
||||
);
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
}, overrides: <Type, Generator>{ProcessManager: () => processManager}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1257,6 +1264,7 @@ name: foo
|
||||
WasmCompilerConfig(optimizationLevel: 0),
|
||||
WasmCompilerConfig(renderer: WebRendererMode.canvaskit),
|
||||
WasmCompilerConfig(stripWasm: false),
|
||||
WasmCompilerConfig(minify: false),
|
||||
|
||||
// All properties non-default
|
||||
WasmCompilerConfig(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user