2

I use more than one dart main file in my lib folder for passing different app configuration depending on server each will use.

Example of main_dev.dart

void main() async {
  FlavorConfig(
    flavorName: 'test',
    values: {
      'BASE_URL': 'http://$MY_IP:9002/graphql',
      'WS_URL': 'ws://$MY_IP:9002/graphql',
    },
  );

  await runApp(ProviderApp());
}

For now I have main_test.dart and main_live.dart and everything works fine when building android app.

Example I use the following command to build test app.

flutter build apk --obfuscate --split-debug-info=./build/app/outputs/symbols lib/main_test.dart

Note the last part lib/main_test.dart I specify which file I intend to use and it works really well for building android app.

But I tried similar thing for web and I get the following error as it seems to me building web app needs main.dart.

Target dart2js failed: Exception: .dart_tool/flutter_build/11c1feed0a867bb072ab6c7b64967a31/main.dart:8:8: Error: Error when reading 'lib/main.dart': Error reading 'lib/main.dart' (The system cannot find the file specified. ) import 'package:my_amazing_app/main.dart' as entrypoint; ^ .dart_tool/flutter_build/11c1feed0a867bb072ab6c7b64967a31/main.dart:13:3: Error: Method not found: 'main'. entrypoint.main(); ^^^^ Error: Compilation failed.

Compiling lib\main.dart for the Web...
20.3s Exception: Failed to compile application for the Web.

How can can specify the file I want in command for web too?.

I have tried the following without success flutter build web lib/main_test.dart

Nux
  • 5,890
  • 13
  • 48
  • 74
  • 1
    [Flutter web as of yet doesn't support flavors,](https://github.com/flutter/flutter/issues/59388) so the workaround seems to be to use Firebase build targets. Personally, I'd just use [environment variables](https://stackoverflow.com/questions/44250184/setting-environment-variables-in-flutter). – Abion47 Jun 25 '21 at 22:52

1 Answers1

2

Rather than using different entrypoints, you can use compile-time constants. When running flutter build, you can pass in --dart-define=foo=bar to set a compile-time constant, and you can then use it from your code using:

const foo = String.fromEnvironment('foo');
print(foo);  // prints "bar"

const fooExists = bool.hasEnvironment('foo');
print(fooExists);  // prints "true"

Note that this is a const value, so the compiler can still use this information for tree shaking.

In your case, assuming you have 2 environments: prod and test, you could do something like this:

// lib/main.dart

void main() {
  const env = String.fromEnvironment('env');
  if (env == 'test') {
    runApp(TestApp());
  } else if (env == 'prod') {
    runApp(ProdApp());
  } else {
    throw 'unknown environment: $env';
  }
}

Then when you build your app, you can use:

flutter build web --dart-define=env=prod <other-args>
cameron1024
  • 9,083
  • 2
  • 16
  • 36