Closed josh-burton closed 1 day ago
hey, I see that this is for wasm compilation but I don't think we support symbolication for wasm yet
This is blocking some customers. Happy to discuss how we can help!
Attention: Patch coverage is 97.05882%
with 4 lines
in your changes missing coverage. Please review.
Project coverage is 88.64%. Comparing base (
e6b16cd
) to head (80a0e2b
). Report is 21 commits behind head on main.:exclamation: Current head 80a0e2b differs from pull request most recent head 2bf4b4f
Please upload reports for the commit 2bf4b4f to get more accurate results.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
quick fyi: the ci jobsentry-sqflite / analyze / package-analysis
currently fails expectedly so no need to try and fix this here
@denrase @buenaflor I've addressed the PR comments and hopefully fixed the build failures.
I needed to bump the min version of Flutter has Dart 3.1.0 is required by package:web.
@josh-burton if it's okay with you we'd like to fork your branch and take over from here, it's easier for us to fix the rest of the ci since we don't need to approve runnning them every time (cc @denrase)
@josh-burton if it's okay with you we'd like to fork your branch and take over from here, it's easier for us to fix the rest of the ci since we don't need to approve runnning them every time (cc @denrase)
No problem, go for it.
Any help we can get here?
hey we've been looking into it. The main problem we have is the necessity to bump the min versions. as far as I can see we would need to bump it to dart 3.3.0 and flutter 3.19.0 which is pretty much a huge jump for us
Any recommendations to alleviate that?
@buenaflor
need to bump it to dart 3.3.0 and flutter 3.19.0 which is pretty much a huge jump for us Any recommendations to alleviate that?
We cannot simply bump to versions that are only a few months old, we want to avoid that even in a new major release. A large part of our customers are not on dart 3.3.0 and flutter 3.19 yet (which are very close to the latest versions) and we don't plan on maintaining two majors for an extended period of time.
@kevmoo do you have guidance here if we have any other option available other than bumping the min versions?
@buenaflor – this is a tricky spot.
If you want to maintain backward compat, you could test for the existence of dart:js_interop
– see https://dart.dev/guides/libraries/create-packages#conditionally-importing-and-exporting-library-files
I worry that you'll get folks importing this library before it's stable on versions before Dart 3.3 – but it might be work investigating
@kevmoo We do this, however this does not preclude us from adding the web package to our dependencies, which automatically raises the dart min SDK version to 3.3. Or am I missing something here?
@vaind idea might work. I worry about the fact that dart:js_interop
was in Dart 3.2 – just not "stable" - https://api.dart.dev/stable/3.2.1/index.html
So we might be in the same spot!
we have a poc for moving the web package implementations to another package called sentry_web
which then inside the dart library we import it conditionally
import '../../web/noop_window.dart'
if (dart.library.html) '../../web/http_window.dart'
if (dart.library.js_interop) '../../web/web_window.dart';
inside a user's application if they wanna be able to build for wasm:
import 'package:sentry_web/sentry_web.dart' as sentry_web;
// set the window in SentryFlutter.init
options.window = sentry_web.SentryWeb.createWindow;
as far as testing goes it looks fine, doesn't break backwards compat on lower dart versions (🤞).
might be a wrong direction though, it was only briefly tested
we have a poc for moving the web package implementations to another package called
sentry_web
which then inside the dart library we import it conditionally
import '../../web/noop_window.dart' if (dart.library.html) '../../web/http_window.dart' if (dart.library.js_interop) '../../web/web_window.dart';
inside a user's application if they wanna be able to build for wasm:
import 'package:sentry_web/sentry_web.dart' as sentry_web; // set the window in SentryFlutter.init options.window = sentry_web.SentryWeb.createWindow;
as far as testing goes it looks fine, doesn't break backwards compat on lower dart versions (🤞).
might be a wrong direction though, it was only briefly tested
Great. That sounds like the best approach. Should I close this PR?
we have a poc for moving the web package implementations to another package called
sentry_web
which then inside the dart library we import it conditionally
import '../../web/noop_window.dart' if (dart.library.html) '../../web/http_window.dart' if (dart.library.js_interop) '../../web/web_window.dart';
inside a user's application if they wanna be able to build for wasm:
import 'package:sentry_web/sentry_web.dart' as sentry_web; // set the window in SentryFlutter.init options.window = sentry_web.SentryWeb.createWindow;
as far as testing goes it looks fine, doesn't break backwards compat on lower dart versions (🤞).
might be a wrong direction though, it was only briefly tested
Having custom code for one platform is not ideal because then people need to know they need to change this, i.e. there need to be docs and they have to notice it in the docs.
Just to double check: has anyone tried if my proposals actually work or did we just assume they won't? Because in that case I would give it a try myself.
Having custom code for one platform is not ideal because then people need to know they need to change this, i.e. there need to be docs and they have to notice it in the docs.
We've already decided that we won't bump the versions not matter what for this use case so this solution is the "worst" case scenario if we can't manage anything more simpler.
Just to double check: has anyone tried if my proposals actually work or did we just assume they won't? Because in that case I would give it a try myself.
The approach is very similar to the poc. I'm only confused about the removal of the web package since we have to use a specific property of that package (window) so I'm not sure how it's possible to leave it out.
I'm only confused about the removal of the web package since we have to use a specific property of that package (window) so I'm not sure how it's possible to leave it out.
AFAIU it will work because the consumer app depends on the web package. If it doesn't then our code doesn't use it anyway (it should be tree-shaken/trimmed)
let me check this out in a new PR
@kevmoo, @srujzs, and I were brainstorming a bit here to see what other alternative we could offer from a Dart perspective, and we landed on either branching (having 2 versions of the package under maintenance) or practically what @buenaflor suggested above (2 versions of the web-specific code, one based on dart:html
, the other on dart:js_interop
, but a package version.)
There are a lot of caveats to keep in mind:
dart.library.html
to go first. Technically that will keep all JavaScript clients on the old logic for a lot longer (until you are ready to bump this package's SDK constraint and directly use package:web
). However, I'm inclined to go in that direction because of the risks of inconsistent behavior with using dart:js_interop
depending on the SDK version. If you have a solution that works across all SDK versions consistently, then by all means put dart.library.js_interop
first.dart:js_interop
breaking changes: dart:js_interop
has existed since Dart 3.1.0 and has gone through several breaking changes until it graduated as a stable library in Dart 3.3.0. If it's possible to make the logic consistent across all versions of dart:js_interop
, then great! If not, I believe putting it second in the import order may be good enough. That's because dart2wasm
only reached stable in Dart 3.4, so we should expect some consistency to follow from the fact that users are likely only using the newer versions of the SDK. extension types
were only added in Dart 3.3, which is what we default to use now for JS-interop APIs. To use dart:js_interop
without a min-SDK constraint, you will likely need to use older forms of interop. This may be to use @staticInterop
or rely on the more primitive parts of the API (like dart:js_interop_unsafe
).package:web
: I think this is OK to do, but I wouldn't rely on that dependency existing on user's package. Instead, I would suggest you simply don't use the package altogether. The good news is that all of package:web
is written using dart:js_interop
, so it is possible to access directly the browser APIs you need using only the Dart/JS interop layer (e.g. use JS() external JSObject get window;
to expose window directly, if you need it)Hope this is helpful.
@kevmoo, @srujzs, and I were brainstorming a bit here to see what other alternative we could offer from a Dart perspective, and we landed on either branching (having 2 versions of the package under maintenance) or practically what @buenaflor suggested above (2 versions of the web-specific code, one based on
dart:html
, the other ondart:js_interop
, but a package version.)There are a lot of caveats to keep in mind:
- Import order: the order of the conditional imports matters, I'd recommend
dart.library.html
to go first. Technically that will keep all JavaScript clients on the old logic for a lot longer (until you are ready to bump this package's SDK constraint and directly usepackage:web
). However, I'm inclined to go in that direction because of the risks of inconsistent behavior with usingdart:js_interop
depending on the SDK version. If you have a solution that works across all SDK versions consistently, then by all means putdart.library.js_interop
first.- _
dart:js_interop
breaking changes_:dart:js_interop
has existed since Dart 3.1.0 and has gone through several breaking changes until it graduated as a stable library in Dart 3.3.0. If it's possible to make the logic consistent across all versions ofdart:js_interop
, then great! If not, I believe putting it second in the import order may be good enough. That's becausedart2wasm
only reached stable in Dart 3.4, so we should expect some consistency to follow from the fact that users are likely only using the newer versions of the SDK.- no extension types: Note that
extension types
were only added in Dart 3.3, which is what we default to use now for JS-interop APIs. To usedart:js_interop
without a min-SDK constraint, you will likely need to use older forms of interop. This may be to use@staticInterop
or rely on the more primitive parts of the API (likedart:js_interop_unsafe
).- dropping
package:web
: I think this is OK to do, but I wouldn't rely on that dependency existing on user's package. Instead, I would suggest you simply don't use the package altogether. The good news is that all ofpackage:web
is written usingdart:js_interop
, so it is possible to access directly the browser APIs you need using only the Dart/JS interop layer (e.g. useJS() external JSObject get window;
to expose window directly, if you need it)Hope this is helpful.
Thanks for inputs. I was able to make this work today by dropping the import & using conditional imports (i.e. what I've suggested above). See followup PR https://github.com/getsentry/sentry-dart/pull/2113 - with a little bit of fiddling it seems to work fine in my tests and I don't think it would break anyone currently using the SDK while also enabling people to start using WASM (once we update stack trace parsing & implement offline symbolication for wasm - #1480)
Import order: the order of the conditional imports matters, I'd recommend
dart.library.html
to go first
that's right, that's exactly what I did
- _
dart:js_interop
breaking changes_:dart:js_interop
has existed since Dart 3.1.0 and has gone through several breaking changes until it graduated as a stable library in Dart 3.3.0
I'm testing on Dart 3.3+ with the new package:web
dependency and it seems to work for me.
:scroll: Description
Migrates to package:web and js_interop
:bulb: Motivation and Context
Supports compilation via WASM
:green_heart: How did you test it?
Tested on a flutter web app project, ran unit tests
:pencil: Checklist
sendDefaultPii
is enabled:crystal_ball: Next steps
Version numbers should be bumped. I think technically this is not a breaking change, but perhaps it should be treated as one.