Add support for flutter build web --debug
. (#157186)
There have been various requests for this for a while. See https://github.com/flutter/flutter/issues/96283 for an example. This has become more important with dart2wasm builds in the mix, as the profiling versions of the dart2wasm builds are a lot less debuggable than the debug versions. Most of this is already wired up so it just requires taking out a few explicit checks for it and making sure that we compile with the right optimization levels when compiling debug.
This commit is contained in:
parent
3512745071
commit
e19d352fc9
@ -28,7 +28,7 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
usesPubOption();
|
||||
usesBuildNumberOption();
|
||||
usesBuildNameOption();
|
||||
addBuildModeFlags(verboseHelp: verboseHelp, excludeDebug: true);
|
||||
addBuildModeFlags(verboseHelp: verboseHelp);
|
||||
usesDartDefineOption();
|
||||
addEnableExperimentation(hide: !verboseHelp);
|
||||
addNullSafetyModeOptions(hide: !verboseHelp);
|
||||
@ -62,7 +62,6 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
abbr: 'O',
|
||||
help:
|
||||
'Sets the optimization level used for Dart compilation to JavaScript/Wasm.',
|
||||
defaultsTo: '${WebCompilerConfig.kDefaultOptimizationLevel}',
|
||||
allowed: const <String>['0', '1', '2', '3', '4'],
|
||||
);
|
||||
argParser.addFlag(
|
||||
@ -134,10 +133,11 @@ 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? optimizationLevelArg = stringArg('optimization-level');
|
||||
final int? optimizationLevel = optimizationLevelArg != null ? int.parse(optimizationLevelArg) : null;
|
||||
|
||||
final String? dart2jsOptimizationLevelValue = stringArg('dart2js-optimization');
|
||||
final int jsOptimizationLevel = dart2jsOptimizationLevelValue != null
|
||||
final int? jsOptimizationLevel = dart2jsOptimizationLevelValue != null
|
||||
? int.parse(dart2jsOptimizationLevelValue.substring(1))
|
||||
: optimizationLevel;
|
||||
|
||||
@ -191,9 +191,6 @@ class BuildWebCommand extends BuildSubCommand {
|
||||
|
||||
final String target = stringArg('target')!;
|
||||
final BuildInfo buildInfo = await getBuildInfo();
|
||||
if (buildInfo.isDebug) {
|
||||
throwToolExit('debug builds cannot be built directly for the web. Try using "flutter run"');
|
||||
}
|
||||
final String? baseHref = stringArg('base-href');
|
||||
if (baseHref != null && !(baseHref.startsWith('/') && baseHref.endsWith('/'))) {
|
||||
throwToolExit(
|
||||
|
@ -13,22 +13,29 @@ enum CompileTarget {
|
||||
|
||||
sealed class WebCompilerConfig {
|
||||
const WebCompilerConfig({required this.renderer,
|
||||
required this.optimizationLevel,
|
||||
this.optimizationLevel,
|
||||
required this.sourceMaps});
|
||||
|
||||
/// The default optimization level for dart2js/dart2wasm.
|
||||
static const int kDefaultOptimizationLevel = 4;
|
||||
|
||||
/// Build environment flag for [optimizationLevel].
|
||||
static const String kOptimizationLevel = 'OptimizationLevel';
|
||||
|
||||
/// Build environment flag for [sourceMaps].
|
||||
static const String kSourceMapsEnabled = 'SourceMaps';
|
||||
|
||||
/// The compiler optimization level.
|
||||
/// Calculates the optimization level for dart2js/dart2wasm for the given
|
||||
/// build mode.
|
||||
int optimizationLevelForBuildMode(BuildMode mode) =>
|
||||
optimizationLevel ?? switch (mode) {
|
||||
BuildMode.debug => 0,
|
||||
BuildMode.profile || BuildMode.release => 4,
|
||||
BuildMode.jitRelease => throw ArgumentError('Invalid build mode for web'),
|
||||
};
|
||||
|
||||
/// The compiler optimization level specified by the user.
|
||||
///
|
||||
/// Valid values are O0 (lowest, debug default) to O4 (highest, release default).
|
||||
final int optimizationLevel;
|
||||
/// If the value is null, the user hasn't specified an optimization level and an
|
||||
/// appropriate default for the build mode will be used instead.
|
||||
final int? optimizationLevel;
|
||||
|
||||
/// `true` if the compiler build should output source maps.
|
||||
final bool sourceMaps;
|
||||
@ -40,7 +47,7 @@ sealed class WebCompilerConfig {
|
||||
String get buildKey;
|
||||
|
||||
Map<String, Object> get buildEventAnalyticsValues => <String, Object>{
|
||||
'optimizationLevel': optimizationLevel,
|
||||
if (optimizationLevel != null) 'optimizationLevel': optimizationLevel!,
|
||||
};
|
||||
|
||||
|
||||
@ -56,7 +63,7 @@ class JsCompilerConfig extends WebCompilerConfig {
|
||||
this.csp = false,
|
||||
this.dumpInfo = false,
|
||||
this.nativeNullAssertions = false,
|
||||
super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel,
|
||||
super.optimizationLevel,
|
||||
this.noFrequencyBasedMinification = false,
|
||||
super.sourceMaps = true,
|
||||
super.renderer = WebRendererMode.defaultForJs,
|
||||
@ -68,7 +75,6 @@ class JsCompilerConfig extends WebCompilerConfig {
|
||||
required WebRendererMode renderer,
|
||||
}) : this(
|
||||
nativeNullAssertions: nativeNullAssertions,
|
||||
optimizationLevel: WebCompilerConfig.kDefaultOptimizationLevel ,
|
||||
renderer: renderer,
|
||||
);
|
||||
|
||||
@ -108,13 +114,22 @@ class JsCompilerConfig extends WebCompilerConfig {
|
||||
if (buildMode == BuildMode.debug) '--enable-asserts',
|
||||
];
|
||||
|
||||
@override
|
||||
int optimizationLevelForBuildMode(BuildMode mode) {
|
||||
final int level = super.optimizationLevelForBuildMode(mode);
|
||||
|
||||
// dart2js optimization level 0 is not well supported. Use
|
||||
// 1 instead.
|
||||
return level == 0 ? 1 : level;
|
||||
}
|
||||
|
||||
/// Arguments to use in the full JS compile, but not CFE-only.
|
||||
///
|
||||
/// Includes the contents of [toSharedCommandOptions].
|
||||
List<String> toCommandOptions(BuildMode buildMode) => <String>[
|
||||
if (buildMode != BuildMode.release) '--no-minify',
|
||||
...toSharedCommandOptions(buildMode),
|
||||
'-O$optimizationLevel',
|
||||
'-O${optimizationLevelForBuildMode(buildMode)}',
|
||||
if (dumpInfo) '--stage=dump-info-all',
|
||||
if (noFrequencyBasedMinification) '--no-frequency-based-minification',
|
||||
if (csp) '--csp',
|
||||
@ -137,7 +152,7 @@ class JsCompilerConfig extends WebCompilerConfig {
|
||||
/// Configuration for the Wasm compiler.
|
||||
class WasmCompilerConfig extends WebCompilerConfig {
|
||||
const WasmCompilerConfig({
|
||||
super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel,
|
||||
super.optimizationLevel,
|
||||
this.stripWasm = true,
|
||||
super.sourceMaps = true,
|
||||
super.renderer = WebRendererMode.defaultForWasm,
|
||||
@ -155,7 +170,7 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
||||
List<String> toCommandOptions(BuildMode buildMode) {
|
||||
final bool stripSymbols = buildMode == BuildMode.release && stripWasm;
|
||||
return <String>[
|
||||
'-O$optimizationLevel',
|
||||
'-O${optimizationLevelForBuildMode(buildMode)}',
|
||||
'--${stripSymbols ? '' : 'no-'}strip-wasm',
|
||||
if (!sourceMaps) '--no-source-maps',
|
||||
if (buildMode == BuildMode.debug) '--extra-compiler-option=--enable-asserts',
|
||||
|
@ -83,25 +83,6 @@ void main() {
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testUsingContext('Refuses to build a debug build for web', () async {
|
||||
final CommandRunner<void> runner = createTestCommandRunner(BuildCommand(
|
||||
artifacts: artifacts,
|
||||
androidSdk: FakeAndroidSdk(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
processUtils: processUtils,
|
||||
osUtils: FakeOperatingSystemUtils(),
|
||||
));
|
||||
|
||||
expect(() => runner.run(<String>['build', 'web', '--debug', '--no-pub']),
|
||||
throwsA(isA<UsageException>()));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => fakePlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testUsingContext('Refuses to build for web when feature is disabled', () async {
|
||||
final CommandRunner<void> runner = createTestCommandRunner(BuildCommand(
|
||||
artifacts: artifacts,
|
||||
|
@ -909,7 +909,7 @@ void main() {
|
||||
'--no-minify',
|
||||
'--no-source-maps',
|
||||
'--enable-asserts',
|
||||
'-O4',
|
||||
'-O1',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.js').absolute.path,
|
||||
environment.buildDir.childFile('app.dill').absolute.path,
|
||||
|
@ -107,7 +107,7 @@ void main() {
|
||||
label: 'web-compile',
|
||||
parameters: CustomDimensions(
|
||||
buildEventSettings:
|
||||
'optimizationLevel: 4; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
||||
'optimizationLevel: 0; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
||||
|
||||
),
|
||||
),
|
||||
@ -121,7 +121,7 @@ void main() {
|
||||
Event.flutterBuildInfo(
|
||||
label: 'web-compile',
|
||||
buildType: 'web',
|
||||
settings: 'optimizationLevel: 4; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
||||
settings: 'optimizationLevel: 0; web-renderer: skwasm,canvaskit; web-target: wasm,js;',
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user