apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.59k stars 1.52k forks source link

DevTools cannot display source map properly #1695

Closed nonameShijian closed 2 months ago

nonameShijian commented 2 months ago

Bug Report

Problem

When I use TypeScript compiled JavaScript code in Cordova version 10, the browser console does not display the source map correctly

What is expected to happen?

DevTools displays source map correctly

What does actually happen?

DevTools displays the following content:

DevTools cannot display authored sources, but can debug deployed code. Load URL https://localhost/xxx.js.map: Connection error: net:ERR CONNECTION REFUSED

Information

I used Cordova version 10.0 to create an offline web game, which provides the WebViewAssetLoader class to access local web pages using HTTPS URLs. My project uses the HTTPS protocol and introduces eruda.js And its source map file, but DevTools displays the above error. The other compiled JavaScript files in my project used the "inlineSourceMap" compilation option, and DevTools also displayed the above error. I haven't found a solution to the problem online, but I think it may be related to the WebViewAssetLoader class? I did not reproduce the same issue in my Electron project that started the HTTP server with Express, and I did not encounter this issue in the Egde browser on Windows, only in the Cordova project that used the WebViewAssetLoader class. Similarly, when I changed the startup protocol of the Cordova project to HTTP instead of HTTPS, this issue also occurred.

Command or Code

No commands or code, only the generated JavaScript file was compiled using the "inlineSourceMap" compilation option

Environment, Platform, Device

Android 12, and Google Webview 118

Version information

Cordova 10.0.0,Android Studio

Checklist

breautek commented 2 months ago

I haven't found a solution to the problem online, but I think it may be related to the WebViewAssetLoader class?

You're suspicion is right here.

For context... The WebViewAssetLoader is part of the android SDK and it effectively intercepts local connections within the webview's network stack going to a specific domain (in this case `https://localhost`). Any connections opened up outside of the webview against `https://localhost` isn't intercepted. Connections opened up in the dev tools is an independent webview that isn't even running on the device itself, it runs in a chrome browser on your local workstation. So the `https://localhost` endpoint ends up pointing at our own workstation instead. If you don't have a web server listening on port 443, then your machine will refuse connections, hence the `ERR_CONNECTION_REFUSED` error. Note that even if you were using a filesystem based strategy which doesn't use the WebViewAssetLoader, this issue still manifests in a slightly different way, but if the `file://` points to a real path on your local machine then source maps I believe it will work. Issues will probably manifest if you're working with teams and you're using a build bundled by another machine.

The workaround is to inline your source maps. I'm not sure what tools you're using but using inlineSourceMap may not be enough if you're importing dependencies that also has source maps, and if they distribute via an external sourcemap file (as that's generally recommended for production releases).

Workaround with webpack... The `source-map-loader` can be used to lift sourcemaps from any imported dependencies to the main application being bundled, which is configured to use `inline-source-map` devtool: ```js { devtool: 'inline-source-map', ..., module: { rules: [ ..., { test: /\.js$/, enforce : 'pre', use: ["source-map-loader"], include: [ Path.resolve(__dirname, 'src'), // Include paths to packages that you want source map files to be lifted. // Including the entire_node_modules may blow up your file size // But could be a valid strategy for debug builds. Path.resolve(__dirname, 'node_modules/tp-app-common'), Path.resolve(__dirname, 'node_modules/tp-mobile-common'), Path.resolve(__dirname, 'node_modules/@totalpave') ] } ] } } ``` More details about source-map-loader webpack plugin can be found [here](https://webpack.js.org/loaders/source-map-loader/)

Other bundlers I'm not sure if they are workarounds, you may have to ask for their support if it is possible to lift the source-maps up so that they become a source-map for the bundled application. For webpack, source-map-loader exists because webpack bundles tends to break source maps of imported dependencies to begin with, so source-map-loader addresses that issue, which conveniently also corrects the caveat with source maps on webview mobile applications as well.

I'm closing this issue because there isn't anything that Cordova can do to really address this problem. The main issue is devtool window doesn't route requests through the webview's network stack, and thus it doesn't get intercepted by the app's webview asset loader. That's something only the Chromium team can sort out.

If you're using another build tool then you can try asking in our discussions to see if anybody else have found the workaround using the same build tools.

breautek commented 2 months ago

So the https://localhost endpoint ends up pointing at our own workstation instead. If you don't have a web server listening on port 443, then your machine will refuse connections, hence the ERR_CONNECTION_REFUSED error.

Not something that I have tried but if you have the technical knowledge to configure webservers.... setting up a local webserver with a self-signed trusted certificate that serves the map files might actually work.