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();
|
usesPubOption();
|
||||||
usesBuildNumberOption();
|
usesBuildNumberOption();
|
||||||
usesBuildNameOption();
|
usesBuildNameOption();
|
||||||
addBuildModeFlags(verboseHelp: verboseHelp, excludeDebug: true);
|
addBuildModeFlags(verboseHelp: verboseHelp);
|
||||||
usesDartDefineOption();
|
usesDartDefineOption();
|
||||||
addEnableExperimentation(hide: !verboseHelp);
|
addEnableExperimentation(hide: !verboseHelp);
|
||||||
addNullSafetyModeOptions(hide: !verboseHelp);
|
addNullSafetyModeOptions(hide: !verboseHelp);
|
||||||
@ -62,7 +62,6 @@ class BuildWebCommand extends BuildSubCommand {
|
|||||||
abbr: 'O',
|
abbr: 'O',
|
||||||
help:
|
help:
|
||||||
'Sets the optimization level used for Dart compilation to JavaScript/Wasm.',
|
'Sets the optimization level used for Dart compilation to JavaScript/Wasm.',
|
||||||
defaultsTo: '${WebCompilerConfig.kDefaultOptimizationLevel}',
|
|
||||||
allowed: const <String>['0', '1', '2', '3', '4'],
|
allowed: const <String>['0', '1', '2', '3', '4'],
|
||||||
);
|
);
|
||||||
argParser.addFlag(
|
argParser.addFlag(
|
||||||
@ -134,10 +133,11 @@ class BuildWebCommand extends BuildSubCommand {
|
|||||||
throwToolExit('"build web" is not currently supported. To enable, run "flutter config --enable-web".');
|
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 String? dart2jsOptimizationLevelValue = stringArg('dart2js-optimization');
|
||||||
final int jsOptimizationLevel = dart2jsOptimizationLevelValue != null
|
final int? jsOptimizationLevel = dart2jsOptimizationLevelValue != null
|
||||||
? int.parse(dart2jsOptimizationLevelValue.substring(1))
|
? int.parse(dart2jsOptimizationLevelValue.substring(1))
|
||||||
: optimizationLevel;
|
: optimizationLevel;
|
||||||
|
|
||||||
@ -191,9 +191,6 @@ class BuildWebCommand extends BuildSubCommand {
|
|||||||
|
|
||||||
final String target = stringArg('target')!;
|
final String target = stringArg('target')!;
|
||||||
final BuildInfo buildInfo = await getBuildInfo();
|
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');
|
final String? baseHref = stringArg('base-href');
|
||||||
if (baseHref != null && !(baseHref.startsWith('/') && baseHref.endsWith('/'))) {
|
if (baseHref != null && !(baseHref.startsWith('/') && baseHref.endsWith('/'))) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
|
@ -13,22 +13,29 @@ enum CompileTarget {
|
|||||||
|
|
||||||
sealed class WebCompilerConfig {
|
sealed class WebCompilerConfig {
|
||||||
const WebCompilerConfig({required this.renderer,
|
const WebCompilerConfig({required this.renderer,
|
||||||
required this.optimizationLevel,
|
this.optimizationLevel,
|
||||||
required this.sourceMaps});
|
required this.sourceMaps});
|
||||||
|
|
||||||
/// The default optimization level for dart2js/dart2wasm.
|
|
||||||
static const int kDefaultOptimizationLevel = 4;
|
|
||||||
|
|
||||||
/// Build environment flag for [optimizationLevel].
|
/// Build environment flag for [optimizationLevel].
|
||||||
static const String kOptimizationLevel = 'OptimizationLevel';
|
static const String kOptimizationLevel = 'OptimizationLevel';
|
||||||
|
|
||||||
/// Build environment flag for [sourceMaps].
|
/// Build environment flag for [sourceMaps].
|
||||||
static const String kSourceMapsEnabled = '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).
|
/// 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.
|
/// `true` if the compiler build should output source maps.
|
||||||
final bool sourceMaps;
|
final bool sourceMaps;
|
||||||
@ -40,7 +47,7 @@ sealed class WebCompilerConfig {
|
|||||||
String get buildKey;
|
String get buildKey;
|
||||||
|
|
||||||
Map<String, Object> get buildEventAnalyticsValues => <String, Object>{
|
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.csp = false,
|
||||||
this.dumpInfo = false,
|
this.dumpInfo = false,
|
||||||
this.nativeNullAssertions = false,
|
this.nativeNullAssertions = false,
|
||||||
super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel,
|
super.optimizationLevel,
|
||||||
this.noFrequencyBasedMinification = false,
|
this.noFrequencyBasedMinification = false,
|
||||||
super.sourceMaps = true,
|
super.sourceMaps = true,
|
||||||
super.renderer = WebRendererMode.defaultForJs,
|
super.renderer = WebRendererMode.defaultForJs,
|
||||||
@ -68,7 +75,6 @@ class JsCompilerConfig extends WebCompilerConfig {
|
|||||||
required WebRendererMode renderer,
|
required WebRendererMode renderer,
|
||||||
}) : this(
|
}) : this(
|
||||||
nativeNullAssertions: nativeNullAssertions,
|
nativeNullAssertions: nativeNullAssertions,
|
||||||
optimizationLevel: WebCompilerConfig.kDefaultOptimizationLevel ,
|
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -108,13 +114,22 @@ class JsCompilerConfig extends WebCompilerConfig {
|
|||||||
if (buildMode == BuildMode.debug) '--enable-asserts',
|
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.
|
/// Arguments to use in the full JS compile, but not CFE-only.
|
||||||
///
|
///
|
||||||
/// Includes the contents of [toSharedCommandOptions].
|
/// Includes the contents of [toSharedCommandOptions].
|
||||||
List<String> toCommandOptions(BuildMode buildMode) => <String>[
|
List<String> toCommandOptions(BuildMode buildMode) => <String>[
|
||||||
if (buildMode != BuildMode.release) '--no-minify',
|
if (buildMode != BuildMode.release) '--no-minify',
|
||||||
...toSharedCommandOptions(buildMode),
|
...toSharedCommandOptions(buildMode),
|
||||||
'-O$optimizationLevel',
|
'-O${optimizationLevelForBuildMode(buildMode)}',
|
||||||
if (dumpInfo) '--stage=dump-info-all',
|
if (dumpInfo) '--stage=dump-info-all',
|
||||||
if (noFrequencyBasedMinification) '--no-frequency-based-minification',
|
if (noFrequencyBasedMinification) '--no-frequency-based-minification',
|
||||||
if (csp) '--csp',
|
if (csp) '--csp',
|
||||||
@ -137,7 +152,7 @@ class JsCompilerConfig extends WebCompilerConfig {
|
|||||||
/// Configuration for the Wasm compiler.
|
/// Configuration for the Wasm compiler.
|
||||||
class WasmCompilerConfig extends WebCompilerConfig {
|
class WasmCompilerConfig extends WebCompilerConfig {
|
||||||
const WasmCompilerConfig({
|
const WasmCompilerConfig({
|
||||||
super.optimizationLevel = WebCompilerConfig.kDefaultOptimizationLevel,
|
super.optimizationLevel,
|
||||||
this.stripWasm = true,
|
this.stripWasm = true,
|
||||||
super.sourceMaps = true,
|
super.sourceMaps = true,
|
||||||
super.renderer = WebRendererMode.defaultForWasm,
|
super.renderer = WebRendererMode.defaultForWasm,
|
||||||
@ -155,7 +170,7 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
|||||||
List<String> toCommandOptions(BuildMode buildMode) {
|
List<String> toCommandOptions(BuildMode buildMode) {
|
||||||
final bool stripSymbols = buildMode == BuildMode.release && stripWasm;
|
final bool stripSymbols = buildMode == BuildMode.release && stripWasm;
|
||||||
return <String>[
|
return <String>[
|
||||||
'-O$optimizationLevel',
|
'-O${optimizationLevelForBuildMode(buildMode)}',
|
||||||
'--${stripSymbols ? '' : 'no-'}strip-wasm',
|
'--${stripSymbols ? '' : 'no-'}strip-wasm',
|
||||||
if (!sourceMaps) '--no-source-maps',
|
if (!sourceMaps) '--no-source-maps',
|
||||||
if (buildMode == BuildMode.debug) '--extra-compiler-option=--enable-asserts',
|
if (buildMode == BuildMode.debug) '--extra-compiler-option=--enable-asserts',
|
||||||
|
@ -83,25 +83,6 @@ void main() {
|
|||||||
ProcessManager: () => processManager,
|
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 {
|
testUsingContext('Refuses to build for web when feature is disabled', () async {
|
||||||
final CommandRunner<void> runner = createTestCommandRunner(BuildCommand(
|
final CommandRunner<void> runner = createTestCommandRunner(BuildCommand(
|
||||||
artifacts: artifacts,
|
artifacts: artifacts,
|
||||||
|
@ -909,7 +909,7 @@ void main() {
|
|||||||
'--no-minify',
|
'--no-minify',
|
||||||
'--no-source-maps',
|
'--no-source-maps',
|
||||||
'--enable-asserts',
|
'--enable-asserts',
|
||||||
'-O4',
|
'-O1',
|
||||||
'-o',
|
'-o',
|
||||||
environment.buildDir.childFile('main.dart.js').absolute.path,
|
environment.buildDir.childFile('main.dart.js').absolute.path,
|
||||||
environment.buildDir.childFile('app.dill').absolute.path,
|
environment.buildDir.childFile('app.dill').absolute.path,
|
||||||
|
@ -107,7 +107,7 @@ void main() {
|
|||||||
label: 'web-compile',
|
label: 'web-compile',
|
||||||
parameters: CustomDimensions(
|
parameters: CustomDimensions(
|
||||||
buildEventSettings:
|
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(
|
Event.flutterBuildInfo(
|
||||||
label: 'web-compile',
|
label: 'web-compile',
|
||||||
buildType: 'web',
|
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