Open gdurandrexel opened 4 weeks ago
kIsWeb
separates code logic so that you only call web APIs when compiling to web and vice versa. In this case, a stub could work, but checking for kIsWeb
everywhere is quite clunky. Instead, I'd stub out the platform-specific logic and then call those stubs.
When compiling for web, importing dart:io does not cause any problem.
Can you elaborate? Are you using a stub there to avoid the unsupported error?
kIsWeb
is convenient when only a tiny portion of your code is dependent of the platform. Without this I have to create 3 files (stub, io, web) and create a public function for just 3 lines of code in each platform, instead of writing if(kIsWeb) doWebStuff else doIOStuff
. It's cumbersome to implement and maintain. So I wanted to know if there was another way.
If I import dart:io, to use Platform.isAndroid
for instance, this compiles fine for web and I can call the io code conditionally at runtime. If I import web/web is does not compile for io, which prevents to use kIsWeb
to branch platform-specific code as described above. Actually is seems to be more dart:js_interop
that complains, but since web/web imports it, it is basically the same.
So if I ever need to import web/web, I have to go the stub way, which is overkill in my opinion in several instances in my code.
I'm not very familiar with all this: I've just stumbled upon this kind of problem recently. So if you tell me there's no way to import web/web without going the stub way, that's fine.
@srujzs I am having the exact same issue.
Even though my code logic is wrapped around if (kIsWeb)
, just by having the import
import 'package:web/web.dart';
it causes my project to stop compiling to native platform targets.
Just like @gdurandrexel suggested, the solution in this case was to create a stub file and add a conditional import.
import 'package:web_stub.dart'
if (dart.library.js_interop) 'package:web/web.dart';
I would be really nice to have this stub file created inside the package so it doesn't affect native platform targets or maybe just add this info to the package's home page, just in case someone else has the same problem.
Without this I have to create 3 files (stub, io, web) and create a public function for just 3 lines of code in each platform, instead of writing if(kIsWeb) doWebStuff else doIOStuff.
I may be wrong, but I think you only need two stubs - one for the VM and one for web and then just do a conditional like you were thinking of for package:web
:
import 'vm_impl.dart' as impl
if (dart.library.js_interop) 'web_impl.dart';
So if you tell me there's no way to import web/web without going the stub way, that's fine.
Ultimately if you want to avoid creating your own more general stubs and want to still use kIsWeb
, a stub of all of web
is the only remaining solution. The VM will indeed complain you're importing a platform-specific library, because that's what package:web
is.
I would be really nice to have this stub file created inside the package so it doesn't affect native platform targets or maybe just add this info to the package's home page, just in case someone else has the same problem.
It's a good idea to put this in the README or an FAQ. I'm not completely opposed to a stub of web
- it just feels like the wrong solution when you're comparing with the package ecosystem. I also recognize that that opinion adds some onus on users to implement their specific stubs I'm proposing above.
Similar issue: https://github.com/dart-lang/web/issues/55
Yes, you're right, I need only 2 files as you explained. I had come across several examples with another stub file and at that time I was still in my copy/paste phase regarding this new kind of problem.
Yes, a full stub of web/web may work, and I proposed this solution because the code is generated, so it might not be too much work or need too much maintenance (though it may, I have no idea). There would still be the problem of dart:js_interop that surfaces in the API. If we cannot apply the same technique for this package also, then there is no point in creating a stub for web/web I suppose.
If we cannot apply the same technique for this package also, then there is no point in creating a stub for web/web I suppose.
Agreed. We may be able to get away with typedefs, but I'm not sure. We definitely do not want to either do a huge breaking change to web
or stub dart:js_interop
on the VM.
Is there a way to override dart:*
package paths? Similar to passing a path to an overridden package_config.json
.
Is there a way to override
dart:*
package paths? Similar to passing a path to an overriddenpackage_config.json
.
Nope. dart:
libraries are hard-wired. What do you want to override? (Also, this is a bit off-topic)
@kevmoo I mean that we could use it to provide paths to the patched web
and js_interop
packages, if that’s possible.
you can override web
, but js_interop
is baked in.
I have a flutter app that should support mobile and web, but compilation fails when building for mobile with errors such as "Dart library 'dart:js_interop' is not available on this platform.".
In my code I import dart:io and web/web and use kIsWeb to call IO methods or web methods.
When compiling for web, importing dart:io does not cause any problem.
I've read about creating a stub file and importing io or web implementations, but my code is sprinkled with kIsWeb checks with tiny bits of code. Is it really the only way to make this work? How come importing dart:io is fine but web/web is not? Could this package provide a stub so we can write something like this: