
Git — Using Git & Flutter’s conditional import to solve the dart.js cross platform bug.
I recently made changes to a Flutter project to support Azure AD authentication for iOS, Android & the web in that order.
The code worked for each platform, but when I then tried to run the iOS version after completing all the platform integrations, I got this error:
Unhandled exception:
FileSystemException(uri=org-dartlang-untranslatable-uri:dart%3Ajs;
message=StandardFileSystem only supports file:* and data:* URIs)
#0 StandardFileSystem.entityForUri
(package:front_end/src/api_prototype/standard_file_system.dart:34:7)
#1 asFileUri (package:vm/kernel_front_end.dart:659:37)
#2 writeDepfile (package:vm/kernel_front_end.dart:799:21)In this article I’m recording how I used git to turned back time and isolate where this issue was introduced and then fix it.
Starting with the simple option of listing the commits and working backwards reversing them until the issue disappeared:
git log --oneline
Then its just a case of going back 1 commit at a time:
git checkout <commit-id>In this case backing out the “MSAL for the Web” change, by checking out MSAL for Android commit:

git checkout 102f226And bingo the app is working again now the web changes are removed.

If you now do:
git statusYou will notice the branch is detached:
Note: switching to '102f226'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 102f226 MSAL for AndroidI then switched back to the latest code by checking out the branch:
git checkout mainThe next step was to investigate what changed in commit that caused the error:
git show --stat a4ab89a
You can then view the changes for a particular file with this command:
git diff 102f226 a4ab89a pubspec.yaml
Which is good if you want to cover a period i.e. more than 1 commit for a file, but for a single commit I usually use the GUI in the online repository, in this case GitLab:

Eventually there is no substitute for understanding when getting to the bottom of something, other than backing out files.
In my case I can ignore all the files related to change for flutter_native_splash: and for the BDD acceptance tests which left just a few files to look into:

Based on the error about untranslatable dart.js I started by removing changes to a file that added the reference to the js packages: lib/security/service/msal_js_authentication_service.dart 0 → 100644_
import ‘package:msal_js/msal_js.dart’;
And we are back in business!
Fixing it required some research which led me to Flutters condition import ability, details below.
XP
Conditional Imports
You cannot reference anything that loads dart.js if you want to compile your application for iOS, which gives you a multiple platform issue when you need to use it for the web, luckily Flutter supports conditional Imports:
import 'msal_authentication_service.dart'
if (dart.library.js) 'msal_js_authentication_service.dart';Next, declare the same method in both implementations, msal_authentication_service.dart & msal_js_authentication_service.dart:
// Mobile Implementation
AuthenticationService getAuthenticationService() => MsalAuthenticationService();
class MsalAuthenticationService implements AuthenticationService {
// Web Implementation
AuthenticationService getAuthenticationService() => MsalJsAuthenticationService();
class MsalJsAuthenticationService implements AuthenticationService {And use it in code you are writing:
static AuthenticationService get instance {
return getAuthenticationService();
}Be sure to notice that in the implementations the method is outside of the class.
Thx, Randal for the simplification suggestion, original it was more complicated:

Git Time Travel
Stash any changes first as using the git reset — hard option resets the current branch tip, and also deletes any changes in the working directory and staging area.
git reset --hard HEAD@{5.minutes.ago}
// Other periods
HEAD@{1.day.2.hours.ago},
HEAD@{yesterday},
HEAD@{2020-01-01 18:30:00},
HEAD@{12:43}- Only works for your local terminal — your reflog and gitrevisions are stored locally, but aren’t shared when you push to a remote repository
- Only works for committed files — if you’ve deleted uncommitted files, these aren’t stored in Git anywhere. Good reason to commit early and often
Detached Head
detached head state where you can make changes and it will allow you to make commits, but nothing will be saved and any commits you make will be lost. HEAD answers the question, “Where am I right now?” Most of the time, HEAD points to a branch. This is the detached HEAD state; HEAD is pointing directly to a commit instead of a branch. Its good for investigation a bug as you can run the previous version and make changes that will not be saved.

If you want to keep changes made with a detached HEAD, just create a new branch and switch to it. You can create it right after arriving at a detached HEAD or after creating one or more commits. The result is the same.
git branch <branch-name>